From: Adeel Kazmi Date: Thu, 4 Jan 2018 17:33:31 +0000 (+0000) Subject: Merge "Fix text scrolling bug" into devel/master X-Git-Tag: dali_1.3.6~2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=f6d6e9bb02a6d7b0d8b16c9af2eb5de32b383065;hp=d319327a918acb5e8e662ec13e70777f3d4e7396 Merge "Fix text scrolling bug" into devel/master --- diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Typesetter.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Typesetter.cpp index 14f352c..44136a7 100644 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Typesetter.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Typesetter.cpp @@ -27,6 +27,7 @@ #include #include #include +#include using namespace Dali; using namespace Toolkit; @@ -108,7 +109,7 @@ int UtcDaliTextRenderingControllerRender(void) DALI_TEST_CHECK( renderingController ); // Renders the text and creates the final bitmap. - PixelData bitmap = renderingController->Render( relayoutSize ); + PixelData bitmap = renderingController->Render( relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT ); DALI_TEST_CHECK( bitmap ); DALI_TEST_EQUALS( 120u, bitmap.GetWidth(), TEST_LOCATION ); @@ -120,7 +121,7 @@ int UtcDaliTextRenderingControllerRender(void) controller->Relayout( relayoutSize ); // Renders the text and creates the final bitmap. - bitmap = renderingController->Render( relayoutSize ); + bitmap = renderingController->Render( relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT ); DALI_TEST_CHECK( bitmap ); DALI_TEST_EQUALS( 120u, bitmap.GetWidth(), TEST_LOCATION ); @@ -131,7 +132,7 @@ int UtcDaliTextRenderingControllerRender(void) controller->Relayout( relayoutSize ); // Renders the text and creates the final bitmap. - bitmap = renderingController->Render( relayoutSize ); + bitmap = renderingController->Render( relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT ); DALI_TEST_CHECK( bitmap ); DALI_TEST_EQUALS( 120u, bitmap.GetWidth(), TEST_LOCATION ); @@ -166,32 +167,32 @@ int UtcDaliTextTypesetterVerticalLineAlignment(void) DALI_TEST_CHECK( renderingController ); { - controller->SetVerticalLineAlignment(Dali::Toolkit::DevelText::VerticalLineAlignment::TOP); - controller->Relayout(relayoutSize); + controller->SetVerticalLineAlignment( Dali::Toolkit::DevelText::VerticalLineAlignment::TOP ); + controller->Relayout( relayoutSize ); // Renders the text and creates the final bitmap. - auto bitmap = renderingController->Render(relayoutSize); + auto bitmap = renderingController->Render( relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT ); DALI_TEST_EQUALS( 60u, bitmap.GetHeight(), TEST_LOCATION ); } { - controller->SetVerticalLineAlignment(Dali::Toolkit::DevelText::VerticalLineAlignment::MIDDLE); - controller->Relayout(relayoutSize); + controller->SetVerticalLineAlignment( Dali::Toolkit::DevelText::VerticalLineAlignment::MIDDLE ); + controller->Relayout( relayoutSize ); // Renders the text and creates the final bitmap. - auto bitmap = renderingController->Render(relayoutSize); + auto bitmap = renderingController->Render( relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT ); DALI_TEST_EQUALS( 60u, bitmap.GetHeight(), TEST_LOCATION ); } { - controller->SetVerticalLineAlignment(Dali::Toolkit::DevelText::VerticalLineAlignment::BOTTOM); - controller->Relayout(relayoutSize); + controller->SetVerticalLineAlignment( Dali::Toolkit::DevelText::VerticalLineAlignment::BOTTOM ); + controller->Relayout( relayoutSize ); // Renders the text and creates the final bitmap. - auto bitmap = renderingController->Render(relayoutSize); + auto bitmap = renderingController->Render( relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT ); DALI_TEST_EQUALS( 60u, bitmap.GetHeight(), TEST_LOCATION ); } tet_result(TET_PASS); END_TEST; -} \ No newline at end of file +} diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp index cf36a87..825e7d4 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp @@ -1234,11 +1234,21 @@ int UtcDaliToolkitTextlabelTextDirection(void) label.SetProperty( TextLabel::Property::POINT_SIZE, 20 ); Stage::GetCurrent().Add( label ); + // Test LTR text DALI_TEST_EQUALS( label.GetProperty< int >( DevelTextLabel::Property::TEXT_DIRECTION ), static_cast< int >( Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT ), TEST_LOCATION ); + // Test RTL text label.SetProperty( TextLabel::Property::TEXT, "ﻡﺮﺤﺑﺍ ﺏﺎﻠﻋﺎﻠﻣ ﻡﺮﺤﺑﺍ" ); DALI_TEST_EQUALS( label.GetProperty< int >( DevelTextLabel::Property::TEXT_DIRECTION ), static_cast< int >( Toolkit::DevelText::TextDirection::RIGHT_TO_LEFT ), TEST_LOCATION ); + // Test RTL text starting with weak character + label.SetProperty( TextLabel::Property::TEXT, "()ﻡﺮﺤﺑﺍ ﺏﺎﻠﻋﺎﻠﻣ ﻡﺮﺤﺑﺍ" ); + DALI_TEST_EQUALS( label.GetProperty< int >( DevelTextLabel::Property::TEXT_DIRECTION ), static_cast< int >( Toolkit::DevelText::TextDirection::RIGHT_TO_LEFT ), TEST_LOCATION ); + + // Test RTL text string with emoji and weak character + label.SetProperty( TextLabel::Property::TEXT, "\xF0\x9F\x98\x81 () ﻡﺮﺤﺑﺍ ﺏﺎﻠﻋﺎﻠﻣ ﻡﺮﺤﺑﺍ" ); + DALI_TEST_EQUALS( label.GetProperty< int >( DevelTextLabel::Property::TEXT_DIRECTION ), static_cast< int >( Toolkit::DevelText::TextDirection::RIGHT_TO_LEFT ), TEST_LOCATION ); + END_TEST; } 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 3f420b5..5eece25 100644 --- a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp @@ -60,6 +60,19 @@ namespace Internal namespace { const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND; + + /** + * @brief How the text visual should be aligned vertically inside the control. + * + * 0.0f aligns the text to the top, 0.5f aligns the text to the center, 1.0f aligns the text to the bottom. + * The alignment depends on the alignment value of the text label (Use Text::VerticalAlignment enumerations). + */ + const float VERTICAL_ALIGNMENT_TABLE[ Text::VerticalAlignment::BOTTOM + 1 ] = + { + 0.0f, // VerticalAlignment::TOP + 0.5f, // VerticalAlignment::CENTER + 1.0f // VerticalAlignment::BOTTOM + }; } namespace @@ -940,10 +953,29 @@ void TextLabel::OnRelayout( const Vector2& size, RelayoutContainer& container ) std::swap( padding.start, padding.end ); } + // Calculate the size of the visual that can fit the text + Size layoutSize = mController->GetTextModel()->GetLayoutSize(); + layoutSize.x = contentSize.x; + + const Vector2& shadowOffset = mController->GetTextModel()->GetShadowOffset(); + if ( shadowOffset.y > Math::MACHINE_EPSILON_1 ) + { + layoutSize.y += shadowOffset.y; + } + + float outlineWidth = mController->GetTextModel()->GetOutlineWidth(); + layoutSize.y += outlineWidth * 2.0f; + layoutSize.y = std::min( layoutSize.y, contentSize.y ); + + // Calculate the offset for vertical alignment only, as the layout engine will do the horizontal alignment. + Vector2 alignmentOffset; + alignmentOffset.x = 0.0f; + alignmentOffset.y = ( contentSize.y - layoutSize.y ) * VERTICAL_ALIGNMENT_TABLE[mController->GetVerticalAlignment()]; + Property::Map visualTransform; - visualTransform.Add( Toolkit::Visual::Transform::Property::SIZE, contentSize ) + visualTransform.Add( Toolkit::Visual::Transform::Property::SIZE, layoutSize ) .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) ) - .Add( Toolkit::Visual::Transform::Property::OFFSET, Vector2( padding.start, padding.top ) ) + .Add( Toolkit::Visual::Transform::Property::OFFSET, Vector2( padding.start, padding.top ) + alignmentOffset ) .Add( Toolkit::Visual::Transform::Property::OFFSET_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) ) .Add( Toolkit::Visual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN ) .Add( Toolkit::Visual::Transform::Property::ANCHOR_POINT, Toolkit::Align::TOP_BEGIN ); @@ -1003,7 +1035,7 @@ void TextLabel::SetUpAutoScrolling() Text::TypesetterPtr typesetter = Text::Typesetter::New( mController->GetTextModel() ); - PixelData data = typesetter->Render( verifiedSize, Text::Typesetter::RENDER_TEXT_AND_STYLES, true, Pixel::RGBA8888 ); // ignore the horizontal alignment + PixelData data = typesetter->Render( verifiedSize, mController->GetTextDirection(), Text::Typesetter::RENDER_TEXT_AND_STYLES, true, Pixel::RGBA8888 ); // ignore the horizontal alignment Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D, data.GetPixelFormat(), data.GetWidth(), diff --git a/dali-toolkit/internal/text/rendering/text-typesetter.cpp b/dali-toolkit/internal/text/rendering/text-typesetter.cpp index 314bc63..901c477 100755 --- a/dali-toolkit/internal/text/rendering/text-typesetter.cpp +++ b/dali-toolkit/internal/text/rendering/text-typesetter.cpp @@ -267,7 +267,7 @@ ViewModel* Typesetter::GetViewModel() return mModel; } -PixelData Typesetter::Render( const Vector2& size, RenderBehaviour behaviour, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat ) +PixelData Typesetter::Render( const Vector2& size, Toolkit::DevelText::TextDirection::Type textDirection, RenderBehaviour behaviour, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat ) { // @todo. This initial implementation for a TextLabel has only one visible page. @@ -277,8 +277,32 @@ PixelData Typesetter::Render( const Vector2& size, RenderBehaviour behaviour, bo // Retrieves the layout size. const Size& layoutSize = mModel->GetLayoutSize(); + const float outlineWidth = mModel->GetOutlineWidth(); + + // Set the offset for the horizontal alignment according to the text direction and outline width. + int penX = 0; + + switch( mModel->GetHorizontalAlignment() ) + { + case HorizontalAlignment::BEGIN: + { + // No offset to add. + break; + } + case HorizontalAlignment::CENTER: + { + penX += ( textDirection == Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT ) ? -outlineWidth : outlineWidth; + break; + } + case HorizontalAlignment::END: + { + penX += ( textDirection == Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT ) ? -outlineWidth * 2.0f : outlineWidth * 2.0f; + break; + } + } + // Set the offset for the vertical alignment. - int penY = 0u; + int penY = 0; switch( mModel->GetVerticalAlignment() ) { @@ -340,7 +364,7 @@ PixelData Typesetter::Render( const Vector2& size, RenderBehaviour behaviour, bo if( RENDER_MASK == behaviour ) { // Generate the image buffer as an alpha mask for color glyphs. - imageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_MASK, ignoreHorizontalAlignment, pixelFormat, penY, 0u, numberOfGlyphs - 1 ); + imageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_MASK, ignoreHorizontalAlignment, pixelFormat, penX, penY, 0u, numberOfGlyphs - 1 ); } else if( RENDER_NO_TEXT == behaviour ) { @@ -351,7 +375,7 @@ PixelData Typesetter::Render( const Vector2& size, RenderBehaviour behaviour, bo else { // Generate the image buffer for the text with no style. - imageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_NONE, ignoreHorizontalAlignment, pixelFormat, penY, 0u, numberOfGlyphs -1 ); + imageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_NONE, ignoreHorizontalAlignment, pixelFormat, penX, penY, 0u, numberOfGlyphs -1 ); } if ( ( RENDER_NO_STYLES != behaviour ) && ( RENDER_MASK != behaviour ) ) @@ -362,7 +386,7 @@ PixelData Typesetter::Render( const Vector2& size, RenderBehaviour behaviour, bo if ( outlineWidth > Math::MACHINE_EPSILON_1 ) { // Create the image buffer for outline - Devel::PixelBuffer outlineImageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_OUTLINE, ignoreHorizontalAlignment, pixelFormat, penY, 0u, numberOfGlyphs -1 ); + Devel::PixelBuffer outlineImageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_OUTLINE, ignoreHorizontalAlignment, pixelFormat, penX, penY, 0u, numberOfGlyphs -1 ); // Combine the two buffers imageBuffer = CombineImageBuffer( imageBuffer, outlineImageBuffer, bufferWidth, bufferHeight ); @@ -375,7 +399,7 @@ PixelData Typesetter::Render( const Vector2& size, RenderBehaviour behaviour, bo if ( fabsf( shadowOffset.x ) > Math::MACHINE_EPSILON_1 || fabsf( shadowOffset.y ) > Math::MACHINE_EPSILON_1 ) { // Create the image buffer for shadow - Devel::PixelBuffer shadowImageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_SHADOW, ignoreHorizontalAlignment, pixelFormat, penY, 0u, numberOfGlyphs - 1 ); + Devel::PixelBuffer shadowImageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_SHADOW, ignoreHorizontalAlignment, pixelFormat, penX, penY, 0u, numberOfGlyphs - 1 ); // Check whether it will be a soft shadow const float& blurRadius = mModel->GetShadowBlurRadius(); @@ -394,7 +418,7 @@ PixelData Typesetter::Render( const Vector2& size, RenderBehaviour behaviour, bo if ( underlineEnabled ) { // Create the image buffer for underline - Devel::PixelBuffer underlineImageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_UNDERLINE, ignoreHorizontalAlignment, pixelFormat, penY, 0u, numberOfGlyphs - 1 ); + Devel::PixelBuffer underlineImageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_UNDERLINE, ignoreHorizontalAlignment, pixelFormat, penX, penY, 0u, numberOfGlyphs - 1 ); // Combine the two buffers imageBuffer = CombineImageBuffer( imageBuffer, underlineImageBuffer, bufferWidth, bufferHeight ); @@ -407,7 +431,7 @@ PixelData Typesetter::Render( const Vector2& size, RenderBehaviour behaviour, bo return pixelData; } -Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth, const unsigned int bufferHeight, Typesetter::Style style, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat, int verticalOffset, GlyphIndex fromGlyphIndex, GlyphIndex toGlyphIndex ) +Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth, const unsigned int bufferHeight, Typesetter::Style style, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat, int horizontalOffset, int verticalOffset, GlyphIndex fromGlyphIndex, GlyphIndex toGlyphIndex ) { // Retrieve lines, glyphs, positions and colors from the view model. const Length modelNumberOfLines = mModel->GetNumberOfLines(); @@ -451,6 +475,7 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth // Sets the horizontal offset of the line. glyphData.horizontalOffset = ignoreHorizontalAlignment ? 0 : static_cast( line.alignmentOffset ); + glyphData.horizontalOffset += horizontalOffset; // Increases the vertical offset with the line's ascender. glyphData.verticalOffset += static_cast( line.ascender ); diff --git a/dali-toolkit/internal/text/rendering/text-typesetter.h b/dali-toolkit/internal/text/rendering/text-typesetter.h index 285348e..453541b 100644 --- a/dali-toolkit/internal/text/rendering/text-typesetter.h +++ b/dali-toolkit/internal/text/rendering/text-typesetter.h @@ -25,6 +25,7 @@ #include #include #include +#include namespace Dali { @@ -102,13 +103,14 @@ public: * - Combines different image buffers to create the pixel data used to generate the final image * * @param[in] size The renderer size. + * @param[in] textDirection The direction of the text. * @param[in] behaviour The behaviour of how to render the text (i.e. whether to render the text only or the styles only or both). * @param[in] ignoreHorizontalAlignment Whether to ignore the horizontal alignment (i.e. always render as if HORIZONTAL_ALIGN_BEGIN). * @param[in] pixelFormat The format of the pixel in the image that the text is rendered as (i.e. either Pixel::BGRA8888 or Pixel::L8). * * @return A pixel data with the text rendered. */ - PixelData Render( const Vector2& size, RenderBehaviour behaviour = RENDER_TEXT_AND_STYLES, bool ignoreHorizontalAlignment = false, Pixel::Format pixelFormat = Pixel::RGBA8888 ); + PixelData Render( const Vector2& size, Toolkit::DevelText::TextDirection::Type textDirection, RenderBehaviour behaviour = RENDER_TEXT_AND_STYLES, bool ignoreHorizontalAlignment = false, Pixel::Format pixelFormat = Pixel::RGBA8888 ); private: /** @@ -137,13 +139,14 @@ private: * @param[in] style The style of the text. * @param[in] ignoreHorizontalAlignment Whether to ignore the horizontal alignment, not ignored by default. * @param[in] pixelFormat The format of the pixel in the image that the text is rendered as (i.e. either Pixel::BGRA8888 or Pixel::L8). + * @param[in] horizontalOffset The horizontal offset to be added to the glyph's position. * @param[in] verticalOffset The vertical offset to be added to the glyph's position. * @param[in] fromGlyphIndex The index of the first glyph within the text to be drawn * @param[in] toGlyphIndex The index of the last glyph within the text to be drawn * * @return An image buffer with the text. */ - Devel::PixelBuffer CreateImageBuffer( const unsigned int bufferWidth, const unsigned int bufferHeight, Typesetter::Style style, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat, int verticalOffset, TextAbstraction::GlyphIndex fromGlyphIndex, TextAbstraction::GlyphIndex toGlyphIndex ); + Devel::PixelBuffer CreateImageBuffer( const unsigned int bufferWidth, const unsigned int bufferHeight, Typesetter::Style style, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat, int horizontalOffset, int verticalOffset, TextAbstraction::GlyphIndex fromGlyphIndex, TextAbstraction::GlyphIndex toGlyphIndex ); /** * @brief Combine the two RGBA image buffers together. diff --git a/dali-toolkit/internal/text/text-controller-impl.h b/dali-toolkit/internal/text/text-controller-impl.h index 47c9bc0..f07e955 100644 --- a/dali-toolkit/internal/text/text-controller-impl.h +++ b/dali-toolkit/internal/text/text-controller-impl.h @@ -323,7 +323,8 @@ struct Controller::Impl mMarkupProcessorEnabled( false ), mClipboardHideEnabled( true ), mIsAutoScrollEnabled( false ), - mAutoScrollDirectionRTL( false ), + mUpdateTextDirection( true ), + mIsTextDirectionRTL( false ), mUnderlineSetByString( false ), mShadowSetByString( false ), mOutlineSetByString( false ), @@ -744,7 +745,8 @@ public: bool mMarkupProcessorEnabled:1; ///< Whether the mark-up procesor is enabled. bool mClipboardHideEnabled:1; ///< Whether the ClipboardHide function work or not bool mIsAutoScrollEnabled:1; ///< Whether auto text scrolling is enabled. - CharacterDirection mAutoScrollDirectionRTL:1; ///< Direction of auto scrolling, true if rtl + bool mUpdateTextDirection:1; ///< Whether the text direction needs to be updated. + CharacterDirection mIsTextDirectionRTL:1; ///< Whether the text direction is right to left or not bool mUnderlineSetByString:1; ///< Set when underline is set by string (legacy) instead of map bool mShadowSetByString:1; ///< Set when shadow is set by string (legacy) instead of map diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index d454031..c618006 100755 --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -222,7 +222,7 @@ bool Controller::IsAutoScrollEnabled() const CharacterDirection Controller::GetAutoScrollDirection() const { - return mImpl->mAutoScrollDirectionRTL; + return mImpl->mIsTextDirectionRTL; } float Controller::GetAutoScrollLineAlignment() const @@ -554,6 +554,9 @@ void Controller::SetText( const std::string& text ) // The natural size needs to be re-calculated. mImpl->mRecalculateNaturalSize = true; + // The text direction needs to be updated. + mImpl->mUpdateTextDirection = true; + // Apply modifications to the model mImpl->mOperationsPending = ALL_OPERATIONS; } @@ -2120,20 +2123,39 @@ void Controller::GetPlaceholderProperty( Property::Map& map ) Toolkit::DevelText::TextDirection::Type Controller::GetTextDirection() { - if( ( 0u == mImpl->mModel->mLogicalModel->mText.Count() ) ) + // Make sure the model is up-to-date before layouting + ProcessModifyEvents(); + + if ( mImpl->mUpdateTextDirection ) { - return Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT; - } + // Operations that can be done only once until the text changes. + const OperationsMask onlyOnceOperations = static_cast( GET_SCRIPTS | + VALIDATE_FONTS | + GET_LINE_BREAKS | + GET_WORD_BREAKS | + BIDI_INFO | + SHAPE_TEXT ); - const Character character = mImpl->mModel->mLogicalModel->mText[0]; - Script script = TextAbstraction::GetCharacterScript( character ); + // Set the update info to relayout the whole text. + mImpl->mTextUpdateInfo.mParagraphCharacterIndex = 0u; + mImpl->mTextUpdateInfo.mRequestedNumberOfCharacters = mImpl->mModel->mLogicalModel->mText.Count(); - if( TextAbstraction::IsRightToLeftScript( script ) ) - { - return Toolkit::DevelText::TextDirection::RIGHT_TO_LEFT; + // Make sure the model is up-to-date before layouting + mImpl->UpdateModel( onlyOnceOperations ); + + Vector3 naturalSize; + DoRelayout( Size( MAX_FLOAT, MAX_FLOAT ), + static_cast( onlyOnceOperations | + LAYOUT | REORDER | UPDATE_DIRECTION ), + naturalSize.GetVectorXY() ); + + // Clear the update info. This info will be set the next time the text is updated. + mImpl->mTextUpdateInfo.Clear(); + + mImpl->mUpdateTextDirection = false; } - return Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT; + return mImpl->mIsTextDirectionRTL ? Toolkit::DevelText::TextDirection::RIGHT_TO_LEFT : Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT; } Toolkit::DevelText::VerticalLineAlignment::Type Controller::GetVerticalLineAlignment() const @@ -3422,7 +3444,8 @@ bool Controller::DoRelayout( const Size& size, const float outlineWidth = static_cast( mImpl->mModel->GetOutlineWidth() ); // Set the layout parameters. - Layout::Parameters layoutParameters( size, + const Vector2 sizeOffset = Vector2(outlineWidth * 2.0f, outlineWidth * 2.0f); // The outline should be fit into the bounding box + Layout::Parameters layoutParameters( size - sizeOffset, textBuffer, lineBreakInfo.Begin(), wordBreakInfo.Begin(), @@ -3489,7 +3512,7 @@ bool Controller::DoRelayout( const Size& size, if( NO_OPERATION != ( UPDATE_DIRECTION & operations ) ) { - mImpl->mAutoScrollDirectionRTL = false; + mImpl->mIsTextDirectionRTL = false; } // Reorder the lines @@ -3527,7 +3550,7 @@ bool Controller::DoRelayout( const Size& size, const LineRun* const firstline = mImpl->mModel->mVisualModel->mLines.Begin(); if ( firstline ) { - mImpl->mAutoScrollDirectionRTL = firstline->direction; + mImpl->mIsTextDirectionRTL = firstline->direction; } } } @@ -3560,7 +3583,7 @@ bool Controller::DoRelayout( const Size& size, #if defined(DEBUG_ENABLED) std::string currentText; GetText( currentText ); - DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::DoRelayout [%p] mImpl->mAutoScrollDirectionRTL[%s] [%s]\n", this, (mImpl->mAutoScrollDirectionRTL)?"true":"false", currentText.c_str() ); + DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::DoRelayout [%p] mImpl->mIsTextDirectionRTL[%s] [%s]\n", this, (mImpl->mIsTextDirectionRTL)?"true":"false", currentText.c_str() ); #endif DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--Controller::DoRelayout, view updated %s\n", ( viewUpdated ? "true" : "false" ) ); return viewUpdated; @@ -3655,6 +3678,9 @@ void Controller::TextReplacedEvent() // The natural size needs to be re-calculated. mImpl->mRecalculateNaturalSize = true; + // The text direction needs to be updated. + mImpl->mUpdateTextDirection = true; + // Apply modifications to the model mImpl->mOperationsPending = ALL_OPERATIONS; } @@ -3673,6 +3699,9 @@ void Controller::TextInsertedEvent() // The natural size needs to be re-calculated. mImpl->mRecalculateNaturalSize = true; + // The text direction needs to be updated. + mImpl->mUpdateTextDirection = true; + // Apply modifications to the model; TODO - Optimize this mImpl->mOperationsPending = ALL_OPERATIONS; } @@ -3691,6 +3720,9 @@ void Controller::TextDeletedEvent() // The natural size needs to be re-calculated. mImpl->mRecalculateNaturalSize = true; + // The text direction needs to be updated. + mImpl->mUpdateTextDirection = true; + // Apply modifications to the model; TODO - Optimize this mImpl->mOperationsPending = ALL_OPERATIONS; } @@ -3792,6 +3824,9 @@ void Controller::ResetText() // The natural size needs to be re-calculated. mImpl->mRecalculateNaturalSize = true; + // The text direction needs to be updated. + mImpl->mUpdateTextDirection = true; + // Apply modifications to the model mImpl->mOperationsPending = ALL_OPERATIONS; } @@ -3858,6 +3893,9 @@ void Controller::ShowPlaceholderText() // The natural size needs to be re-calculated. mImpl->mRecalculateNaturalSize = true; + // The text direction needs to be updated. + mImpl->mUpdateTextDirection = true; + // Apply modifications to the model mImpl->mOperationsPending = ALL_OPERATIONS; diff --git a/dali-toolkit/internal/visuals/animated-image/rolling-gif-image-cache.h b/dali-toolkit/internal/visuals/animated-image/rolling-gif-image-cache.h index 778eeda..d912ab3 100644 --- a/dali-toolkit/internal/visuals/animated-image/rolling-gif-image-cache.h +++ b/dali-toolkit/internal/visuals/animated-image/rolling-gif-image-cache.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_INTERNAL_ROLLING_GIF_IMAGE_CACHE_H /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -105,7 +105,7 @@ private: */ struct ImageFrame { - unsigned int mFrameNumber; + unsigned int mFrameNumber = 0u; }; GifLoading& mGifLoading; diff --git a/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.h b/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.h index 06240c6..b1fcce3 100644 --- a/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.h +++ b/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_INTERNAL_ROLLING_IMAGE_CACHE_H /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -119,8 +119,8 @@ private: */ struct ImageFrame { - unsigned int mUrlIndex; - bool mReady; + unsigned int mUrlIndex = 0u; + bool mReady = false; }; std::vector& mImageUrls; diff --git a/dali-toolkit/internal/visuals/text/text-visual.cpp b/dali-toolkit/internal/visuals/text/text-visual.cpp index e44b005..e4c62f8 100755 --- a/dali-toolkit/internal/visuals/text/text-visual.cpp +++ b/dali-toolkit/internal/visuals/text/text-visual.cpp @@ -35,6 +35,7 @@ #include #include #include +#include namespace Dali { @@ -697,7 +698,7 @@ void TextVisual::UpdateRenderer() const bool styleEnabled = ( shadowEnabled || underlineEnabled || outlineEnabled ); - TextureSet textureSet = GetTextTexture( relayoutSize, hasMultipleTextColors, containsEmoji, styleEnabled ); + TextureSet textureSet = GetTextTexture( mImpl->mTransform.mSize, hasMultipleTextColors, containsEmoji, styleEnabled ); mImpl->mRenderer.SetTextures( textureSet ); Shader shader = GetTextShader( mFactoryCache, hasMultipleTextColors, containsEmoji, styleEnabled ); @@ -752,8 +753,11 @@ TextureSet TextVisual::GetTextTexture( const Vector2& size, bool hasMultipleText // Create RGBA texture if the text contains emojis or multiple text colors, otherwise L8 texture Pixel::Format textPixelFormat = ( containsEmoji || hasMultipleTextColors ) ? Pixel::RGBA8888 : Pixel::L8; + // Check the text direction + Toolkit::DevelText::TextDirection::Type textDirection = mController->GetTextDirection(); + // Create a texture for the text without any styles - PixelData data = mTypesetter->Render( size, Text::Typesetter::RENDER_NO_STYLES, false, textPixelFormat ); + PixelData data = mTypesetter->Render( size, textDirection, Text::Typesetter::RENDER_NO_STYLES, false, textPixelFormat ); // It may happen the image atlas can't handle a pixel data it exceeds the maximum size. // In that case, create a texture. TODO: should tile the text. @@ -771,7 +775,7 @@ TextureSet TextVisual::GetTextTexture( const Vector2& size, bool hasMultipleText if ( styleEnabled ) { // Create RGBA texture for all the text styles (without the text itself) - PixelData styleData = mTypesetter->Render( size, Text::Typesetter::RENDER_NO_TEXT, false, Pixel::RGBA8888 ); + PixelData styleData = mTypesetter->Render( size, textDirection, Text::Typesetter::RENDER_NO_TEXT, false, Pixel::RGBA8888 ); Texture styleTexture = Texture::New( Dali::TextureType::TEXTURE_2D, styleData.GetPixelFormat(), @@ -787,7 +791,7 @@ TextureSet TextVisual::GetTextTexture( const Vector2& size, bool hasMultipleText if ( containsEmoji && !hasMultipleTextColors ) { // Create a L8 texture as a mask to avoid color glyphs (e.g. emojis) to be affected by text color animation - PixelData maskData = mTypesetter->Render( size, Text::Typesetter::RENDER_MASK, false, Pixel::L8 ); + PixelData maskData = mTypesetter->Render( size, textDirection, Text::Typesetter::RENDER_MASK, false, Pixel::L8 ); Texture maskTexture = Texture::New( Dali::TextureType::TEXTURE_2D, maskData.GetPixelFormat(),