X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Ftext-controller-impl.cpp;h=14844672f90652d6a588b641d2d8da0e9e448079;hp=b49ea43dbceb7865858ce7fb78cbba721bb9ad5c;hb=b8dec7134bf61ca6b9e47efce907131cb326cc64;hpb=ca0909c54cdc7ba39ae8916352cabe078c060626 diff --git a/dali-toolkit/internal/text/text-controller-impl.cpp b/dali-toolkit/internal/text/text-controller-impl.cpp index b49ea43..1484467 100644 --- a/dali-toolkit/internal/text/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/text-controller-impl.cpp @@ -25,13 +25,9 @@ // INTERNAL INCLUDES #include #include -#include #include -#include #include #include -#include -#include namespace { @@ -329,7 +325,6 @@ void Controller::Impl::UpdateModel( OperationsMask operationsRequired ) { // Retrieves the scripts used in the text. multilanguageSupport.SetScripts( utf32Characters, - lineBreakInfo, scripts ); } @@ -352,13 +347,12 @@ void Controller::Impl::UpdateModel( OperationsMask operationsRequired ) Vector mirroredUtf32Characters; bool textMirrored = false; + Length numberOfParagraphs = 0u; if( BIDI_INFO & operations ) { // Count the number of LINE_NO_BREAK to reserve some space for the vector of paragraph's // bidirectional info. - Length numberOfParagraphs = 0u; - const TextAbstraction::LineBreakInfo* lineBreakInfoBuffer = lineBreakInfo.Begin(); for( Length index = 0u; index < numberOfCharacters; ++index ) { @@ -382,7 +376,9 @@ void Controller::Impl::UpdateModel( OperationsMask operationsRequired ) // 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, mirroredUtf32Characters ); + textMirrored = GetMirroredText( utf32Characters, + mirroredUtf32Characters, + bidirectionalInfo ); // Only set the character directions if there is right to left characters. Vector& directions = mLogicalModel->mCharacterDirections; @@ -401,6 +397,9 @@ void Controller::Impl::UpdateModel( OperationsMask operationsRequired ) Vector& glyphs = mVisualModel->mGlyphs; Vector& glyphsToCharactersMap = mVisualModel->mGlyphsToCharacters; Vector& charactersPerGlyph = mVisualModel->mCharactersPerGlyph; + Vector newParagraphGlyphs; + newParagraphGlyphs.Reserve( numberOfParagraphs ); + if( SHAPE_TEXT & operations ) { const Vector& textToShape = textMirrored ? mirroredUtf32Characters : utf32Characters; @@ -411,7 +410,8 @@ void Controller::Impl::UpdateModel( OperationsMask operationsRequired ) validFonts, glyphs, glyphsToCharactersMap, - charactersPerGlyph ); + charactersPerGlyph, + newParagraphGlyphs ); // Create the 'number of glyphs' per character and the glyph to character conversion tables. mVisualModel->CreateGlyphsPerCharacterTable( numberOfCharacters ); @@ -422,7 +422,40 @@ void Controller::Impl::UpdateModel( OperationsMask operationsRequired ) if( GET_GLYPH_METRICS & operations ) { - mFontClient.GetGlyphMetrics( glyphs.Begin(), numberOfGlyphs ); + GlyphInfo* glyphsBuffer = glyphs.Begin(); + mFontClient.GetGlyphMetrics( glyphsBuffer, numberOfGlyphs ); + + // Update the width and advance of all new paragraph characters. + for( Vector::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; + } + } + + if( mEventData && + mEventData->mPreEditFlag && + ( 0u != mVisualModel->mCharactersToGlyph.Count() ) ) + { + // Add the underline for the pre-edit text. + const GlyphIndex* const charactersToGlyphBuffer = mVisualModel->mCharactersToGlyph.Begin(); + const Length* const glyphsPerCharacterBuffer = mVisualModel->mGlyphsPerCharacter.Begin(); + + const GlyphIndex glyphStart = *( charactersToGlyphBuffer + mEventData->mPreEditStartPosition ); + const CharacterIndex lastPreEditCharacter = mEventData->mPreEditStartPosition + ( ( mEventData->mPreEditLength > 0u ) ? mEventData->mPreEditLength - 1u : 0u ); + const Length numberOfGlyphsLastCharacter = *( glyphsPerCharacterBuffer + lastPreEditCharacter ); + const GlyphIndex glyphEnd = *( charactersToGlyphBuffer + lastPreEditCharacter ) + ( numberOfGlyphsLastCharacter > 1u ? numberOfGlyphsLastCharacter - 1u : 0u ); + + GlyphRun underlineRun; + underlineRun.glyphIndex = glyphStart; + underlineRun.numberOfGlyphs = 1u + glyphEnd - glyphStart; + + // TODO: At the moment the underline runs are only for pre-edit. + mVisualModel->mUnderlineRuns.PushBack( underlineRun ); } } @@ -725,7 +758,7 @@ void Controller::Impl::OnHandleEvent( const Event& event ) Vector2 position = mEventData->mDecorator->GetPosition( GRAB_HANDLE ); // Position the grag handle close to either the left or right edge. - position.x = scrollRightDirection ? 0.f : mControlSize.width; + position.x = scrollRightDirection ? 0.f : mVisualModel->mControlSize.width; // Get the new handle position. // The grab handle's position is in decorator coords. Need to transforms to text coords. @@ -746,7 +779,7 @@ void Controller::Impl::OnHandleEvent( const Event& event ) Vector2 position = mEventData->mDecorator->GetPosition( leftSelectionHandleEvent ? Text::LEFT_SELECTION_HANDLE : Text::RIGHT_SELECTION_HANDLE ); // Position the selection handle close to either the left or right edge. - position.x = scrollRightDirection ? 0.f : mControlSize.width; + position.x = scrollRightDirection ? 0.f : mVisualModel->mControlSize.width; // Get the new handle position. // The selection handle's position is in decorator coords. Need to transforms to text coords. @@ -988,7 +1021,7 @@ void Controller::Impl::RepositionSelectionHandles( CharacterIndex selectionStart mEventData->mDecorator->AddHighlight( xPosition, offset.y, xPosition + static_cast( numberOfCharacters ) * glyphAdvance, - height ); + offset.y + height ); splitStartGlyph = false; continue; @@ -1013,14 +1046,17 @@ void Controller::Impl::RepositionSelectionHandles( CharacterIndex selectionStart mEventData->mDecorator->AddHighlight( xPosition, offset.y, xPosition + static_cast( interGlyphIndex ) * glyphAdvance, - height ); + offset.y + height ); splitEndGlyph = false; continue; } const float xPosition = position.x - glyph.xBearing + offset.x; - mEventData->mDecorator->AddHighlight( xPosition, offset.y, xPosition + glyph.advance, height ); + mEventData->mDecorator->AddHighlight( xPosition, + offset.y, + xPosition + glyph.advance, + offset.y + height ); } CursorInfo primaryCursorInfo; @@ -1038,6 +1074,9 @@ void Controller::Impl::RepositionSelectionHandles( CharacterIndex selectionStart mEventData->mDecorator->SetPosition( RIGHT_SELECTION_HANDLE, secondaryPosition.x, secondaryPosition.y, secondaryCursorInfo.lineHeight ); + // Cursor to be positioned at end of selection so if selection interrupted and edit mode restarted the cursor will be at end of selection + mEventData->mPrimaryCursorPosition = (indicesSwapped)?mEventData->mLeftSelectionPosition:mEventData->mRightSelectionPosition; + // Set the flag to update the decorator. mEventData->mDecoratorUpdated = true; } @@ -1458,7 +1497,7 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical, cursorInfo.lineHeight = GetDefaultFontLineHeight(); cursorInfo.primaryCursorHeight = cursorInfo.lineHeight; - cursorInfo.primaryPosition.x = 1.f; + cursorInfo.primaryPosition.x = mEventData->mDecorator->GetCursorWidth(); cursorInfo.primaryPosition.y = 0.f; // Nothing else to do. @@ -1694,7 +1733,7 @@ void Controller::Impl::UpdateCursorPosition() return; } - if( IsShowingPlaceholderText() ) + if( IsShowingPlaceholderText() || ( 0u == mLogicalModel->mText.Count() ) ) { // Do not want to use the place-holder text to set the cursor position. @@ -1727,17 +1766,17 @@ void Controller::Impl::UpdateCursorPosition() { case LayoutEngine::HORIZONTAL_ALIGN_BEGIN: { - cursorPosition.x = 1.f; + cursorPosition.x = mEventData->mDecorator->GetCursorWidth(); break; } case LayoutEngine::HORIZONTAL_ALIGN_CENTER: { - cursorPosition.x = floor( 0.5f * mControlSize.width ); + cursorPosition.x = floor( 0.5f * mVisualModel->mControlSize.width ); break; } case LayoutEngine::HORIZONTAL_ALIGN_END: { - cursorPosition.x = mControlSize.width; + cursorPosition.x = mVisualModel->mControlSize.width; break; } } @@ -1751,12 +1790,12 @@ void Controller::Impl::UpdateCursorPosition() } case LayoutEngine::VERTICAL_ALIGN_CENTER: { - cursorPosition.y = floorf( 0.5f * ( mControlSize.height - lineHeight ) ); + cursorPosition.y = floorf( 0.5f * ( mVisualModel->mControlSize.height - lineHeight ) ); break; } case LayoutEngine::VERTICAL_ALIGN_BOTTOM: { - cursorPosition.y = mControlSize.height - lineHeight; + cursorPosition.y = mVisualModel->mControlSize.height - lineHeight; break; } } @@ -1841,9 +1880,9 @@ void Controller::Impl::UpdateSelectionHandle( HandleType handleType ) void Controller::Impl::ClampHorizontalScroll( const Vector2& actualSize ) { // Clamp between -space & 0 (and the text alignment). - if( actualSize.width > mControlSize.width ) + if( actualSize.width > mVisualModel->mControlSize.width ) { - const float space = ( actualSize.width - mControlSize.width ) + mAlignmentOffset.x; + const float space = ( actualSize.width - mVisualModel->mControlSize.width ) + mAlignmentOffset.x; mEventData->mScrollPosition.x = ( mEventData->mScrollPosition.x < -space ) ? -space : mEventData->mScrollPosition.x; mEventData->mScrollPosition.x = ( mEventData->mScrollPosition.x > -mAlignmentOffset.x ) ? -mAlignmentOffset.x : mEventData->mScrollPosition.x; @@ -1858,9 +1897,9 @@ void Controller::Impl::ClampHorizontalScroll( const Vector2& actualSize ) void Controller::Impl::ClampVerticalScroll( const Vector2& actualSize ) { // Clamp between -space & 0 (and the text alignment). - if( actualSize.height > mControlSize.height ) + if( actualSize.height > mVisualModel->mControlSize.height ) { - const float space = ( actualSize.height - mControlSize.height ) + mAlignmentOffset.y; + const float space = ( actualSize.height - mVisualModel->mControlSize.height ) + mAlignmentOffset.y; mEventData->mScrollPosition.y = ( mEventData->mScrollPosition.y < -space ) ? -space : mEventData->mScrollPosition.y; mEventData->mScrollPosition.y = ( mEventData->mScrollPosition.y > -mAlignmentOffset.y ) ? -mAlignmentOffset.y : mEventData->mScrollPosition.y; @@ -1882,9 +1921,9 @@ void Controller::Impl::ScrollToMakePositionVisible( const Vector2& position ) mEventData->mScrollPosition.x += offset.x; updateDecorator = true; } - else if( position.x > mControlSize.width ) + else if( position.x > mVisualModel->mControlSize.width ) { - offset.x = mControlSize.width - position.x; + offset.x = mVisualModel->mControlSize.width - position.x; mEventData->mScrollPosition.x += offset.x; updateDecorator = true; } @@ -1939,8 +1978,9 @@ void Controller::Impl::ScrollTextToMatchCursor() } // Set which cursors are active according the state. - if( ( EventData::EDITING == mEventData->mState ) || - ( EventData::EDITING_WITH_POPUP == mEventData->mState ) || + if( ( EventData::EDITING == mEventData->mState ) || + ( EventData::EDITING_WITH_POPUP == mEventData->mState ) || + ( EventData::EDITING_WITH_GRAB_HANDLE == mEventData->mState ) || ( EventData::GRAB_HANDLE_PANNING == mEventData->mState ) ) { if( cursorInfo.isSecondaryCursor )