- if( NO_OPERATION != ( REORDER & operations ) )
- {
- uint32_t startRemoveIndex = mModel->mLogicalModel->mBidirectionalLineInfo.Count();
- uint32_t endRemoveIndex = startRemoveIndex;
- ClearCharacterRuns( startIndex,
- endIndex,
- mModel->mLogicalModel->mBidirectionalLineInfo,
- startRemoveIndex,
- endRemoveIndex );
-
- BidirectionalLineInfoRun* bidirectionalLineInfoBuffer = mModel->mLogicalModel->mBidirectionalLineInfo.Begin();
-
- // Free the allocated memory used to store the conversion table in the bidirectional line info run.
- for( Vector<BidirectionalLineInfoRun>::Iterator it = bidirectionalLineInfoBuffer + startRemoveIndex,
- endIt = bidirectionalLineInfoBuffer + endRemoveIndex;
- it != endIt;
- ++it )
- {
- BidirectionalLineInfoRun& bidiLineInfo = *it;
-
- free( bidiLineInfo.visualToLogicalMap );
- bidiLineInfo.visualToLogicalMap = NULL;
- }
-
- mModel->mLogicalModel->mBidirectionalLineInfo.Erase( bidirectionalLineInfoBuffer + startRemoveIndex,
- bidirectionalLineInfoBuffer + endRemoveIndex );
- }
- }
-}
-
-void Controller::Impl::ClearGlyphModelData( CharacterIndex startIndex, CharacterIndex endIndex, OperationsMask operations )
-{
- const CharacterIndex endIndexPlusOne = endIndex + 1u;
- const Length numberOfCharactersRemoved = endIndexPlusOne - startIndex;
-
- // Convert the character index to glyph index before deleting the character to glyph and the glyphs per character buffers.
- GlyphIndex* charactersToGlyphBuffer = mModel->mVisualModel->mCharactersToGlyph.Begin();
- Length* glyphsPerCharacterBuffer = mModel->mVisualModel->mGlyphsPerCharacter.Begin();
-
- const GlyphIndex endGlyphIndexPlusOne = *( charactersToGlyphBuffer + endIndex ) + *( glyphsPerCharacterBuffer + endIndex );
- const Length numberOfGlyphsRemoved = endGlyphIndexPlusOne - mTextUpdateInfo.mStartGlyphIndex;
-
- if( NO_OPERATION != ( SHAPE_TEXT & operations ) )
- {
- // Update the character to glyph indices.
- for( Vector<GlyphIndex>::Iterator it = charactersToGlyphBuffer + endIndexPlusOne,
- endIt = charactersToGlyphBuffer + mModel->mVisualModel->mCharactersToGlyph.Count();
- it != endIt;
- ++it )
- {
- CharacterIndex& index = *it;
- index -= numberOfGlyphsRemoved;
- }
-
- // Clear the character to glyph conversion table.
- mModel->mVisualModel->mCharactersToGlyph.Erase( charactersToGlyphBuffer + startIndex,
- charactersToGlyphBuffer + endIndexPlusOne );
-
- // Clear the glyphs per character table.
- mModel->mVisualModel->mGlyphsPerCharacter.Erase( glyphsPerCharacterBuffer + startIndex,
- glyphsPerCharacterBuffer + endIndexPlusOne );
-
- // Clear the glyphs buffer.
- GlyphInfo* glyphsBuffer = mModel->mVisualModel->mGlyphs.Begin();
- mModel->mVisualModel->mGlyphs.Erase( glyphsBuffer + mTextUpdateInfo.mStartGlyphIndex,
- glyphsBuffer + endGlyphIndexPlusOne );
-
- CharacterIndex* glyphsToCharactersBuffer = mModel->mVisualModel->mGlyphsToCharacters.Begin();
-
- // Update the glyph to character indices.
- for( Vector<CharacterIndex>::Iterator it = glyphsToCharactersBuffer + endGlyphIndexPlusOne,
- endIt = glyphsToCharactersBuffer + mModel->mVisualModel->mGlyphsToCharacters.Count();
- it != endIt;
- ++it )
- {
- CharacterIndex& index = *it;
- index -= numberOfCharactersRemoved;
- }
-
- // Clear the glyphs to characters buffer.
- mModel->mVisualModel->mGlyphsToCharacters.Erase( glyphsToCharactersBuffer + mTextUpdateInfo.mStartGlyphIndex,
- glyphsToCharactersBuffer + endGlyphIndexPlusOne );
-
- // Clear the characters per glyph buffer.
- Length* charactersPerGlyphBuffer = mModel->mVisualModel->mCharactersPerGlyph.Begin();
- mModel->mVisualModel->mCharactersPerGlyph.Erase( charactersPerGlyphBuffer + mTextUpdateInfo.mStartGlyphIndex,
- charactersPerGlyphBuffer + endGlyphIndexPlusOne );
-
- // Clear the positions buffer.
- Vector2* positionsBuffer = mModel->mVisualModel->mGlyphPositions.Begin();
- mModel->mVisualModel->mGlyphPositions.Erase( positionsBuffer + mTextUpdateInfo.mStartGlyphIndex,
- positionsBuffer + endGlyphIndexPlusOne );
- }
-
- if( NO_OPERATION != ( LAYOUT & operations ) )
- {
- // Clear the lines.
- uint32_t startRemoveIndex = mModel->mVisualModel->mLines.Count();
- uint32_t endRemoveIndex = startRemoveIndex;
- ClearCharacterRuns( startIndex,
- endIndex,
- mModel->mVisualModel->mLines,
- startRemoveIndex,
- endRemoveIndex );
-
- // Will update the glyph runs.
- startRemoveIndex = mModel->mVisualModel->mLines.Count();
- endRemoveIndex = startRemoveIndex;
- ClearGlyphRuns( mTextUpdateInfo.mStartGlyphIndex,
- endGlyphIndexPlusOne - 1u,
- mModel->mVisualModel->mLines,
- startRemoveIndex,
- endRemoveIndex );
-
- // Set the line index from where to insert the new laid-out lines.
- mTextUpdateInfo.mStartLineIndex = startRemoveIndex;
-
- LineRun* linesBuffer = mModel->mVisualModel->mLines.Begin();
- mModel->mVisualModel->mLines.Erase( linesBuffer + startRemoveIndex,
- linesBuffer + endRemoveIndex );
- }
-
- if( NO_OPERATION != ( COLOR & operations ) )
- {
- if( 0u != mModel->mVisualModel->mColorIndices.Count() )
- {
- ColorIndex* colorIndexBuffer = mModel->mVisualModel->mColorIndices.Begin();
- mModel->mVisualModel->mColorIndices.Erase( colorIndexBuffer + mTextUpdateInfo.mStartGlyphIndex,
- colorIndexBuffer + endGlyphIndexPlusOne );
- }
-
- if( 0u != mModel->mVisualModel->mBackgroundColorIndices.Count() )
- {
- ColorIndex* backgroundColorIndexBuffer = mModel->mVisualModel->mBackgroundColorIndices.Begin();
- mModel->mVisualModel->mBackgroundColorIndices.Erase( backgroundColorIndexBuffer + mTextUpdateInfo.mStartGlyphIndex,
- backgroundColorIndexBuffer + endGlyphIndexPlusOne );
- }
- }
-}
-
-void Controller::Impl::ClearModelData( CharacterIndex startIndex, CharacterIndex endIndex, OperationsMask operations )
-{
- if( mTextUpdateInfo.mClearAll ||
- ( ( 0u == startIndex ) &&
- ( mTextUpdateInfo.mPreviousNumberOfCharacters == endIndex + 1u ) ) )
- {
- ClearFullModelData( operations );
- }
- else
- {
- // Clear the model data related with characters.
- ClearCharacterModelData( startIndex, endIndex, operations );
-
- // Clear the model data related with glyphs.
- ClearGlyphModelData( startIndex, endIndex, operations );
- }
-
- // The estimated number of lines. Used to avoid reallocations when layouting.
- mTextUpdateInfo.mEstimatedNumberOfLines = std::max( mModel->mVisualModel->mLines.Count(), mModel->mLogicalModel->mParagraphInfo.Count() );
-
- mModel->mVisualModel->ClearCaches();
-}
-
-bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
-{
- DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::UpdateModel\n" );
-
- // Calculate the operations to be done.
- const OperationsMask operations = static_cast<OperationsMask>( mOperationsPending & operationsRequired );
-
- if( NO_OPERATION == operations )
- {
- // Nothing to do if no operations are pending and required.
- return false;
- }
-
- Vector<Character>& srcCharacters = mModel->mLogicalModel->mText;
- Vector<Character> displayCharacters;
- bool useHiddenText = false;
- if ( mHiddenInput && mEventData != NULL && !mEventData->mIsShowingPlaceholderText)
- {
- mHiddenInput->Substitute( srcCharacters,displayCharacters );
- useHiddenText = true;
- }
-
- Vector<Character>& utf32Characters = useHiddenText ? displayCharacters : srcCharacters;
- const Length numberOfCharacters = utf32Characters.Count();
-
- // Index to the first character of the first paragraph to be updated.
- CharacterIndex startIndex = 0u;
- // Number of characters of the paragraphs to be removed.
- Length paragraphCharacters = 0u;
-
- CalculateTextUpdateIndices( paragraphCharacters );
-
- // Check whether the indices for updating the text is valid
- if ( numberOfCharacters > 0u &&
- ( mTextUpdateInfo.mParagraphCharacterIndex > numberOfCharacters ||
- mTextUpdateInfo.mRequestedNumberOfCharacters > numberOfCharacters ) )
- {
- std::string currentText;
- Utf32ToUtf8( mModel->mLogicalModel->mText.Begin(), numberOfCharacters, currentText );
-
- DALI_LOG_ERROR( "Controller::Impl::UpdateModel: mTextUpdateInfo has invalid indices\n" );
- DALI_LOG_ERROR( "Number of characters: %d, current text is: %s\n", numberOfCharacters, currentText.c_str() );
-
- // Dump mTextUpdateInfo
- DALI_LOG_ERROR( "Dump mTextUpdateInfo:\n" );
- DALI_LOG_ERROR( " mTextUpdateInfo.mCharacterIndex = %u\n", mTextUpdateInfo.mCharacterIndex );
- DALI_LOG_ERROR( " mTextUpdateInfo.mNumberOfCharactersToRemove = %u\n", mTextUpdateInfo.mNumberOfCharactersToRemove );
- DALI_LOG_ERROR( " mTextUpdateInfo.mNumberOfCharactersToAdd = %u\n", mTextUpdateInfo.mNumberOfCharactersToAdd );
- DALI_LOG_ERROR( " mTextUpdateInfo.mPreviousNumberOfCharacters = %u\n", mTextUpdateInfo.mPreviousNumberOfCharacters );
- DALI_LOG_ERROR( " mTextUpdateInfo.mParagraphCharacterIndex = %u\n", mTextUpdateInfo.mParagraphCharacterIndex );
- DALI_LOG_ERROR( " mTextUpdateInfo.mRequestedNumberOfCharacters = %u\n", mTextUpdateInfo.mRequestedNumberOfCharacters );
- DALI_LOG_ERROR( " mTextUpdateInfo.mStartGlyphIndex = %u\n", mTextUpdateInfo.mStartGlyphIndex );
- DALI_LOG_ERROR( " mTextUpdateInfo.mStartLineIndex = %u\n", mTextUpdateInfo.mStartLineIndex );
- DALI_LOG_ERROR( " mTextUpdateInfo.mEstimatedNumberOfLines = %u\n", mTextUpdateInfo.mEstimatedNumberOfLines );
- DALI_LOG_ERROR( " mTextUpdateInfo.mClearAll = %d\n", mTextUpdateInfo.mClearAll );
- DALI_LOG_ERROR( " mTextUpdateInfo.mFullRelayoutNeeded = %d\n", mTextUpdateInfo.mFullRelayoutNeeded );
- DALI_LOG_ERROR( " mTextUpdateInfo.mIsLastCharacterNewParagraph = %d\n", mTextUpdateInfo.mIsLastCharacterNewParagraph );
-
- return false;
- }
-
- startIndex = mTextUpdateInfo.mParagraphCharacterIndex;
-
- if( mTextUpdateInfo.mClearAll ||
- ( 0u != paragraphCharacters ) )
- {
- ClearModelData( startIndex, startIndex + ( ( paragraphCharacters > 0u ) ? paragraphCharacters - 1u : 0u ), operations );
- }
-
- mTextUpdateInfo.mClearAll = false;
-
- // Whether the model is updated.
- bool updated = false;
-
- Vector<LineBreakInfo>& lineBreakInfo = mModel->mLogicalModel->mLineBreakInfo;
- const Length requestedNumberOfCharacters = mTextUpdateInfo.mRequestedNumberOfCharacters;
-
- if( NO_OPERATION != ( GET_LINE_BREAKS & operations ) )
- {
- // Retrieves the line break info. The line break info is used to split the text in 'paragraphs' to
- // calculate the bidirectional info for each 'paragraph'.
- // It's also used to layout the text (where it should be a new line) or to shape the text (text in different lines
- // is not shaped together).
- lineBreakInfo.Resize( numberOfCharacters, TextAbstraction::LINE_NO_BREAK );
-
- SetLineBreakInfo( utf32Characters,
- startIndex,
- requestedNumberOfCharacters,
- lineBreakInfo );
-
- // Create the paragraph info.
- mModel->mLogicalModel->CreateParagraphInfo( startIndex,
- requestedNumberOfCharacters );
- updated = true;
- }
-
- const bool getScripts = NO_OPERATION != ( GET_SCRIPTS & operations );
- const bool validateFonts = NO_OPERATION != ( VALIDATE_FONTS & operations );
-
- Vector<ScriptRun>& scripts = mModel->mLogicalModel->mScriptRuns;
- Vector<FontRun>& validFonts = mModel->mLogicalModel->mFontRuns;
-
- if( getScripts || validateFonts )
- {
- // Validates the fonts assigned by the application or assigns default ones.
- // It makes sure all the characters are going to be rendered by the correct font.
- MultilanguageSupport multilanguageSupport = MultilanguageSupport::Get();
-
- if( getScripts )
- {
- // Retrieves the scripts used in the text.
- multilanguageSupport.SetScripts( utf32Characters,
- startIndex,
- requestedNumberOfCharacters,
- scripts );
- }
-
- if( validateFonts )
- {
- // Validate the fonts set through the mark-up string.
- Vector<FontDescriptionRun>& fontDescriptionRuns = mModel->mLogicalModel->mFontDescriptionRuns;
-
- // Get the default font's description.
- TextAbstraction::FontDescription defaultFontDescription;
- TextAbstraction::PointSize26Dot6 defaultPointSize = TextAbstraction::FontClient::DEFAULT_POINT_SIZE;
-
- if( IsShowingPlaceholderText() && mEventData && ( NULL != mEventData->mPlaceholderFont ) )
- {
- // If the placeholder font is set specifically, only placeholder font is changed.
- defaultFontDescription = mEventData->mPlaceholderFont->mFontDescription;
- if( mEventData->mPlaceholderFont->sizeDefined )
- {
- defaultPointSize = mEventData->mPlaceholderFont->mDefaultPointSize * 64u;
- }
- }
- else if( NULL != mFontDefaults )
- {
- // Set the normal font and the placeholder font.
- defaultFontDescription = mFontDefaults->mFontDescription;
-
- if( mTextFitEnabled )
- {
- defaultPointSize = mFontDefaults->mFitPointSize * 64u;
- }
- else
- {
- defaultPointSize = mFontDefaults->mDefaultPointSize * 64u;
- }
- }
-
- // Validates the fonts. If there is a character with no assigned font it sets a default one.
- // After this call, fonts are validated.
- multilanguageSupport.ValidateFonts( utf32Characters,
- scripts,
- fontDescriptionRuns,
- defaultFontDescription,
- defaultPointSize,
- startIndex,
- requestedNumberOfCharacters,
- validFonts );
- }
- updated = true;
- }
-
- Vector<Character> mirroredUtf32Characters;
- bool textMirrored = false;
- const Length numberOfParagraphs = mModel->mLogicalModel->mParagraphInfo.Count();
- if( NO_OPERATION != ( BIDI_INFO & operations ) )
- {
- Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo = mModel->mLogicalModel->mBidirectionalParagraphInfo;
- bidirectionalInfo.Reserve( numberOfParagraphs );
-
- // Calculates the bidirectional info for the whole paragraph if it contains right to left scripts.
- SetBidirectionalInfo( utf32Characters,
- scripts,
- lineBreakInfo,
- startIndex,
- requestedNumberOfCharacters,
- bidirectionalInfo,
- mModel->mMatchSystemLanguageDirection,
- mLayoutDirection );
-
- if( 0u != bidirectionalInfo.Count() )
- {
- // Only set the character directions if there is right to left characters.
- Vector<CharacterDirection>& directions = mModel->mLogicalModel->mCharacterDirections;
- GetCharactersDirection( bidirectionalInfo,
- numberOfCharacters,
- startIndex,
- requestedNumberOfCharacters,
- directions );
-
- // This paragraph has right to left text. Some characters may need to be mirrored.
- // TODO: consider if the mirrored string can be stored as well.
-
- textMirrored = GetMirroredText( utf32Characters,
- directions,
- bidirectionalInfo,
- startIndex,
- requestedNumberOfCharacters,
- mirroredUtf32Characters );
- }
- else
- {
- // There is no right to left characters. Clear the directions vector.
- mModel->mLogicalModel->mCharacterDirections.Clear();
- }
- updated = true;
- }
-
- Vector<GlyphInfo>& glyphs = mModel->mVisualModel->mGlyphs;
- Vector<CharacterIndex>& glyphsToCharactersMap = mModel->mVisualModel->mGlyphsToCharacters;
- Vector<Length>& charactersPerGlyph = mModel->mVisualModel->mCharactersPerGlyph;
- Vector<GlyphIndex> newParagraphGlyphs;
- newParagraphGlyphs.Reserve( numberOfParagraphs );
-
- const Length currentNumberOfGlyphs = glyphs.Count();
- if( NO_OPERATION != ( SHAPE_TEXT & operations ) )
- {
- const Vector<Character>& textToShape = textMirrored ? mirroredUtf32Characters : utf32Characters;
- // Shapes the text.
- ShapeText( textToShape,
- lineBreakInfo,
- scripts,
- validFonts,
- startIndex,
- mTextUpdateInfo.mStartGlyphIndex,
- requestedNumberOfCharacters,
- glyphs,
- glyphsToCharactersMap,
- charactersPerGlyph,
- newParagraphGlyphs );
-
- // Create the 'number of glyphs' per character and the glyph to character conversion tables.
- mModel->mVisualModel->CreateGlyphsPerCharacterTable( startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters );
- mModel->mVisualModel->CreateCharacterToGlyphTable( startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters );
- updated = true;
- }
-
- const Length numberOfGlyphs = glyphs.Count() - currentNumberOfGlyphs;
-
- if( NO_OPERATION != ( GET_GLYPH_METRICS & operations ) )
- {
- GlyphInfo* glyphsBuffer = glyphs.Begin();
- mMetrics->GetGlyphMetrics( glyphsBuffer + mTextUpdateInfo.mStartGlyphIndex, numberOfGlyphs );
-
- // Update the width and advance of all new paragraph characters.
- for( Vector<GlyphIndex>::ConstIterator it = newParagraphGlyphs.Begin(), endIt = newParagraphGlyphs.End(); it != endIt; ++it )
- {
- const GlyphIndex index = *it;
- GlyphInfo& glyph = *( glyphsBuffer + index );
-
- glyph.xBearing = 0.f;
- glyph.width = 0.f;
- glyph.advance = 0.f;
- }
- updated = true;
- }
-
- if( ( NULL != mEventData ) &&
- mEventData->mPreEditFlag &&
- ( 0u != mModel->mVisualModel->mCharactersToGlyph.Count() ) )
- {
- Dali::InputMethodContext::PreEditAttributeDataContainer attrs;
- mEventData->mInputMethodContext.GetPreeditStyle( attrs );
- Dali::InputMethodContext::PreeditStyle type = Dali::InputMethodContext::PreeditStyle::NONE;
-
- // Check the type of preedit and run it.
- for( Dali::InputMethodContext::PreEditAttributeDataContainer::Iterator it = attrs.Begin(), endIt = attrs.End(); it != endIt; it++ )
- {
- Dali::InputMethodContext::PreeditAttributeData attrData = *it;
- DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::UpdateModel PreeditStyle type : %d start %d end %d \n", attrData.preeditType, attrData.startIndex, attrData.endIndex );
- type = attrData.preeditType;
-
- // Check the number of commit characters for the start position.
- unsigned int numberOfCommit = mEventData->mPrimaryCursorPosition - mEventData->mPreEditLength;
- Length numberOfIndices = attrData.endIndex - attrData.startIndex;
-
- switch( type )
- {
- case Dali::InputMethodContext::PreeditStyle::UNDERLINE:
- {
- // Add the underline for the pre-edit text.
- GlyphRun underlineRun;
- underlineRun.glyphIndex = attrData.startIndex + numberOfCommit;
- underlineRun.numberOfGlyphs = numberOfIndices;
- mModel->mVisualModel->mUnderlineRuns.PushBack( underlineRun );
- break;
- }
- case Dali::InputMethodContext::PreeditStyle::REVERSE:
- {
- Vector4 textColor = mModel->mVisualModel->GetTextColor();
- ColorRun backgroundColorRun;
- backgroundColorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
- backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
- backgroundColorRun.color = textColor;
- mModel->mLogicalModel->mBackgroundColorRuns.PushBack( backgroundColorRun );
-
- Vector4 backgroundColor = mModel->mVisualModel->GetBackgroundColor();
- Vector<ColorRun> colorRuns;
- colorRuns.Resize( 1u );
- ColorRun& colorRun = *( colorRuns.Begin() );
- colorRun.color = backgroundColor;
- colorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
- colorRun.characterRun.numberOfCharacters = numberOfIndices;
-
- mModel->mLogicalModel->mColorRuns.PushBack( colorRun );
- break;
- }
- case Dali::InputMethodContext::PreeditStyle::HIGHLIGHT:
- {
- ColorRun backgroundColorRun;
- backgroundColorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
- backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
- backgroundColorRun.color = LIGHT_BLUE;
- mModel->mLogicalModel->mBackgroundColorRuns.PushBack( backgroundColorRun );
- break;
- }
- case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_1:
- {
- // CUSTOM_PLATFORM_STYLE_1 should be drawn with background and underline together.
- ColorRun backgroundColorRun;
- backgroundColorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
- backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
- backgroundColorRun.color = BACKGROUND_SUB4;
- mModel->mLogicalModel->mBackgroundColorRuns.PushBack( backgroundColorRun );
-
- GlyphRun underlineRun;
- underlineRun.glyphIndex = attrData.startIndex + numberOfCommit;
- underlineRun.numberOfGlyphs = numberOfIndices;
- mModel->mVisualModel->mUnderlineRuns.PushBack( underlineRun );
- break;
- }
- case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_2:
- {
- // CUSTOM_PLATFORM_STYLE_2 should be drawn with background and underline together.
- ColorRun backgroundColorRun;
- backgroundColorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
- backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
- backgroundColorRun.color = BACKGROUND_SUB5;
- mModel->mLogicalModel->mBackgroundColorRuns.PushBack( backgroundColorRun );
-
- GlyphRun underlineRun;
- underlineRun.glyphIndex = attrData.startIndex + numberOfCommit;
- underlineRun.numberOfGlyphs = numberOfIndices;
- mModel->mVisualModel->mUnderlineRuns.PushBack( underlineRun );
- break;
- }
- case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_3:
- {
- // CUSTOM_PLATFORM_STYLE_3 should be drawn with background and underline together.
- ColorRun backgroundColorRun;
- backgroundColorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
- backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
- backgroundColorRun.color = BACKGROUND_SUB6;
- mModel->mLogicalModel->mBackgroundColorRuns.PushBack( backgroundColorRun );
-
- GlyphRun underlineRun;
- underlineRun.glyphIndex = attrData.startIndex + numberOfCommit;
- underlineRun.numberOfGlyphs = numberOfIndices;
- mModel->mVisualModel->mUnderlineRuns.PushBack( underlineRun );
- break;
- }
- case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_4:
- {
- // CUSTOM_PLATFORM_STYLE_4 should be drawn with background and underline together.
- ColorRun backgroundColorRun;
- backgroundColorRun.characterRun.characterIndex = attrData.startIndex + numberOfCommit;
- backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
- backgroundColorRun.color = BACKGROUND_SUB7;
- mModel->mLogicalModel->mBackgroundColorRuns.PushBack( backgroundColorRun );
-
- GlyphRun underlineRun;
- underlineRun.glyphIndex = attrData.startIndex + numberOfCommit;
- underlineRun.numberOfGlyphs = numberOfIndices;
- mModel->mVisualModel->mUnderlineRuns.PushBack( underlineRun );
- break;
- }
- case Dali::InputMethodContext::PreeditStyle::NONE:
- default:
- {
- break;
- }
- }
- }
- attrs.Clear();
- updated = true;
- }
-
- if( NO_OPERATION != ( COLOR & operations ) )
- {
- // Set the color runs in glyphs.
- SetColorSegmentationInfo( mModel->mLogicalModel->mColorRuns,
- mModel->mVisualModel->mCharactersToGlyph,
- mModel->mVisualModel->mGlyphsPerCharacter,
- startIndex,
- mTextUpdateInfo.mStartGlyphIndex,
- requestedNumberOfCharacters,
- mModel->mVisualModel->mColors,
- mModel->mVisualModel->mColorIndices );
-
- // Set the background color runs in glyphs.
- SetColorSegmentationInfo( mModel->mLogicalModel->mBackgroundColorRuns,
- mModel->mVisualModel->mCharactersToGlyph,
- mModel->mVisualModel->mGlyphsPerCharacter,
- startIndex,
- mTextUpdateInfo.mStartGlyphIndex,
- requestedNumberOfCharacters,
- mModel->mVisualModel->mBackgroundColors,
- mModel->mVisualModel->mBackgroundColorIndices );
-
- updated = true;
- }
-
-
- // The estimated number of lines. Used to avoid reallocations when layouting.
- mTextUpdateInfo.mEstimatedNumberOfLines = std::max( mModel->mVisualModel->mLines.Count(), mModel->mLogicalModel->mParagraphInfo.Count() );
-
- // Set the previous number of characters for the next time the text is updated.
- mTextUpdateInfo.mPreviousNumberOfCharacters = numberOfCharacters;
-
- return updated;
-}
-
-void Controller::Impl::RetrieveDefaultInputStyle( InputStyle& inputStyle )
-{
- // Sets the default text's color.
- inputStyle.textColor = mTextColor;
- inputStyle.isDefaultColor = true;
-
- inputStyle.familyName.clear();
- inputStyle.weight = TextAbstraction::FontWeight::NORMAL;
- inputStyle.width = TextAbstraction::FontWidth::NORMAL;
- inputStyle.slant = TextAbstraction::FontSlant::NORMAL;
- inputStyle.size = 0.f;
-
- inputStyle.lineSpacing = 0.f;
-
- inputStyle.underlineProperties.clear();
- inputStyle.shadowProperties.clear();
- inputStyle.embossProperties.clear();
- inputStyle.outlineProperties.clear();
-
- inputStyle.isFamilyDefined = false;
- inputStyle.isWeightDefined = false;
- inputStyle.isWidthDefined = false;
- inputStyle.isSlantDefined = false;
- inputStyle.isSizeDefined = false;
-
- inputStyle.isLineSpacingDefined = false;
-
- inputStyle.isUnderlineDefined = false;
- inputStyle.isShadowDefined = false;
- inputStyle.isEmbossDefined = false;
- inputStyle.isOutlineDefined = false;
-
- // Sets the default font's family name, weight, width, slant and size.
- if( mFontDefaults )
- {
- if( mFontDefaults->familyDefined )
- {
- inputStyle.familyName = mFontDefaults->mFontDescription.family;
- inputStyle.isFamilyDefined = true;
- }
-
- if( mFontDefaults->weightDefined )
- {
- inputStyle.weight = mFontDefaults->mFontDescription.weight;
- inputStyle.isWeightDefined = true;
- }
-
- if( mFontDefaults->widthDefined )
- {
- inputStyle.width = mFontDefaults->mFontDescription.width;
- inputStyle.isWidthDefined = true;
- }
-
- if( mFontDefaults->slantDefined )
- {
- inputStyle.slant = mFontDefaults->mFontDescription.slant;
- inputStyle.isSlantDefined = true;
- }
-
- if( mFontDefaults->sizeDefined )
- {
- inputStyle.size = mFontDefaults->mDefaultPointSize;
- inputStyle.isSizeDefined = true;
- }
- }
-}
-
-float Controller::Impl::GetDefaultFontLineHeight()
-{
- FontId defaultFontId = 0u;
- if( NULL == mFontDefaults )
- {
- TextAbstraction::FontDescription fontDescription;
- defaultFontId = mFontClient.GetFontId( fontDescription );
- }
- else
- {
- defaultFontId = mFontDefaults->GetFontId( mFontClient );
- }
-
- Text::FontMetrics fontMetrics;
- mMetrics->GetFontMetrics( defaultFontId, fontMetrics );
-
- return( fontMetrics.ascender - fontMetrics.descender );
-}
-
-void Controller::Impl::OnCursorKeyEvent( const Event& event )
-{
- if( NULL == mEventData || !IsShowingRealText() )
- {
- // Nothing to do if there is no text input.
- return;
- }
-
- int keyCode = event.p1.mInt;
- bool isShiftModifier = event.p2.mBool;
-
- CharacterIndex previousPrimaryCursorPosition = mEventData->mPrimaryCursorPosition;
-
- if( Dali::DALI_KEY_CURSOR_LEFT == keyCode )
- {
- if( mEventData->mPrimaryCursorPosition > 0u )
- {
- if ( !isShiftModifier && mEventData->mDecorator->IsHighlightVisible() )
- {
- mEventData->mPrimaryCursorPosition = std::min(mEventData->mLeftSelectionPosition, mEventData->mRightSelectionPosition);
- }
- else
- {
- mEventData->mPrimaryCursorPosition = CalculateNewCursorIndex( mEventData->mPrimaryCursorPosition - 1u );
- }
- }
- }
- else if( Dali::DALI_KEY_CURSOR_RIGHT == keyCode )
- {
- if( mModel->mLogicalModel->mText.Count() > mEventData->mPrimaryCursorPosition )
- {
- if ( !isShiftModifier && mEventData->mDecorator->IsHighlightVisible() )
- {
- mEventData->mPrimaryCursorPosition = std::max(mEventData->mLeftSelectionPosition, mEventData->mRightSelectionPosition);
- }
- else
- {
- mEventData->mPrimaryCursorPosition = CalculateNewCursorIndex( mEventData->mPrimaryCursorPosition );
- }
- }
- }
- else if( Dali::DALI_KEY_CURSOR_UP == keyCode && !isShiftModifier )