From 623f66dbb88907eb2effc163a5fb8a6d4836c534 Mon Sep 17 00:00:00 2001 From: Victor Cebollada Date: Thu, 25 Sep 2014 14:21:52 +0100 Subject: [PATCH] TextView - Do not create TextActor with white spaces. Change-Id: I7988b4ce7357b7a2dc3e2b6a68fed35f8204fbde Signed-off-by: Victor Cebollada --- .../controls/text-view/relayout-utilities.cpp | 191 ++++++++++++--------- 1 file changed, 107 insertions(+), 84 deletions(-) diff --git a/base/dali-toolkit/internal/controls/text-view/relayout-utilities.cpp b/base/dali-toolkit/internal/controls/text-view/relayout-utilities.cpp index b172976..c21cccf 100644 --- a/base/dali-toolkit/internal/controls/text-view/relayout-utilities.cpp +++ b/base/dali-toolkit/internal/controls/text-view/relayout-utilities.cpp @@ -472,6 +472,11 @@ void ReorderLayout( std::size_t characterGlobalIndex, Vector positions; TextProcessor::SplitInWords( info->mText, positions ); + // Whether last character is a word or a paragraph separator. + const std::size_t lastCharacterIndex = info->mText.GetLength() - 1u; + const bool isLastCharacterParagraphSeparator = info->mText.IsNewLine( lastCharacterIndex ); + const bool isLastCharacterWordSeparator = info->mText.IsWhiteSpace( lastCharacterIndex ); + // Sets the characters into the words they belong to. for( Vector::ConstIterator it = positions.Begin(), endIt = positions.End(); it != endIt; ++it ) { @@ -492,10 +497,13 @@ void ReorderLayout( std::size_t characterGlobalIndex, // white space or new paragraph. TextViewProcessor::WordLayoutInfo space; + space.mCharactersLayoutInfo.insert( space.mCharactersLayoutInfo.end(), characters.begin() + position, characters.begin() + position + 1u ); + space.mType = TextViewProcessor::WordSeparator; + TextViewProcessor::UpdateLayoutInfo( space ); paragraph.mRightToLeftLayout->mWordsLayoutInfo.push_back( space ); @@ -511,6 +519,14 @@ void ReorderLayout( std::size_t characterGlobalIndex, characters.begin() + previousPosition, characters.end() ); + if( isLastCharacterParagraphSeparator ) + { + word.mType = TextViewProcessor::ParagraphSeparator; + } + else if( isLastCharacterWordSeparator ) + { + word.mType = TextViewProcessor::WordSeparator; + } TextViewProcessor::UpdateLayoutInfo( word ); paragraph.mRightToLeftLayout->mWordsLayoutInfo.push_back( word ); @@ -1889,21 +1905,27 @@ void CreateEmoticon( const TextView::VisualParameters& visualParameters, * @param[in] visualParameters Some visual parameters (fade, sort modifier and blending). * @param[in,out] relayoutData Natural size (metrics), layout, text-actor info. * @param[in,out] paragraph Layout info for the paragraph. + * @param[in,out] wordLayout Layout info for the word. * @param[in,out] characterLayout Layout info for the character. * @param[in] character The character. * @param[in] style The character's style. * @param[in,out] currentTextActorInfo Temporary stores the text-actor's info to be set. * @param[in,out] createGlyphActors Whether to initialize renderable-actor handles. + * @param[in,out] textActorCreated Whether a text-actor */ void CreateTextActor( const TextView::VisualParameters& visualParameters, TextView::RelayoutData& relayoutData, const TextViewProcessor::ParagraphLayoutInfo& paragraph, + TextViewProcessor::WordLayoutInfo& wordLayout, TextViewProcessor::CharacterLayoutInfo& characterLayout, const Character& character, const TextStyle& style, CurrentTextActorInfo& currentTextActorInfo, - bool createGlyphActors ) + bool createGlyphActors, + bool& textActorCreated ) { + textActorCreated = false; + // Set the text-actor for the current traversed text. if( currentTextActorInfo.textActor ) { @@ -1932,7 +1954,18 @@ void CreateTextActor( const TextView::VisualParameters& visualParameters, rightToLeftOffset = characterLayout.mSize.width * relayoutData.mShrinkFactor; } - currentTextActorInfo.text = Text( character ); + // Whether this word is not a white space or if it is, it is underlined. + // Don't want to create text-actors for white spaces unless they are underlined. + bool isNotWhiteSpace = ( TextViewProcessor::NoSeparator == wordLayout.mType ) || ( ( TextViewProcessor::WordSeparator == wordLayout.mType ) && style.IsUnderlineEnabled() ); + + if( isNotWhiteSpace ) + { + currentTextActorInfo.text = Text( character ); + } + else + { + currentTextActorInfo.text = Text(); + } currentTextActorInfo.position = Vector3( characterLayout.mPosition.x + characterLayout.mOffset.x - rightToLeftOffset, characterLayout.mPosition.y + characterLayout.mOffset.y, characterLayout.mPosition.z ); @@ -1943,8 +1976,9 @@ void CreateTextActor( const TextView::VisualParameters& visualParameters, TextActor textActor = TextActor::DownCast( characterLayout.mGlyphActor ); - if( createGlyphActors ) + if( createGlyphActors && isNotWhiteSpace ) { + textActorCreated = true; if( textActor ) { // Try to reuse first the text-actor of this character. @@ -1993,16 +2027,14 @@ void UpdateTextActorInfoForParagraph( const TextView::VisualParameters& visualPa std::size_t& lineLayoutInfoIndex, bool createGlyphActors ) { - // TODO: Check if there is text-actor created only with white spaces. Check first in RTL text. - CurrentTextActorInfo currentTextActorInfo; currentTextActorInfo.characterLayout = NULL; const std::size_t lineLayoutInfoSize = relayoutData.mLines.size(); // Number of lines. - bool lineLayoutEnd = false; // Whether lineLayoutInfoIndex points at the last line. - bool glyphActorCreatedForLine = false; // Whether a renderable actor has been created for this line. + bool lineLayoutEnd = false; // Whether lineLayoutInfoIndex points at the last line. + bool textActorCreated = false; // Whether a text actor has been created for this the current group of characters traversed. - TextStyle currentStyle; // style for the current text-actor. + TextStyle currentStyle; // style for the current text-actor. TextViewProcessor::GradientInfo* currentGradientInfo = NULL; // gradient color for the current text-actor. // start point for the current text-actor. @@ -2020,7 +2052,7 @@ void UpdateTextActorInfoForParagraph( const TextView::VisualParameters& visualPa Vector& textStyles = isRightToLeftLayout ? paragraphLayout.mRightToLeftLayout->mTextStyles : paragraphLayout.mTextStyles; // In case the previous right to left layout has been cleared, all text-actors have been removed as well. If this bool is set to true, text-actors will be created again. - const bool previousRightToLeftLayoutCleared = isRightToLeftLayout ? paragraphLayout.mRightToLeftLayout->mPreviousLayoutCleared : false; + createGlyphActors = createGlyphActors || ( ( isRightToLeftLayout ) ? paragraphLayout.mRightToLeftLayout->mPreviousLayoutCleared : false ); std::size_t characterParagraphIndex = 0u; // Index to the character (within the paragraph). for( TextViewProcessor::WordLayoutInfoContainer::iterator wordIt = wordsLayoutInfo.begin(), wordEndIt = wordsLayoutInfo.end(); @@ -2047,104 +2079,77 @@ void UpdateTextActorInfoForParagraph( const TextView::VisualParameters& visualPa // Arrived at last line. lineLayoutEnd = true; // Avoids access out of bounds in the relayoutData.mLines vector. } - glyphActorCreatedForLine = false; + textActorCreated = false; } // Do not create a glyph-actor if there is no text. const Character character = text[characterParagraphIndex]; const TextStyle& style = *( *( textStyles.Begin() + characterParagraphIndex ) ); - bool appendCharacter = false; - - if( characterLayout.mIsColorGlyph || - ( TextViewProcessor::NoSeparator == wordLayout.mType ) || - ( ( TextViewProcessor::WordSeparator == wordLayout.mType ) && style.IsUnderlineEnabled() ) ) + // Check if the character has the same gradient info than the current one. + bool differentGradientInfo = false; + if( characterLayout.mGradientInfo && currentGradientInfo ) { - // Do not create a glyph-actor if it's a white space (without underline) or a new paragraph character. + differentGradientInfo = ( characterLayout.mGradientInfo->mGradientColor != currentGradientInfo->mGradientColor ) || + ( characterLayout.mGradientInfo->mStartPoint != currentGradientInfo->mStartPoint ) || + ( characterLayout.mGradientInfo->mEndPoint != currentGradientInfo->mEndPoint ); + } + else if( ( NULL != currentGradientInfo ) || ( NULL != characterLayout.mGradientInfo ) ) + { + differentGradientInfo = true; + } - // Check if the character has the same gradient info than the current one. - bool differentGradientInfo = false; - if( characterLayout.mGradientInfo && currentGradientInfo ) - { - differentGradientInfo = ( characterLayout.mGradientInfo->mGradientColor != currentGradientInfo->mGradientColor ) || - ( characterLayout.mGradientInfo->mStartPoint != currentGradientInfo->mStartPoint ) || - ( characterLayout.mGradientInfo->mEndPoint != currentGradientInfo->mEndPoint ); - } - else if( ( NULL != currentGradientInfo ) || ( NULL != characterLayout.mGradientInfo ) ) - { - differentGradientInfo = true; - } + if( ( createGlyphActors && !textActorCreated ) || + characterLayout.mIsColorGlyph || + differentGradientInfo || + ( characterLayout.mIsColorGlyph != currentIsColorGlyph ) || + ( style != currentStyle ) ) + { + characterLayout.mSetText = false; + characterLayout.mSetStyle = false; - // Creates one glyph-actor for each counsecutive group of characters, with the same style, per line, or if it's an emoticon. - if( !glyphActorCreatedForLine || - characterLayout.mIsColorGlyph || - differentGradientInfo || - ( characterLayout.mIsColorGlyph != currentIsColorGlyph ) || - ( style != currentStyle ) ) + if( characterLayout.mIsColorGlyph ) { - characterLayout.mSetText = false; - characterLayout.mSetStyle = false; - - if( characterLayout.mIsColorGlyph ) - { - CreateEmoticon( visualParameters, - characterLayout, - character ); - } - else - { - CreateTextActor( visualParameters, - relayoutData, - paragraphLayout, - characterLayout, - character, - style, - currentTextActorInfo, - createGlyphActors || previousRightToLeftLayoutCleared ); - } - - // There is a new style or a new line. - glyphActorCreatedForLine = true; - - // Update style to be checked with next characters. - currentStyle = style; - currentGradientInfo = characterLayout.mGradientInfo; - currentIsColorGlyph = characterLayout.mIsColorGlyph; + CreateEmoticon( visualParameters, + characterLayout, + character ); characterLayout.mGlyphActor.SetParentOrigin( ParentOrigin::TOP_LEFT ); characterLayout.mGlyphActor.SetAnchorPoint( AnchorPoint::BOTTOM_LEFT ); } else { - DALI_ASSERT_DEBUG( !characterLayout.mIsColorGlyph && "TextViewProcessor::InitializeTextActorInfo. An image-actor doesn't store more than one emoticon." ); - - // Same style than previous one. - - // Add the character to the current text-actor and update the size. - appendCharacter = true; - - TextActor textActor = TextActor::DownCast( characterLayout.mGlyphActor ); - if( textActor ) - { - // There is a previously created text-actor for this character. - // If this character has another one put it into the cache. - textActor.SetText( "" ); - textActorsToRemove.push_back( textActor ); - } + // There is a new style or a new line. - if( characterLayout.mGlyphActor ) + CreateTextActor( visualParameters, + relayoutData, + paragraphLayout, + wordLayout, + characterLayout, + character, + style, + currentTextActorInfo, + createGlyphActors, + textActorCreated ); + + if( textActorCreated ) { - characterLayout.mGlyphActor.Reset(); + characterLayout.mGlyphActor.SetParentOrigin( ParentOrigin::TOP_LEFT ); + characterLayout.mGlyphActor.SetAnchorPoint( AnchorPoint::BOTTOM_LEFT ); } } - } // no white space / new paragraph char + + // Update style to be checked with next characters. + currentStyle = style; + currentGradientInfo = characterLayout.mGradientInfo; + currentIsColorGlyph = characterLayout.mIsColorGlyph; + } else { - appendCharacter = true; - } + DALI_ASSERT_DEBUG( !characterLayout.mIsColorGlyph && "TextViewProcessor::InitializeTextActorInfo. An image-actor doesn't store more than one emoticon." ); + + // Same style than previous one. - if( appendCharacter ) - { // Add the character to the current text-actor and update the size. if( characterLayout.mIsVisible && ( TextViewProcessor::ParagraphSeparator != wordLayout.mType ) ) { @@ -2156,6 +2161,24 @@ void UpdateTextActorInfoForParagraph( const TextView::VisualParameters& visualPa } } + if( ( createGlyphActors ) && + !characterLayout.mIsColorGlyph && + !textActorCreated ) + { + TextActor textActor = TextActor::DownCast( characterLayout.mGlyphActor ); + if( textActor ) + { + // There is a previously created text-actor for this character. + // If this character has another one put it into the cache. + textActor.SetText( "" ); + textActorsToRemove.push_back( textActor ); + } + + if( characterLayout.mGlyphActor ) + { + characterLayout.mGlyphActor.Reset(); + } + } ++characterGlobalIndex; ++characterParagraphIndex; } // characters -- 2.7.4