From fb0ac60585dd9becfbb208328d9f4625e6cbde8c Mon Sep 17 00:00:00 2001 From: Victor Cebollada Date: Fri, 8 May 2015 09:15:30 +0100 Subject: [PATCH] TextLayout - Wrap a word by character if it doesn't fit. Change-Id: I73c2005e0fab4ce538248ca0c428803096fce460 Signed-off-by: Victor Cebollada --- .../internal/text/layouts/layout-engine.cpp | 59 +++++++++++++++++++--- 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/dali-toolkit/internal/text/layouts/layout-engine.cpp b/dali-toolkit/internal/text/layouts/layout-engine.cpp index e165103..1589446 100644 --- a/dali-toolkit/internal/text/layouts/layout-engine.cpp +++ b/dali-toolkit/internal/text/layouts/layout-engine.cpp @@ -22,6 +22,7 @@ #include #include #include +#include // INTERNAL INCLUDES #include @@ -39,6 +40,10 @@ namespace Text namespace { +#if defined(DEBUG_ENABLED) + Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_LAYOUT"); +#endif + const float MAX_FLOAT = std::numeric_limits::max(); const bool RTL = true; @@ -52,8 +57,8 @@ struct LineLayout LineLayout() : glyphIndex( 0u ), characterIndex( 0u ), - numberOfCharacters( 0u ), numberOfGlyphs( 0u ), + numberOfCharacters( 0u ), length( 0.f ), widthAdvanceDiff( 0.f ), wsLengthEndOfLine( 0.f ), @@ -68,8 +73,8 @@ struct LineLayout { glyphIndex = 0u; characterIndex = 0u; - numberOfCharacters = 0u; numberOfGlyphs = 0u; + numberOfCharacters = 0u; length = 0.f; widthAdvanceDiff = 0.f; wsLengthEndOfLine = 0.f; @@ -79,8 +84,8 @@ struct LineLayout GlyphIndex glyphIndex; ///< Index of the first glyph to be laid-out. CharacterIndex characterIndex; ///< Index of the first character to be laid-out. - Length numberOfCharacters; ///< The number of characters which fit in one line. Length numberOfGlyphs; ///< The number of glyph which fit in one line. + Length numberOfCharacters; ///< The number of characters which fit in one line. float length; ///< The length of the glyphs which fit in one line. float widthAdvanceDiff; ///< The difference between the xBearing + width and the advance of the last glyph. float wsLengthEndOfLine; ///< The length of the white spaces at the end of the line. @@ -164,6 +169,8 @@ struct LayoutEngine::Impl void GetLineLayoutForBox( const LayoutParameters& parameters, LineLayout& lineLayout ) { + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "-->GetLineLayoutForBox\n" ); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, " initial glyph index : %d\n", lineLayout.glyphIndex ); // Stores temporary line layout which has not been added to the final line layout. LineLayout tmpLineLayout; @@ -209,6 +216,7 @@ struct LayoutEngine::Impl glyphIndex < parameters.totalNumberOfGlyphs; ++glyphIndex ) { + DALI_LOG_INFO( gLogFilter, Debug::Verbose, " glyph index : %d\n", glyphIndex ); const bool isLastGlyph = glyphIndex == lastGlyphIndex; // Get the glyph info. @@ -237,6 +245,10 @@ struct LayoutEngine::Impl const Character character = *( parameters.textBuffer + characterFirstIndex ); const bool isWhiteSpace = TextAbstraction::IsWhiteSpace( character ); + // Used to restore the temporal line layout when a single word does not fit in the control's width and is split by character. + const float previousTmpLineLength = tmpLineLayout.length; + const float previousTmpWidthAdvanceDiff = tmpLineLayout.widthAdvanceDiff; + // Increase the accumulated length. if( isWhiteSpace ) { @@ -261,10 +273,31 @@ struct LayoutEngine::Impl } // Check if the accumulated length fits in the width of the box. - if( isMultiline && oneWordLaidOut && !isWhiteSpace && + if( isMultiline && !isWhiteSpace && ( lineLayout.length + lineLayout.wsLengthEndOfLine + tmpLineLayout.length + tmpLineLayout.widthAdvanceDiff > boundingBoxWidth ) ) { // Current word does not fit in the box's width. + if( !oneWordLaidOut ) + { + DALI_LOG_INFO( gLogFilter, Debug::Verbose, " Break the word by character\n" ); + + // The word's with doesn't fit in the control's with. It needs to be split by character. + if( tmpLineLayout.numberOfGlyphs > 1u ) + { + tmpLineLayout.numberOfCharacters -= charactersPerGlyph; + --tmpLineLayout.numberOfGlyphs; + tmpLineLayout.length = previousTmpLineLength; + tmpLineLayout.widthAdvanceDiff = previousTmpWidthAdvanceDiff; + } + + // Add part of the word to the line layout. + MergeLineLayout( lineLayout, tmpLineLayout ); + } + else + { + DALI_LOG_INFO( gLogFilter, Debug::Verbose, " Current word does not fit.\n" ); + } + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--GetLineLayoutForBox\n" ); return; } @@ -274,16 +307,16 @@ struct LayoutEngine::Impl // Must break the line. Update the line layout and return. MergeLineLayout( lineLayout, tmpLineLayout ); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, " Must break\n" ); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--GetLineLayoutForBox\n" ); return; } if( isMultiline && ( TextAbstraction::WORD_BREAK == wordBreakInfo ) ) { - if( !oneWordLaidOut && !isWhiteSpace ) - { - oneWordLaidOut = true; - } + oneWordLaidOut = true; + DALI_LOG_INFO( gLogFilter, Debug::Verbose, " One word laid out\n" ); // Current glyph is the last one of the current word. // Add the temporal layout to the current one. @@ -300,6 +333,7 @@ struct LayoutEngine::Impl lastFontId = glyphInfo.fontId; } } + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--GetLineLayoutForBox\n" ); } bool LayoutText( const LayoutParameters& layoutParameters, @@ -307,6 +341,7 @@ struct LayoutEngine::Impl Vector& lines, Size& actualSize ) { + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "-->LayoutText\n" ); Vector2* glyphPositionsBuffer = glyphPositions.Begin(); float penY = 0.f; @@ -318,9 +353,16 @@ struct LayoutEngine::Impl GetLineLayoutForBox( layoutParameters, layout ); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, " glyph index %d\n", layout.glyphIndex ); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, " character index %d\n", layout.characterIndex ); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, " number of glyphs %d\n", layout.numberOfGlyphs ); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, " number of characters %d\n", layout.numberOfCharacters ); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, " length %f\n", layout.length ); + if( 0u == layout.numberOfGlyphs ) { // The width is too small and no characters are laid-out. + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--LayoutText width too small!\n\n" ); return false; } @@ -377,6 +419,7 @@ struct LayoutEngine::Impl index += layout.numberOfGlyphs; } + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--LayoutText\n\n" ); return true; } -- 2.7.4