- std::vector<ModifyEvent>& events = mImpl->mModifyEvents;
-
- for( unsigned int i=0; i<events.size(); ++i )
- {
- if( REPLACE_TEXT == events[0].type )
- {
- // A (single) replace event should come first, otherwise we wasted time processing NOOP events
- DALI_ASSERT_DEBUG( 0 == i && "Unexpected REPLACE event" );
-
- ReplaceTextEvent( events[0].text );
- }
- else if( INSERT_TEXT == events[0].type )
- {
- InsertTextEvent( events[0].text );
- }
- else if( DELETE_TEXT == events[0].type )
- {
- DeleteTextEvent();
- }
- }
-
- // Discard temporary text
- events.clear();
-}
-
-void Controller::ReplaceTextEvent( const std::string& text )
-{
- // Reset buffers.
- mImpl->mLogicalModel->mText.Clear();
- mImpl->mLogicalModel->mScriptRuns.Clear();
- mImpl->mLogicalModel->mFontRuns.Clear();
- mImpl->mLogicalModel->mLineBreakInfo.Clear();
- mImpl->mLogicalModel->mWordBreakInfo.Clear();
- mImpl->mLogicalModel->mBidirectionalParagraphInfo.Clear();
- mImpl->mLogicalModel->mCharacterDirections.Clear();
- mImpl->mLogicalModel->mBidirectionalLineInfo.Clear();
- mImpl->mLogicalModel->mLogicalToVisualMap.Clear();
- mImpl->mLogicalModel->mVisualToLogicalMap.Clear();
- mImpl->mVisualModel->mGlyphs.Clear();
- mImpl->mVisualModel->mGlyphsToCharacters.Clear();
- mImpl->mVisualModel->mCharactersToGlyph.Clear();
- mImpl->mVisualModel->mCharactersPerGlyph.Clear();
- mImpl->mVisualModel->mGlyphsPerCharacter.Clear();
- mImpl->mVisualModel->mGlyphPositions.Clear();
- mImpl->mVisualModel->mLines.Clear();
-
- // Convert text into UTF-32
- Vector<Character>& utf32Characters = mImpl->mLogicalModel->mText;
- utf32Characters.Resize( text.size() );
-
- // This is a bit horrible but std::string returns a (signed) char*
- const uint8_t* utf8 = reinterpret_cast<const uint8_t*>( text.c_str() );
-
- // Transform a text array encoded in utf8 into an array encoded in utf32.
- // It returns the actual number of characters.
- Length characterCount = Utf8ToUtf32( utf8, text.size(), utf32Characters.Begin() );
- utf32Characters.Resize( characterCount );
-
- // Reset the cursor position
- if( mImpl->mTextInput )
- {
- mImpl->mTextInput->mPrimaryCursorPosition = characterCount;
- // TODO - handle secondary cursor
- }
-
- // The natural size needs to be re-calculated.
- mImpl->mRecalculateNaturalSize = true;
-
- // Apply modifications to the model
- mImpl->mOperationsPending = ALL_OPERATIONS;
- UpdateModel( ALL_OPERATIONS );
- mImpl->mOperationsPending = static_cast<OperationsMask>( LAYOUT |
- ALIGN |
- UPDATE_ACTUAL_SIZE |
- REORDER );
-}
-
-void Controller::InsertTextEvent( const std::string& text )
-{
- DALI_ASSERT_DEBUG( NULL != mImpl->mTextInput && "Unexpected InsertTextEvent" );
-
- // TODO - Optimize this
- mImpl->mLogicalModel->mScriptRuns.Clear();
- mImpl->mLogicalModel->mFontRuns.Clear();
- mImpl->mLogicalModel->mLineBreakInfo.Clear();
- mImpl->mLogicalModel->mWordBreakInfo.Clear();
- mImpl->mLogicalModel->mBidirectionalParagraphInfo.Clear();
- mImpl->mLogicalModel->mCharacterDirections.Clear();
- mImpl->mLogicalModel->mBidirectionalLineInfo.Clear();
- mImpl->mLogicalModel->mLogicalToVisualMap.Clear();
- mImpl->mLogicalModel->mVisualToLogicalMap.Clear();
- mImpl->mVisualModel->mGlyphs.Clear();
- mImpl->mVisualModel->mGlyphsToCharacters.Clear();
- mImpl->mVisualModel->mCharactersToGlyph.Clear();
- mImpl->mVisualModel->mCharactersPerGlyph.Clear();
- mImpl->mVisualModel->mGlyphsPerCharacter.Clear();
- mImpl->mVisualModel->mGlyphPositions.Clear();
- mImpl->mVisualModel->mLines.Clear();
-
- // Convert text into UTF-32
- Vector<Character> utf32Characters;
- utf32Characters.Resize( text.size() );
-
- // This is a bit horrible but std::string returns a (signed) char*
- const uint8_t* utf8 = reinterpret_cast<const uint8_t*>( text.c_str() );
-
- // Transform a text array encoded in utf8 into an array encoded in utf32.
- // It returns the actual number of characters.
- Length characterCount = Utf8ToUtf32( utf8, text.size(), utf32Characters.Begin() );
- utf32Characters.Resize( characterCount );
-
- // Insert at current cursor position
- Vector<Character>& modifyText = mImpl->mLogicalModel->mText;
- CharacterIndex& cursorIndex = mImpl->mTextInput->mPrimaryCursorPosition;
-
- if( cursorIndex < modifyText.Count() )
- {
- modifyText.Insert( modifyText.Begin() + cursorIndex, utf32Characters.Begin(), utf32Characters.End() );
- }
- else
- {
- modifyText.Insert( modifyText.End(), utf32Characters.Begin(), utf32Characters.End() );
- }
-
- // Advance the cursor position
- ++cursorIndex;
-
- // The natural size needs to be re-calculated.
- mImpl->mRecalculateNaturalSize = true;
-
- // Apply modifications to the model; TODO - Optimize this
- mImpl->mOperationsPending = ALL_OPERATIONS;
- UpdateModel( ALL_OPERATIONS );
- mImpl->mOperationsPending = static_cast<OperationsMask>( LAYOUT |
- ALIGN |
- UPDATE_ACTUAL_SIZE |
- REORDER );
-
- // Queue a cursor reposition event; this must wait until after DoRelayout()
- mImpl->mTextInput->mUpdateCursorPosition = true;
-}
-
-void Controller::DeleteTextEvent()
-{
- DALI_ASSERT_DEBUG( NULL != mImpl->mTextInput && "Unexpected InsertTextEvent" );
-
- // TODO - Optimize this
- mImpl->mLogicalModel->mScriptRuns.Clear();
- mImpl->mLogicalModel->mFontRuns.Clear();
- mImpl->mLogicalModel->mLineBreakInfo.Clear();
- mImpl->mLogicalModel->mWordBreakInfo.Clear();
- mImpl->mLogicalModel->mBidirectionalParagraphInfo.Clear();
- mImpl->mLogicalModel->mCharacterDirections.Clear();
- mImpl->mLogicalModel->mBidirectionalLineInfo.Clear();
- mImpl->mLogicalModel->mLogicalToVisualMap.Clear();
- mImpl->mLogicalModel->mVisualToLogicalMap.Clear();
- mImpl->mVisualModel->mGlyphs.Clear();
- mImpl->mVisualModel->mGlyphsToCharacters.Clear();
- mImpl->mVisualModel->mCharactersToGlyph.Clear();
- mImpl->mVisualModel->mCharactersPerGlyph.Clear();
- mImpl->mVisualModel->mGlyphsPerCharacter.Clear();
- mImpl->mVisualModel->mGlyphPositions.Clear();
- mImpl->mVisualModel->mLines.Clear();
-
- // Delte at current cursor position
- Vector<Character>& modifyText = mImpl->mLogicalModel->mText;
- CharacterIndex& cursorIndex = mImpl->mTextInput->mPrimaryCursorPosition;
-
- if( cursorIndex > 0 &&
- cursorIndex-1 < modifyText.Count() )
- {
- modifyText.Remove( modifyText.Begin() + cursorIndex - 1 );
-
- // Cursor position retreat
- --cursorIndex;
- }
-
- // The natural size needs to be re-calculated.
- mImpl->mRecalculateNaturalSize = true;
-
- // Apply modifications to the model; TODO - Optimize this
- mImpl->mOperationsPending = ALL_OPERATIONS;
- UpdateModel( ALL_OPERATIONS );
- mImpl->mOperationsPending = static_cast<OperationsMask>( LAYOUT |
- ALIGN |
- UPDATE_ACTUAL_SIZE |
- REORDER );
-
- // Queue a cursor reposition event; this must wait until after DoRelayout()
- mImpl->mTextInput->mUpdateCursorPosition = true;
-}
-
-void Controller::UpdateModel( OperationsMask operationsRequired )
-{
- // Calculate the operations to be done.
- const OperationsMask operations = static_cast<OperationsMask>( mImpl->mOperationsPending & operationsRequired );
-
- Vector<Character>& utf32Characters = mImpl->mLogicalModel->mText;
-
- const Length numberOfCharacters = mImpl->mLogicalModel->GetNumberOfCharacters();
-
- Vector<LineBreakInfo>& lineBreakInfo = mImpl->mLogicalModel->mLineBreakInfo;
- if( 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,
- lineBreakInfo );
- }
-
- Vector<WordBreakInfo>& wordBreakInfo = mImpl->mLogicalModel->mWordBreakInfo;
- if( GET_WORD_BREAKS & operations )
- {
- // Retrieves the word break info. The word break info is used to layout the text (where to wrap the text in lines).
- wordBreakInfo.Resize( numberOfCharacters, TextAbstraction::WORD_NO_BREAK );
-
- SetWordBreakInfo( utf32Characters,
- wordBreakInfo );
- }
-
- const bool getScripts = GET_SCRIPTS & operations;
- const bool validateFonts = VALIDATE_FONTS & operations;
-
- Vector<ScriptRun>& scripts = mImpl->mLogicalModel->mScriptRuns;
- Vector<FontRun>& validFonts = mImpl->mLogicalModel->mFontRuns;