From: Victor Cebollada Date: Wed, 18 Mar 2015 09:55:04 +0000 (+0000) Subject: Text Alignment X-Git-Tag: dali_1.0.38~11^2~46 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=0207e16930421216c5a22a0fd3ac409f3bd2a7b0 Text Alignment Change-Id: Ifc246bd925e14a29ce65f90f8e1042b26c94a342 Signed-off-by: Victor Cebollada --- diff --git a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp index 09a5ecc..b5900c6 100644 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -53,6 +54,14 @@ namespace namespace { +const Scripting::StringEnum< Toolkit::Text::LayoutEngine::Alignment > ALIGNMENT_STRING_TABLE[] = +{ + { "BEGIN", Toolkit::Text::LayoutEngine::ALIGN_BEGIN }, + { "CENTER", Toolkit::Text::LayoutEngine::ALIGN_CENTER }, + { "END", Toolkit::Text::LayoutEngine::ALIGN_END }, +}; +const unsigned int ALIGNMENT_STRING_TABLE_COUNT = sizeof( ALIGNMENT_STRING_TABLE ) / sizeof( ALIGNMENT_STRING_TABLE[0] ); + // Type registration BaseHandle Create() { @@ -77,6 +86,7 @@ DALI_PROPERTY_REGISTRATION( TextField, "cursor-blink-interval", FLOAT, CUR DALI_PROPERTY_REGISTRATION( TextField, "cursor-blink-duration", FLOAT, CURSOR_BLINK_DURATION ) DALI_PROPERTY_REGISTRATION( TextField, "grab-handle-image", STRING, GRAB_HANDLE_IMAGE ) DALI_PROPERTY_REGISTRATION( TextField, "decoration bounding-box", RECTANGLE, DECORATION_BOUNDING_BOX ) +DALI_PROPERTY_REGISTRATION( TextField, "alignment", STRING, ALIGNMENT ) DALI_TYPE_REGISTRATION_END() @@ -249,6 +259,20 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr } break; } + case Toolkit::TextField::Property::ALIGNMENT: + { + LayoutEngine& engine = impl.mController->GetLayoutEngine(); + const LayoutEngine::Alignment alignment = Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::Alignment >( value.Get< std::string >().c_str(), + ALIGNMENT_STRING_TABLE, + ALIGNMENT_STRING_TABLE_COUNT ); + + if( engine.GetAlignment() != alignment ) + { + engine.SetAlignment( alignment ); + impl.RequestTextRelayout(); + } + break; + } } } } @@ -364,6 +388,16 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde } break; } + case Toolkit::TextField::Property::ALIGNMENT: + { + if( impl.mController ) + { + value = std::string( Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::Alignment >( impl.mController->GetLayoutEngine().GetAlignment(), + ALIGNMENT_STRING_TABLE, + ALIGNMENT_STRING_TABLE_COUNT ) ); + } + break; + } } } diff --git a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp index 00ae80d..118c2b3 100644 --- a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp @@ -21,6 +21,7 @@ // EXTERNAL INCLUDES #include #include +#include #include // INTERNAL INCLUDES @@ -49,6 +50,14 @@ namespace namespace { +const Scripting::StringEnum< Toolkit::Text::LayoutEngine::Alignment > ALIGNMENT_STRING_TABLE[] = +{ + { "BEGIN", Toolkit::Text::LayoutEngine::ALIGN_BEGIN }, + { "CENTER", Toolkit::Text::LayoutEngine::ALIGN_CENTER }, + { "END", Toolkit::Text::LayoutEngine::ALIGN_END }, +}; +const unsigned int ALIGNMENT_STRING_TABLE_COUNT = sizeof( ALIGNMENT_STRING_TABLE ) / sizeof( ALIGNMENT_STRING_TABLE[0] ); + // Type registration BaseHandle Create() { @@ -64,6 +73,7 @@ DALI_PROPERTY_REGISTRATION( TextLabel, "font-family", STRING, FONT_FAMILY DALI_PROPERTY_REGISTRATION( TextLabel, "font-style", STRING, FONT_STYLE ) DALI_PROPERTY_REGISTRATION( TextLabel, "point-size", FLOAT, POINT_SIZE ) DALI_PROPERTY_REGISTRATION( TextLabel, "multi-line", BOOLEAN, MULTI_LINE ) +DALI_PROPERTY_REGISTRATION( TextLabel, "alignment", STRING, ALIGNMENT ) DALI_TYPE_REGISTRATION_END() @@ -165,12 +175,26 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr if( engine.GetLayout() != layout ) { - impl.mController->GetLayoutEngine().SetLayout( layout ); + engine.SetLayout( layout ); impl.RequestTextRelayout(); } } break; } + case Toolkit::TextLabel::Property::ALIGNMENT: + { + LayoutEngine& engine = impl.mController->GetLayoutEngine(); + const LayoutEngine::Alignment alignment = Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::Alignment >( value.Get< std::string >().c_str(), + ALIGNMENT_STRING_TABLE, + ALIGNMENT_STRING_TABLE_COUNT ); + + if( engine.GetAlignment() != alignment ) + { + engine.SetAlignment( alignment ); + impl.RequestTextRelayout(); + } + break; + } } } } @@ -209,6 +233,16 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde } break; } + case Toolkit::TextLabel::Property::ALIGNMENT: + { + if( impl.mController ) + { + value = std::string( Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::Alignment >( impl.mController->GetLayoutEngine().GetAlignment(), + ALIGNMENT_STRING_TABLE, + ALIGNMENT_STRING_TABLE_COUNT ) ); + } + break; + } } } diff --git a/dali-toolkit/internal/text/bidirectional-line-info-run.h b/dali-toolkit/internal/text/bidirectional-line-info-run.h index 9aeea2a..355668d 100644 --- a/dali-toolkit/internal/text/bidirectional-line-info-run.h +++ b/dali-toolkit/internal/text/bidirectional-line-info-run.h @@ -35,8 +35,9 @@ namespace Text */ struct BidirectionalLineInfoRun { - CharacterRun characterRun; ///< The initial character index within the whole text and the number of characters of the run. - CharacterIndex* visualToLogicalMap; ///< Pointer to the visual to logical map table. + CharacterRun characterRun; ///< The initial character index within the whole text and the number of characters of the run. + CharacterIndex* visualToLogicalMap; ///< Pointer to the visual to logical map table. + CharacterDirection direction; ///< Direction of the first character of the paragraph. }; } // namespace Text diff --git a/dali-toolkit/internal/text/bidirectional-support.cpp b/dali-toolkit/internal/text/bidirectional-support.cpp index f20641b..b9ff99a 100644 --- a/dali-toolkit/internal/text/bidirectional-support.cpp +++ b/dali-toolkit/internal/text/bidirectional-support.cpp @@ -185,6 +185,7 @@ void ReorderLines( const Vector& bidirectionalInf ++it ) { const BidirectionalParagraphInfoRun& paragraphInfo = *it; + const CharacterDirection direction = bidirectionalSupport.GetParagraphDirection( paragraphInfo.bidirectionalInfoIndex ); // Get the lines for this paragraph. unsigned int firstLine = 0u; @@ -211,6 +212,7 @@ void ReorderLines( const Vector& bidirectionalInf BidirectionalLineInfoRun lineInfoRun; lineInfoRun.characterRun.characterIndex = line.characterRun.characterIndex; lineInfoRun.characterRun.numberOfCharacters = line.characterRun.numberOfCharacters; + lineInfoRun.direction = direction; // Allocate space for the conversion maps. // The memory is freed after the visual to logical to visual conversion tables are built in the logical model. diff --git a/dali-toolkit/internal/text/layouts/layout-engine.cpp b/dali-toolkit/internal/text/layouts/layout-engine.cpp index 86ddbb4..1eed911 100644 --- a/dali-toolkit/internal/text/layouts/layout-engine.cpp +++ b/dali-toolkit/internal/text/layouts/layout-engine.cpp @@ -53,7 +53,8 @@ struct LineLayout struct LayoutEngine::Impl { Impl() - : mLayout( LayoutEngine::SINGLE_LINE_BOX ) + : mLayout( LayoutEngine::SINGLE_LINE_BOX ), + mAlignment( LayoutEngine::ALIGN_BEGIN ) { mFontClient = TextAbstraction::FontClient::Get(); } @@ -83,6 +84,10 @@ struct LayoutEngine::Impl // Get the glyph info. const GlyphInfo& glyphInfo = *( parameters.glyphsBuffer + glyphIndex ); + // Check whether is a white space. + const Character character = *( parameters.textBuffer + lineLayout.numberOfCharacters ); + const bool isWhiteSpace = TextAbstraction::IsWhiteSpace( character ); + // Get the character indices for the current glyph. The last character index is needed // because there are glyphs formed by more than one character but their break info is // given only for the last character. @@ -95,7 +100,21 @@ struct LayoutEngine::Impl lineLayout.numberOfGlyphs++; // Increase the accumulated length. - lineLayout.length += ( glyphIndex == lastGlyphIndex ) ? glyphInfo.width : glyphInfo.advance; + const float glyphLength = ( glyphIndex == lastGlyphIndex ) ? glyphInfo.width : glyphInfo.advance; + + if( isWhiteSpace ) + { + // Add the length to the length of white spaces at the end of the line. + lineLayout.wsLengthEndOfLine += glyphLength; + } + else + { + // Add as well any previous white space length. + lineLayout.length += lineLayout.wsLengthEndOfLine + glyphLength; + + // Clear the white space length at the end of the line. + lineLayout.wsLengthEndOfLine = 0.f; + } if( lastFontId != glyphInfo.fontId ) { @@ -172,11 +191,27 @@ struct LayoutEngine::Impl // Increase the number of glyphs. tmpLineLayout.numberOfGlyphs++; + // Check whether is a white space. + const Character character = *( parameters.textBuffer + characterFirstIndex ); + const bool isWhiteSpace = TextAbstraction::IsWhiteSpace( character ); + // Increase the accumulated length. - tmpLineLayout.length += ( glyphIndex == lastGlyphIndex ) ? glyphInfo.width : glyphInfo.advance; + if( isWhiteSpace ) + { + // Add the length to the length of white spaces at the end of the line. + tmpLineLayout.wsLengthEndOfLine += glyphInfo.advance; // I use the advance as the width is always zero for the white spaces. + } + else + { + // Add as well any previous white space length. + tmpLineLayout.length += tmpLineLayout.wsLengthEndOfLine + ( glyphIndex == lastGlyphIndex ) ? glyphInfo.width : glyphInfo.advance; + + // Clear the white space length at the end of the line. + tmpLineLayout.wsLengthEndOfLine = 0.f; + } // Check if the accumulated length fits in the width of the box. - if( lineLayout.length + tmpLineLayout.length > parameters.boundingBox.width ) + if( lineLayout.length + tmpLineLayout.length + ( ( 0.f < tmpLineLayout.length ) ? lineLayout.wsLengthEndOfLine : 0.f ) > parameters.boundingBox.width ) { // Current word does not fit in the box's width. return; @@ -190,7 +225,17 @@ struct LayoutEngine::Impl lineLayout.numberOfCharacters += tmpLineLayout.numberOfCharacters; lineLayout.numberOfGlyphs += tmpLineLayout.numberOfGlyphs; lineLayout.length += tmpLineLayout.length; - lineLayout.wsLengthEndOfLine = tmpLineLayout.wsLengthEndOfLine; + + if( 0.f < tmpLineLayout.length ) + { + lineLayout.length += lineLayout.wsLengthEndOfLine; + + lineLayout.wsLengthEndOfLine = tmpLineLayout.wsLengthEndOfLine; + } + else + { + lineLayout.wsLengthEndOfLine += tmpLineLayout.wsLengthEndOfLine; + } if( tmpLineLayout.height > lineLayout.height ) { @@ -219,7 +264,16 @@ struct LayoutEngine::Impl lineLayout.numberOfCharacters += tmpLineLayout.numberOfCharacters; lineLayout.numberOfGlyphs += tmpLineLayout.numberOfGlyphs; lineLayout.length += tmpLineLayout.length; - lineLayout.wsLengthEndOfLine = tmpLineLayout.wsLengthEndOfLine; + if( 0.f < tmpLineLayout.length ) + { + lineLayout.length += lineLayout.wsLengthEndOfLine; + + lineLayout.wsLengthEndOfLine = tmpLineLayout.wsLengthEndOfLine; + } + else + { + lineLayout.wsLengthEndOfLine += tmpLineLayout.wsLengthEndOfLine; + } if( tmpLineLayout.height > lineLayout.height ) { @@ -297,7 +351,7 @@ struct LayoutEngine::Impl void ReLayoutRightToLeftLines( const LayoutParameters& layoutParameters, Vector& glyphPositions ) { - for( Length lineIndex = 0u; lineIndex < layoutParameters.numberOfBidirectionalInfoRuns; ++lineIndex ) + for( LineIndex lineIndex = 0u; lineIndex < layoutParameters.numberOfBidirectionalInfoRuns; ++lineIndex ) { const BidirectionalLineInfoRun& bidiLine = *( layoutParameters.lineBidirectionalInfoRunsBuffer +lineIndex ); @@ -324,13 +378,72 @@ struct LayoutEngine::Impl Vector2& position = *( glyphPositionsBuffer + glyphIndex ); position.x = penX + glyph.xBearing; - penX += glyph.advance; } } } } + void Align( const LayoutParameters& layoutParameters, + const Vector& lines, + Vector& glyphPositions ) + { + Vector2* glyphPositionsBuffer = glyphPositions.Begin(); + + // Traverse all lines and align the glyphs. + // LayoutParameters contains bidirectional info for those lines with + // right to left text, this info includes the paragraph's direction. + + LineIndex bidiLineIndex = 0u; + for( Vector::ConstIterator it = lines.Begin(), endIt = lines.End(); + it != endIt; + ++it ) + { + const LineRun& line = *it; + + // 1) Get the paragrap's direction. + bool paragraphDirection = false; + + // Check if there is any right to left line. + if( ( NULL != layoutParameters.lineBidirectionalInfoRunsBuffer ) && + ( bidiLineIndex < layoutParameters.numberOfBidirectionalInfoRuns ) ) + { + const BidirectionalLineInfoRun* bidiLine = layoutParameters.lineBidirectionalInfoRunsBuffer + bidiLineIndex; + + // Get the right to left line that match with current line. + while( ( line.characterRun.characterIndex > bidiLine->characterRun.characterIndex ) && + ( bidiLineIndex < layoutParameters.numberOfBidirectionalInfoRuns ) ) + { + ++bidiLineIndex; + bidiLine = layoutParameters.lineBidirectionalInfoRunsBuffer + bidiLineIndex; + } + + if( line.characterRun.characterIndex == bidiLine->characterRun.characterIndex ) + { + paragraphDirection = bidiLine->direction; + } + } + + // 2) Calculate the alignment offset accordingly with the align option, + // the box width, line length, and the paragraphs direction. + float alignOffset = CalculateAlignment( layoutParameters.boundingBox.width, + line.lineSize.width, + line.extraLength, + paragraphDirection ); + + // 3) Traverse all glyphs and update the 'x' position. + for( GlyphIndex index = line.glyphIndex, + endIndex = line.glyphIndex + line.numberOfGlyphs; + index < endIndex; + ++index ) + { + Vector2& position = *( glyphPositionsBuffer + index ); + + position.x += alignOffset; + } + } + } + bool SingleLineLayout( const LayoutParameters& layoutParameters, Vector& glyphPositions, Vector& lines, @@ -351,6 +464,7 @@ struct LayoutEngine::Impl lineRun.characterRun.numberOfCharacters = *( layoutParameters.glyphsToCharactersBuffer + lastGlyphIndex ) + *( layoutParameters.charactersPerGlyphBuffer + lastGlyphIndex ); lineRun.lineSize.width = layout.length; lineRun.lineSize.height = layout.height; + lineRun.extraLength = layout.wsLengthEndOfLine; lines.PushBack( lineRun ); @@ -408,6 +522,7 @@ struct LayoutEngine::Impl lineRun.characterRun.numberOfCharacters = ( *( layoutParameters.glyphsToCharactersBuffer + lastGlyphIndex ) + *( layoutParameters.charactersPerGlyphBuffer + lastGlyphIndex ) ) - lineRun.characterRun.characterIndex; lineRun.lineSize.width = layout.length; lineRun.lineSize.height = layout.height; + lineRun.extraLength = layout.wsLengthEndOfLine; lines.PushBack( lineRun ); @@ -442,7 +557,56 @@ struct LayoutEngine::Impl return true; } + float CalculateAlignment( float boxWidth, + float lineLength, + float extraLength, + bool paragraphDirection ) + { + float offset = 0.f; + + Alignment alignment = mAlignment; + if( paragraphDirection && + ( ALIGN_CENTER != alignment ) ) + { + if( ALIGN_BEGIN == alignment ) + { + alignment = ALIGN_END; + } + else + { + alignment = ALIGN_BEGIN; + } + } + + switch( alignment ) + { + case ALIGN_BEGIN: + { + offset = 0.f; + break; + } + case ALIGN_CENTER: + { + offset = 0.5f * ( boxWidth - lineLength ); + break; + } + case ALIGN_END: + { + offset = boxWidth - lineLength; + break; + } + } + + if( paragraphDirection ) + { + offset -= extraLength; + } + + return offset; + } + LayoutEngine::Layout mLayout; + LayoutEngine::Alignment mAlignment; TextAbstraction::FontClient mFontClient; }; @@ -468,6 +632,16 @@ unsigned int LayoutEngine::GetLayout() const return mImpl->mLayout; } +void LayoutEngine::SetAlignment( Alignment alignment ) +{ + mImpl->mAlignment = alignment; +} + +LayoutEngine::Alignment LayoutEngine::GetAlignment() const +{ + return mImpl->mAlignment; +} + bool LayoutEngine::LayoutText( const LayoutParameters& layoutParameters, Vector& glyphPositions, Vector& lines, @@ -486,6 +660,15 @@ void LayoutEngine::ReLayoutRightToLeftLines( const LayoutParameters& layoutParam glyphPositions ); } +void LayoutEngine::Align( const LayoutParameters& layoutParameters, + const Vector& lines, + Vector& glyphPositions ) +{ + mImpl->Align( layoutParameters, + lines, + glyphPositions ); +} + } // namespace Text } // namespace Toolkit diff --git a/dali-toolkit/internal/text/layouts/layout-engine.h b/dali-toolkit/internal/text/layouts/layout-engine.h index cdcd156..093399b 100644 --- a/dali-toolkit/internal/text/layouts/layout-engine.h +++ b/dali-toolkit/internal/text/layouts/layout-engine.h @@ -51,6 +51,13 @@ public: MULTI_LINE_BOX }; + enum Alignment + { + ALIGN_BEGIN, + ALIGN_CENTER, + ALIGN_END + }; + /** * @brief Create a new instance of a LayoutEngine. */ @@ -76,6 +83,20 @@ public: unsigned int GetLayout() const; /** + * @brief Choose the required line alignment. + * + * @param[in] alignment The required alignment. + */ + void SetAlignment( Alignment alignment ); + + /** + * @brief Query the required line alignment. + * + * @return The required alignment. + */ + Alignment GetAlignment() const; + + /** * @brief Store the visual position of glyphs in the VisualModel. * * @param[in] layoutParameters The parameters needed to layout the text. @@ -91,7 +112,7 @@ public: Size& actualSize ); /** - * Re-lays out those lines with right to left characters. + * @brief Re-lays out those lines with right to left characters. * * It doesn't change the phisical position of the glyphs in the model but sets their new position. * @@ -101,6 +122,17 @@ public: void ReLayoutRightToLeftLines( const LayoutParameters& layoutParameters, Vector& glyphPositions ); + /** + * @brief Aligns the laid out lines. + * + * @param[in] layoutParameters The parameters needed to layout the text. + * @param[in] lines The laid-out lines. + * @param[in,out] glyphPositions The positions of all the glyphs. + */ + void Align( const LayoutParameters& layoutParameters, + const Vector& lines, + Vector& glyphPositions ); + private: // Undefined diff --git a/dali-toolkit/internal/text/layouts/layout-parameters.h b/dali-toolkit/internal/text/layouts/layout-parameters.h index 808e1ae..a370c02 100644 --- a/dali-toolkit/internal/text/layouts/layout-parameters.h +++ b/dali-toolkit/internal/text/layouts/layout-parameters.h @@ -44,6 +44,7 @@ struct LayoutParameters * Constructor with the needed parameters to layout the text. * * @param[in] boundingBox The size of the box containing the text. + * @param[in] textBuffer The text buffer. * @param[in] lineBreakInfoBuffer The line break info. * @param[in] wordBreakInfoBuffer The word break info. * @param[in] totalNumberOfGlyphs The number of glyphs. @@ -52,6 +53,7 @@ struct LayoutParameters * @param[in] charactersPerGlyphBuffer Vector with the number of characters that forms each glyph. */ LayoutParameters( const Vector2& boundingBox, + const Character* const textBuffer, const LineBreakInfo* const lineBreakInfoBuffer, const WordBreakInfo* const wordBreakInfoBuffer, Length totalNumberOfGlyphs, @@ -59,6 +61,7 @@ struct LayoutParameters const CharacterIndex* const glyphsToCharactersBuffer, const Length* const charactersPerGlyphBuffer ) : boundingBox( boundingBox ), + textBuffer( textBuffer ), lineBreakInfoBuffer( lineBreakInfoBuffer ), wordBreakInfoBuffer( wordBreakInfoBuffer ), totalNumberOfGlyphs( totalNumberOfGlyphs ), @@ -72,6 +75,7 @@ struct LayoutParameters {} Vector2 boundingBox; + const Character* const textBuffer; const LineBreakInfo* const lineBreakInfoBuffer; const WordBreakInfo* const wordBreakInfoBuffer; Length totalNumberOfGlyphs; diff --git a/dali-toolkit/internal/text/line-run.h b/dali-toolkit/internal/text/line-run.h index aedd3f7..fd5371d 100644 --- a/dali-toolkit/internal/text/line-run.h +++ b/dali-toolkit/internal/text/line-run.h @@ -42,6 +42,7 @@ struct LineRun Length numberOfGlyphs; ///< The number of glyphs of the run. CharacterRun characterRun; ///< The initial character and the number of characters. Size lineSize; ///< The size of the line. + float extraLength; ///< The length of the white spaces at the end of the line. }; } // namespace Text diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index ea33695..74ab9ae 100644 --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -630,6 +630,7 @@ Vector3 Controller::GetNaturalSize() // Operations that need to be done if the size changes. const OperationsMask sizeOperations = static_cast( LAYOUT | + ALIGN | REORDER ); DoRelayout( Size( MAX_FLOAT, MAX_FLOAT ), @@ -679,6 +680,7 @@ float Controller::GetHeightForWidth( float width ) // Operations that need to be done if the size changes. const OperationsMask sizeOperations = static_cast( LAYOUT | + ALIGN | REORDER ); DoRelayout( Size( width, MAX_FLOAT ), @@ -720,6 +722,7 @@ bool Controller::Relayout( const Vector2& size ) // Operations that need to be done if the size changes. mImpl->mOperationsPending = static_cast( mImpl->mOperationsPending | LAYOUT | + ALIGN | UPDATE_ACTUAL_SIZE | REORDER ); @@ -777,12 +780,22 @@ void Controller::ProcessModifyEvents() 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->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& utf32Characters = mImpl->mLogicalModel->mText; @@ -809,7 +822,8 @@ void Controller::ReplaceTextEvent( const std::string& text ) // Apply modifications to the model mImpl->mOperationsPending = ALL_OPERATIONS; UpdateModel( ALL_OPERATIONS ); - mImpl->mOperationsPending = static_cast( LAYOUT | + mImpl->mOperationsPending = static_cast( LAYOUT | + ALIGN | UPDATE_ACTUAL_SIZE | REORDER ); } @@ -860,7 +874,8 @@ void Controller::InsertTextEvent( const std::string& text ) // Apply modifications to the model; TODO - Optimize this mImpl->mOperationsPending = ALL_OPERATIONS; UpdateModel( ALL_OPERATIONS ); - mImpl->mOperationsPending = static_cast( LAYOUT | + mImpl->mOperationsPending = static_cast( LAYOUT | + ALIGN | UPDATE_ACTUAL_SIZE | REORDER ); } @@ -896,7 +911,8 @@ void Controller::DeleteTextEvent() // Apply modifications to the model; TODO - Optimize this mImpl->mOperationsPending = ALL_OPERATIONS; UpdateModel( ALL_OPERATIONS ); - mImpl->mOperationsPending = static_cast( LAYOUT | + mImpl->mOperationsPending = static_cast( LAYOUT | + ALIGN | UPDATE_ACTUAL_SIZE | REORDER ); } @@ -1052,7 +1068,6 @@ bool Controller::DoRelayout( const Vector2& size, // after the first time the text has been laid out. // Fill the vectors again. - const Length numberOfCharacters = mImpl->mLogicalModel->GetNumberOfCharacters(); Length numberOfGlyphs = mImpl->mVisualModel->GetNumberOfGlyphs(); Vector& lineBreakInfo = mImpl->mLogicalModel->mLineBreakInfo; @@ -1063,6 +1078,7 @@ bool Controller::DoRelayout( const Vector2& size, // Set the layout parameters. LayoutParameters layoutParameters( size, + mImpl->mLogicalModel->mText.Begin(), lineBreakInfo.Begin(), wordBreakInfo.Begin(), numberOfGlyphs, @@ -1076,18 +1092,16 @@ bool Controller::DoRelayout( const Vector2& size, // some re-allocations. Vector& lines = mImpl->mVisualModel->mLines; + // Delete any previous laid out lines before setting the new ones. + lines.Clear(); + + // The capacity of the bidirectional paragraph info is the number of paragraphs. + lines.Reserve( mImpl->mLogicalModel->mBidirectionalParagraphInfo.Capacity() ); + // Resize the vector of positions to have the same size than the vector of glyphs. Vector& glyphPositions = mImpl->mVisualModel->mGlyphPositions; glyphPositions.Resize( numberOfGlyphs ); - BidirectionalRunIndex firstBidiRunIndex = 0u; - Length numberOfBidiRuns = 0u; - mImpl->mLogicalModel->GetNumberOfBidirectionalInfoRuns( 0u, numberOfCharacters, firstBidiRunIndex, numberOfBidiRuns ); - - // Delete any previous laid out lines before setting the new ones. - lines.Clear(); - lines.Reserve( numberOfBidiRuns ); - // Update the visual model. viewUpdated = mImpl->mLayoutEngine.LayoutText( layoutParameters, glyphPositions, @@ -1144,6 +1158,13 @@ bool Controller::DoRelayout( const Vector2& size, free( bidiLineInfo.visualToLogicalMap ); } } + } // REORDER + + if( ALIGN & operations ) + { + mImpl->mLayoutEngine.Align( layoutParameters, + lines, + glyphPositions ); } // Sets the actual size. @@ -1151,7 +1172,7 @@ bool Controller::DoRelayout( const Vector2& size, { mImpl->mVisualModel->SetActualSize( layoutSize ); } - } + } // view updated } else { diff --git a/dali-toolkit/internal/text/text-controller.h b/dali-toolkit/internal/text/text-controller.h index 82672e6..e1d831e 100644 --- a/dali-toolkit/internal/text/text-controller.h +++ b/dali-toolkit/internal/text/text-controller.h @@ -78,8 +78,7 @@ private: LAYOUT = 0x0100, UPDATE_ACTUAL_SIZE = 0x0200, REORDER = 0x0400, - ALIGNMENT = 0x0800, - RENDER = 0x1000, + ALIGN = 0x0800, ALL_OPERATIONS = 0xFFFF }; diff --git a/dali-toolkit/public-api/controls/text-controls/text-field.h b/dali-toolkit/public-api/controls/text-controls/text-field.h index 5b35407..3721c4b 100644 --- a/dali-toolkit/public-api/controls/text-controls/text-field.h +++ b/dali-toolkit/public-api/controls/text-controls/text-field.h @@ -69,7 +69,8 @@ public: CURSOR_BLINK_INTERVAL, ///< name "cursor-blink-interval", The time interval between cursor on/off states, type FLOAT CURSOR_BLINK_DURATION, ///< name "cursor-blink-duration", The cursor will stop blinking after this duration (if non-zero), type FLOAT GRAB_HANDLE_IMAGE, ///< name "grab-handle-image", The image to display for grab handle, type STRING - DECORATION_BOUNDING_BOX ///< name "decoration-bounding-box", The decorations (handles etc) will positioned within this area on-screen, type RECTANGLE + DECORATION_BOUNDING_BOX, ///< name "decoration-bounding-box", The decorations (handles etc) will positioned within this area on-screen, type RECTANGLE + ALIGNMENT, ///< name "alignment", The line alignment, type STRING, values "BEGIN", "CENTER", "END" }; }; diff --git a/dali-toolkit/public-api/controls/text-controls/text-label.h b/dali-toolkit/public-api/controls/text-controls/text-label.h index e36b44a..fdb9ec7 100644 --- a/dali-toolkit/public-api/controls/text-controls/text-label.h +++ b/dali-toolkit/public-api/controls/text-controls/text-label.h @@ -63,6 +63,7 @@ public: FONT_STYLE, ///< name "font-style", The requested font style e.g. Regular/Italic, type STRING POINT_SIZE, ///< name "point-size", The size of font in points, type FLOAT MULTI_LINE, ///< name "multi-line", The single-line or multi-line layout option, type BOOLEAN + ALIGNMENT, ///< name "alignment", The line alignment, type STRING, values "BEGIN", "CENTER", "END" }; };