From 41d36118a13932bcf1db39b780ac437fcda8aa08 Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Tue, 26 Nov 2019 16:45:43 +0000 Subject: [PATCH] Multiple text background color support for left-to-right text only in TextField Change-Id: I9beee6072fb72997c94b05b3d1cfebe9ee1217bb --- .../src/dali-toolkit-internal/CMakeLists.txt | 1 + .../utc-Dali-TextField-internal.cpp | 114 +++++++++ .../controls/text-controls/text-field-impl.cpp | 38 ++- .../controls/text-controls/text-field-impl.h | 5 + .../internal/text/decorator/text-decorator.cpp | 2 - dali-toolkit/internal/text/logical-model-impl.cpp | 8 + dali-toolkit/internal/text/logical-model-impl.h | 1 + .../internal/text/rendering/view-model.cpp | 10 + dali-toolkit/internal/text/rendering/view-model.h | 10 + .../internal/text/text-controller-impl.cpp | 254 +++++++++++++++++++-- dali-toolkit/internal/text/text-controller-impl.h | 10 + dali-toolkit/internal/text/text-controller.cpp | 5 + dali-toolkit/internal/text/text-controller.h | 7 + dali-toolkit/internal/text/text-model-interface.h | 14 ++ dali-toolkit/internal/text/text-model.cpp | 10 + dali-toolkit/internal/text/text-model.h | 10 + dali-toolkit/internal/text/text-view-interface.h | 14 ++ dali-toolkit/internal/text/text-view.cpp | 20 ++ dali-toolkit/internal/text/text-view.h | 10 + dali-toolkit/internal/text/visual-model-impl.h | 2 + 20 files changed, 526 insertions(+), 19 deletions(-) create mode 100755 automated-tests/src/dali-toolkit-internal/utc-Dali-TextField-internal.cpp diff --git a/automated-tests/src/dali-toolkit-internal/CMakeLists.txt b/automated-tests/src/dali-toolkit-internal/CMakeLists.txt index 984e177..9954a74 100755 --- a/automated-tests/src/dali-toolkit-internal/CMakeLists.txt +++ b/automated-tests/src/dali-toolkit-internal/CMakeLists.txt @@ -25,6 +25,7 @@ SET(TC_SOURCES utc-Dali-Text-Shaping.cpp utc-Dali-Text-Typesetter.cpp utc-Dali-Text-ViewModel.cpp + utc-Dali-TextField-internal.cpp utc-Dali-TextureManager.cpp utc-Dali-Visuals-internal.cpp utc-Dali-VisualModel.cpp diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-TextField-internal.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-TextField-internal.cpp new file mode 100755 index 0000000..5ac4ab1 --- /dev/null +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-TextField-internal.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2019 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include + +#include +#include + +#include +#include +#include + +using namespace Dali; +using namespace Toolkit; +using namespace Text; + +int UtcDaliTextFieldMultipleBackgroundText(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliTextFieldMultipleBackgroundText" ); + + // Create a text field + TextField textField = TextField::New(); + textField.SetSize( 400.f, 60.f ); + textField.SetParentOrigin( ParentOrigin::TOP_LEFT ); + textField.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + + // Add the text field to the stage + Stage::GetCurrent().Add( textField ); + + application.SendNotification(); + application.Render(); + + Toolkit::Internal::TextField& textFieldImpl = GetImpl( textField ); + ControllerPtr controller = textFieldImpl.GetTextController(); + Controller::Impl& controllerImpl = Controller::Impl::GetImplementation( *controller.Get() ); + + // Add multiple background colors for the text. + ColorRun backgroundColorRun1; + backgroundColorRun1.characterRun.characterIndex = 0u; + backgroundColorRun1.characterRun.numberOfCharacters = 1u; + backgroundColorRun1.color = Color::RED; + controllerImpl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack( backgroundColorRun1 ); + + ColorRun backgroundColorRun2; + backgroundColorRun2.characterRun.characterIndex = 5u; + backgroundColorRun2.characterRun.numberOfCharacters = 8u; + backgroundColorRun2.color = Color::CYAN; + controllerImpl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack( backgroundColorRun2 ); + + ColorRun backgroundColorRun3; + backgroundColorRun3.characterRun.characterIndex = 23u; + backgroundColorRun3.characterRun.numberOfCharacters = 6u; + backgroundColorRun3.color = Color::GREEN; + controllerImpl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack( backgroundColorRun3 ); + + // Check the case where there is only one character in the text + controller->SetText( "S" ); + + application.SendNotification(); + application.Render(); + + // The offscreen root actor should have one child: the renderable. + Actor stencil = textField.GetChildAt( 0u ); + DALI_TEST_CHECK( stencil.GetChildCount() == 1u ); + + // The renderable actor should have two children: the text and the background. + Actor renderableActor = stencil.GetChildAt( 0u ); + DALI_TEST_CHECK( renderableActor.GetChildCount() == 2u ); + + // Check that the background is created + Actor backgroundActor = renderableActor.GetChildAt( 0u ); + DALI_TEST_CHECK( backgroundActor ); + DALI_TEST_CHECK( backgroundActor.GetName() == "TextBackgroundColorActor" ); + + // Change the text to contain more characters + controller->SetText( "Text Multiple Background Test" ); + + application.SendNotification(); + application.Render(); + + // Highlight the whole text + textFieldImpl.SelectWholeText(); + + application.SendNotification(); + application.Render(); + + // Now the offscreen root actor should have three children: the renderable, the highlight, and the background. + DALI_TEST_CHECK( stencil.GetChildCount() == 3u ); + // The renderable actor should have one child only: the text + DALI_TEST_CHECK( renderableActor.GetChildCount() == 1u ); + + // The background should now be lowered below the highlight + backgroundActor = stencil.GetChildAt( 0u ); + DALI_TEST_CHECK( backgroundActor ); + DALI_TEST_CHECK( backgroundActor.GetName() == "TextBackgroundColorActor" ); + + END_TEST; +} 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 0def1bc..6a1f1c9 100755 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp @@ -1463,8 +1463,14 @@ void TextField::RenderText( Text::Controller::UpdateTextType updateTextType ) if( renderableActor != mRenderableActor ) { + UnparentAndReset( mBackgroundActor ); UnparentAndReset( mRenderableActor ); mRenderableActor = renderableActor; + + if ( mRenderableActor ) + { + mBackgroundActor = mController->CreateBackgroundActor(); + } } } @@ -1472,9 +1478,12 @@ void TextField::RenderText( Text::Controller::UpdateTextType updateTextType ) { const Vector2& scrollOffset = mController->GetTextModel()->GetScrollPosition(); + float renderableActorPositionX, renderableActorPositionY; + if( mStencil ) { - mRenderableActor.SetPosition( scrollOffset.x + mAlignmentOffset, scrollOffset.y ); + renderableActorPositionX = scrollOffset.x + mAlignmentOffset; + renderableActorPositionY = scrollOffset.y; } else { @@ -1488,13 +1497,17 @@ void TextField::RenderText( Text::Controller::UpdateTextType updateTextType ) std::swap( padding.start, padding.end ); } - mRenderableActor.SetPosition( scrollOffset.x + mAlignmentOffset + padding.start, scrollOffset.y + padding.top ); + renderableActorPositionX = scrollOffset.x + mAlignmentOffset + padding.start; + renderableActorPositionY = scrollOffset.y + padding.top; } + mRenderableActor.SetPosition( renderableActorPositionX, renderableActorPositionY ); // Make sure the actors are parented correctly with/without clipping Actor self = mStencil ? mStencil : Self(); + Actor highlightActor; + for( std::vector::iterator it = mClippingDecorationActors.begin(), endIt = mClippingDecorationActors.end(); it != endIt; @@ -1502,10 +1515,31 @@ void TextField::RenderText( Text::Controller::UpdateTextType updateTextType ) { self.Add( *it ); it->LowerToBottom(); + + if ( it->GetName() == "HighlightActor" ) + { + highlightActor = *it; + } } mClippingDecorationActors.clear(); self.Add( mRenderableActor ); + + if ( mBackgroundActor ) + { + if ( mDecorator && mDecorator->IsHighlightVisible() ) + { + self.Add( mBackgroundActor ); + mBackgroundActor.SetPosition( renderableActorPositionX, renderableActorPositionY); // In text field's coords. + mBackgroundActor.LowerBelow( highlightActor ); + } + else + { + mRenderableActor.Add( mBackgroundActor ); + mBackgroundActor.SetPosition( 0.0f, 0.0f ); // In renderable actor's coords. + mBackgroundActor.LowerToBottom(); + } + } } } diff --git a/dali-toolkit/internal/controls/text-controls/text-field-impl.h b/dali-toolkit/internal/controls/text-controls/text-field-impl.h index 3b1062e..25bd4bd 100755 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.h @@ -268,6 +268,10 @@ private: // Implementation // Connection needed to re-render text, when a Text Field returns to the stage. void OnStageConnect( Dali::Actor actor ); +public: // For UTC only + + Text::ControllerPtr GetTextController() { return mController; } + private: // Data // Signals @@ -285,6 +289,7 @@ private: // Data Actor mRenderableActor; Actor mActiveLayer; + Actor mBackgroundActor; CallbackBase* mIdleCallback; float mAlignmentOffset; diff --git a/dali-toolkit/internal/text/decorator/text-decorator.cpp b/dali-toolkit/internal/text/decorator/text-decorator.cpp index d0f89d9..0cb8b4c 100644 --- a/dali-toolkit/internal/text/decorator/text-decorator.cpp +++ b/dali-toolkit/internal/text/decorator/text-decorator.cpp @@ -1148,9 +1148,7 @@ struct Decorator::Impl : public ConnectionTracker { mHighlightActor = Actor::New(); -#ifdef DECORATOR_DEBUG mHighlightActor.SetName( "HighlightActor" ); -#endif mHighlightActor.SetParentOrigin( ParentOrigin::TOP_LEFT ); mHighlightActor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); mHighlightActor.SetColor( mHighlightColor ); diff --git a/dali-toolkit/internal/text/logical-model-impl.cpp b/dali-toolkit/internal/text/logical-model-impl.cpp index 66c6d89..3d9440e 100755 --- a/dali-toolkit/internal/text/logical-model-impl.cpp +++ b/dali-toolkit/internal/text/logical-model-impl.cpp @@ -289,6 +289,14 @@ void LogicalModel::UpdateTextStyleRuns( CharacterIndex index, int numberOfCharac mColorRuns, removedColorRuns ); + // Process the background color runs. + Vector removedBackgroundColorRuns; + UpdateCharacterRuns( index, + numberOfCharacters, + totalNumberOfCharacters, + mBackgroundColorRuns, + removedBackgroundColorRuns ); + // Process the font description runs. Vector removedFontDescriptionRuns; UpdateCharacterRuns( index, diff --git a/dali-toolkit/internal/text/logical-model-impl.h b/dali-toolkit/internal/text/logical-model-impl.h index 040444f..3c01dc6 100755 --- a/dali-toolkit/internal/text/logical-model-impl.h +++ b/dali-toolkit/internal/text/logical-model-impl.h @@ -211,6 +211,7 @@ public: Vector mScriptRuns; Vector mFontRuns; Vector mColorRuns; + Vector mBackgroundColorRuns; Vector mFontDescriptionRuns; Vector mLineBreakInfo; Vector mParagraphInfo; diff --git a/dali-toolkit/internal/text/rendering/view-model.cpp b/dali-toolkit/internal/text/rendering/view-model.cpp index 83a518b..c79dbd4 100755 --- a/dali-toolkit/internal/text/rendering/view-model.cpp +++ b/dali-toolkit/internal/text/rendering/view-model.cpp @@ -153,6 +153,16 @@ const ColorIndex* const ViewModel::GetColorIndices() const return mModel->GetColorIndices(); } +const Vector4* const ViewModel::GetBackgroundColors() const +{ + return mModel->GetBackgroundColors(); +} + +const ColorIndex* const ViewModel::GetBackgroundColorIndices() const +{ + return mModel->GetBackgroundColorIndices(); +} + const Vector4& ViewModel::GetDefaultColor() const { return mModel->GetDefaultColor(); diff --git a/dali-toolkit/internal/text/rendering/view-model.h b/dali-toolkit/internal/text/rendering/view-model.h index bc7d45f..fe77f67 100755 --- a/dali-toolkit/internal/text/rendering/view-model.h +++ b/dali-toolkit/internal/text/rendering/view-model.h @@ -139,6 +139,16 @@ public: virtual const ColorIndex* const GetColorIndices() const; /** + * @copydoc ModelInterface::GetBackgroundColors() + */ + virtual const Vector4* const GetBackgroundColors() const; + + /** + * @copydoc ModelInterface::GetBackgroundColorIndices() + */ + virtual const ColorIndex* const GetBackgroundColorIndices() const; + + /** * @copydoc ModelInterface::GetDefaultColor() */ virtual const Vector4& GetDefaultColor() const; diff --git a/dali-toolkit/internal/text/text-controller-impl.cpp b/dali-toolkit/internal/text/text-controller-impl.cpp index 6908f04..fa48e52 100755 --- a/dali-toolkit/internal/text/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/text-controller-impl.cpp @@ -20,10 +20,12 @@ // EXTERNAL INCLUDES #include +#include #include #include // INTERNAL INCLUDES +#include #include #include #include @@ -34,6 +36,8 @@ #include #include +using namespace Dali; + namespace { @@ -56,6 +60,44 @@ const float MAX_FLOAT = std::numeric_limits::max(); const float MIN_FLOAT = std::numeric_limits::min(); const Dali::Toolkit::Text::CharacterDirection LTR = false; ///< Left To Right direction +#define MAKE_SHADER(A)#A + +const char* VERTEX_SHADER_BACKGROUND = MAKE_SHADER( +attribute mediump vec2 aPosition; +attribute mediump vec4 aColor; +varying mediump vec4 vColor; +uniform highp mat4 uMvpMatrix; + +void main() +{ + mediump vec4 position = vec4( aPosition, 0.0, 1.0 ); + gl_Position = uMvpMatrix * position; + vColor = aColor; +} +); + +const char* FRAGMENT_SHADER_BACKGROUND = MAKE_SHADER( +varying mediump vec4 vColor; +uniform lowp vec4 uColor; + +void main() +{ + gl_FragColor = vColor * uColor; +} +); + +struct BackgroundVertex +{ + Vector2 mPosition; ///< Vertex posiiton + Vector4 mColor; ///< Vertex color +}; + +struct BackgroundMesh +{ + Vector< BackgroundVertex > mVertices; ///< container of vertices + Vector< unsigned short > mIndices; ///< container of indices +}; + } // namespace namespace Dali @@ -558,6 +600,7 @@ void Controller::Impl::ClearFullModelData( OperationsMask operations ) if( NO_OPERATION != ( COLOR & operations ) ) { mModel->mVisualModel->mColorIndices.Clear(); + mModel->mVisualModel->mBackgroundColorIndices.Clear(); } } @@ -741,6 +784,13 @@ void Controller::Impl::ClearGlyphModelData( CharacterIndex startIndex, Character mModel->mVisualModel->mColorIndices.Erase( colorIndexBuffer + mTextUpdateInfo.mStartGlyphIndex, colorIndexBuffer + endGlyphIndexPlusOne ); } + + if( 0u != mModel->mVisualModel->mBackgroundColorIndices.Count() ) + { + ColorIndex* backgroundColorIndexBuffer = mModel->mVisualModel->mBackgroundColorIndices.Begin(); + mModel->mVisualModel->mBackgroundColorIndices.Erase( backgroundColorIndexBuffer + mTextUpdateInfo.mStartGlyphIndex, + backgroundColorIndexBuffer + endGlyphIndexPlusOne ); + } } } @@ -1026,21 +1076,6 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired ) updated = true; } - if( NO_OPERATION != ( COLOR & operations ) ) - { - // Set the color runs in glyphs. - SetColorSegmentationInfo( mModel->mLogicalModel->mColorRuns, - mModel->mVisualModel->mCharactersToGlyph, - mModel->mVisualModel->mGlyphsPerCharacter, - startIndex, - mTextUpdateInfo.mStartGlyphIndex, - requestedNumberOfCharacters, - mModel->mVisualModel->mColors, - mModel->mVisualModel->mColorIndices ); - - updated = true; - } - if( ( NULL != mEventData ) && mEventData->mPreEditFlag && ( 0u != mModel->mVisualModel->mCharactersToGlyph.Count() ) ) @@ -1076,6 +1111,32 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired ) } } + if( NO_OPERATION != ( COLOR & operations ) ) + { + // Set the color runs in glyphs. + SetColorSegmentationInfo( mModel->mLogicalModel->mColorRuns, + mModel->mVisualModel->mCharactersToGlyph, + mModel->mVisualModel->mGlyphsPerCharacter, + startIndex, + mTextUpdateInfo.mStartGlyphIndex, + requestedNumberOfCharacters, + mModel->mVisualModel->mColors, + mModel->mVisualModel->mColorIndices ); + + // Set the background color runs in glyphs. + SetColorSegmentationInfo( mModel->mLogicalModel->mBackgroundColorRuns, + mModel->mVisualModel->mCharactersToGlyph, + mModel->mVisualModel->mGlyphsPerCharacter, + startIndex, + mTextUpdateInfo.mStartGlyphIndex, + requestedNumberOfCharacters, + mModel->mVisualModel->mBackgroundColors, + mModel->mVisualModel->mBackgroundColorIndices ); + + updated = true; + } + + // The estimated number of lines. Used to avoid reallocations when layouting. mTextUpdateInfo.mEstimatedNumberOfLines = std::max( mModel->mVisualModel->mLines.Count(), mModel->mLogicalModel->mParagraphInfo.Count() ); @@ -3062,6 +3123,169 @@ void Controller::Impl::RequestRelayout() } } +Actor Controller::Impl::CreateBackgroundActor() +{ + // NOTE: Currently we only support background color for one line left-to-right text, + // so the following calculation is based on one line left-to-right text only! + + Actor actor; + + Length numberOfGlyphs = mView.GetNumberOfGlyphs(); + if( numberOfGlyphs > 0u ) + { + Vector glyphs; + glyphs.Resize( numberOfGlyphs ); + + Vector positions; + positions.Resize( numberOfGlyphs ); + + // Get the line where the glyphs are laid-out. + const LineRun* lineRun = mModel->mVisualModel->mLines.Begin(); + float alignmentOffset = lineRun->alignmentOffset; + numberOfGlyphs = mView.GetGlyphs( glyphs.Begin(), + positions.Begin(), + alignmentOffset, + 0u, + numberOfGlyphs ); + + glyphs.Resize( numberOfGlyphs ); + positions.Resize( numberOfGlyphs ); + + const GlyphInfo* const glyphsBuffer = glyphs.Begin(); + const Vector2* const positionsBuffer = positions.Begin(); + + BackgroundMesh mesh; + mesh.mVertices.Reserve( 4u * glyphs.Size() ); + mesh.mIndices.Reserve( 6u * glyphs.Size() ); + + const Vector2 textSize = mView.GetLayoutSize(); + + const float offsetX = textSize.width * 0.5f; + const float offsetY = textSize.height * 0.5f; + + const Vector4* const backgroundColorsBuffer = mView.GetBackgroundColors(); + const ColorIndex* const backgroundColorIndicesBuffer = mView.GetBackgroundColorIndices(); + + Vector4 quad; + uint32_t numberOfQuads = 0u; + + for( uint32_t i = 0, glyphSize = glyphs.Size(); i < glyphSize; ++i ) + { + const GlyphInfo& glyph = *( glyphsBuffer + i ); + + // Get the background color of the character. + // The color index zero is reserved for the default background color (i.e. Color::TRANSPARENT) + const ColorIndex backgroundColorIndex = ( nullptr == backgroundColorsBuffer ) ? 0u : *( backgroundColorIndicesBuffer + i ); + const Vector4& backgroundColor = ( 0u == backgroundColorIndex ) ? Color::TRANSPARENT : *( backgroundColorsBuffer + backgroundColorIndex - 1u ); + + // Only create quads for glyphs with a background color + if ( backgroundColor != Color::TRANSPARENT ) + { + const Vector2 position = *( positionsBuffer + i ); + + if ( i == 0u && glyphSize == 1u ) // Only one glyph in the whole text + { + quad.x = position.x; + quad.y = 0.0f; + quad.z = quad.x + std::max( glyph.advance, glyph.xBearing + glyph.width ); + quad.w = textSize.height; + } + else if ( i == 0u ) // The first glyph in the whole text + { + quad.x = position.x; + quad.y = 0.0f; + quad.z = quad.x - glyph.xBearing + glyph.advance; + quad.w = textSize.height; + } + else if ( i == glyphSize - 1u ) // The last glyph in the whole text + { + quad.x = position.x - glyph.xBearing; + quad.y = 0.0f; + quad.z = quad.x + std::max( glyph.advance, glyph.xBearing + glyph.width ); + quad.w = textSize.height; + } + else // The glyph in the middle of the text + { + quad.x = position.x - glyph.xBearing; + quad.y = 0.0f; + quad.z = quad.x + glyph.advance; + quad.w = textSize.height; + } + + BackgroundVertex vertex; + + // Top left + vertex.mPosition.x = quad.x - offsetX; + vertex.mPosition.y = quad.y - offsetY; + vertex.mColor = backgroundColor; + mesh.mVertices.PushBack( vertex ); + + // Top right + vertex.mPosition.x = quad.z - offsetX; + vertex.mPosition.y = quad.y - offsetY; + vertex.mColor = backgroundColor; + mesh.mVertices.PushBack( vertex ); + + // Bottom left + vertex.mPosition.x = quad.x - offsetX; + vertex.mPosition.y = quad.w - offsetY; + vertex.mColor = backgroundColor; + mesh.mVertices.PushBack( vertex ); + + // Bottom right + vertex.mPosition.x = quad.z - offsetX; + vertex.mPosition.y = quad.w - offsetY; + vertex.mColor = backgroundColor; + mesh.mVertices.PushBack( vertex ); + + // Six indices in counter clockwise winding + mesh.mIndices.PushBack( 1u + 4 * numberOfQuads ); + mesh.mIndices.PushBack( 0u + 4 * numberOfQuads ); + mesh.mIndices.PushBack( 2u + 4 * numberOfQuads ); + mesh.mIndices.PushBack( 2u + 4 * numberOfQuads ); + mesh.mIndices.PushBack( 3u + 4 * numberOfQuads ); + mesh.mIndices.PushBack( 1u + 4 * numberOfQuads ); + + numberOfQuads++; + } + } + + // Only create the background actor if there are glyphs with background color + if ( mesh.mVertices.Count() > 0u ) + { + Property::Map quadVertexFormat; + quadVertexFormat[ "aPosition" ] = Property::VECTOR2; + quadVertexFormat[ "aColor" ] = Property::VECTOR4; + + PropertyBuffer quadVertices = PropertyBuffer::New( quadVertexFormat ); + quadVertices.SetData( &mesh.mVertices[ 0 ], mesh.mVertices.Size() ); + + Geometry quadGeometry = Geometry::New(); + quadGeometry.AddVertexBuffer( quadVertices ); + quadGeometry.SetIndexBuffer( &mesh.mIndices[ 0 ], mesh.mIndices.Size() ); + + if( !mShaderBackground ) + { + mShaderBackground = Shader::New( VERTEX_SHADER_BACKGROUND, FRAGMENT_SHADER_BACKGROUND ); + } + + Dali::Renderer renderer = Dali::Renderer::New( quadGeometry, mShaderBackground ); + renderer.SetProperty( Dali::Renderer::Property::BLEND_MODE, BlendMode::ON ); + renderer.SetProperty( Dali::Renderer::Property::DEPTH_INDEX, DepthIndex::CONTENT ); + + actor = Actor::New(); + actor.SetName( "TextBackgroundColorActor" ); + actor.SetParentOrigin( ParentOrigin::TOP_LEFT ); + actor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + actor.SetSize( textSize ); + actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR ); + actor.AddRenderer( renderer ); + } + } + + return actor; +} + } // namespace Text } // namespace Toolkit diff --git a/dali-toolkit/internal/text/text-controller-impl.h b/dali-toolkit/internal/text/text-controller-impl.h index 5dd231a..064d644 100755 --- a/dali-toolkit/internal/text/text-controller-impl.h +++ b/dali-toolkit/internal/text/text-controller-impl.h @@ -21,6 +21,7 @@ // EXTERNAL INCLUDES #include #include +#include // INTERNAL INCLUDES #include @@ -724,6 +725,13 @@ struct Controller::Impl */ void ScrollTextToMatchCursor( const CursorInfo& cursorInfo ); + /** + * @brief Create an actor that renders the text background color + * + * @return the created actor or an empty handle if no background color needs to be rendered. + */ + Actor CreateBackgroundActor(); + public: /** @@ -780,6 +788,8 @@ public: bool mShouldClearFocusOnEscape:1; ///< Whether text control should clear key input focus LayoutDirection::Type mLayoutDirection; ///< Current system language direction + Shader mShaderBackground; ///< The shader for text background. + float mTextFitMinSize; ///< Minimum Font Size for text fit. Default 10 float mTextFitMaxSize; ///< Maximum Font Size for text fit. Default 100 float mTextFitStepSize; ///< Step Size for font intervalse. Default 1 diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index 76c7fdd..c017039 100755 --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -4297,6 +4297,11 @@ bool Controller::ShouldClearFocusOnEscape() const return mImpl->mShouldClearFocusOnEscape; } +Actor Controller::CreateBackgroundActor() +{ + return mImpl->CreateBackgroundActor(); +} + // private : Private contructors & copy operator. Controller::Controller() diff --git a/dali-toolkit/internal/text/text-controller.h b/dali-toolkit/internal/text/text-controller.h index 3e2a50d..82a7a15 100755 --- a/dali-toolkit/internal/text/text-controller.h +++ b/dali-toolkit/internal/text/text-controller.h @@ -1487,6 +1487,13 @@ public: // Text-input Event Queuing. */ bool ShouldClearFocusOnEscape() const; + /** + * @brief Create an actor that renders the text background color + * + * @return the created actor or an empty handle if no background color needs to be rendered. + */ + Actor CreateBackgroundActor(); + protected: // Inherit from Text::Decorator::ControllerInterface. /** diff --git a/dali-toolkit/internal/text/text-model-interface.h b/dali-toolkit/internal/text/text-model-interface.h index a301d03..812ba7c 100755 --- a/dali-toolkit/internal/text/text-model-interface.h +++ b/dali-toolkit/internal/text/text-model-interface.h @@ -162,6 +162,20 @@ public: virtual const ColorIndex* const GetColorIndices() const = 0; /** + * @brief Retrieves the vector of background colors. + * + * @return Pointer to the vector of background colors. + */ + virtual const Vector4* const GetBackgroundColors() const = 0; + + /** + * @brief Retrieves the vector of indices to the vector of background colors. + * + * @return Pointer to a vector which stores for each glyph the index to the vector of background colors. + */ + virtual const ColorIndex* const GetBackgroundColorIndices() const = 0; + + /** * @brief Retrieves the text's default color. * * @return The default color. diff --git a/dali-toolkit/internal/text/text-model.cpp b/dali-toolkit/internal/text/text-model.cpp index da87e0c..c1767d8 100755 --- a/dali-toolkit/internal/text/text-model.cpp +++ b/dali-toolkit/internal/text/text-model.cpp @@ -112,6 +112,16 @@ const ColorIndex* const Model::GetColorIndices() const return mVisualModel->mColorIndices.Begin(); } +const Vector4* const Model::GetBackgroundColors() const +{ + return mVisualModel->mBackgroundColors.Begin(); +} + +const ColorIndex* const Model::GetBackgroundColorIndices() const +{ + return mVisualModel->mBackgroundColorIndices.Begin(); +} + const Vector4& Model::GetDefaultColor() const { return mVisualModel->mTextColor; diff --git a/dali-toolkit/internal/text/text-model.h b/dali-toolkit/internal/text/text-model.h index 3230e47..5edb294 100755 --- a/dali-toolkit/internal/text/text-model.h +++ b/dali-toolkit/internal/text/text-model.h @@ -139,6 +139,16 @@ public: virtual const ColorIndex* const GetColorIndices() const override; /** + * @copydoc ModelInterface::GetBackgroundColors() + */ + virtual const Vector4* const GetBackgroundColors() const override; + + /** + * @copydoc ModelInterface::GetBackgroundColorIndices() + */ + virtual const ColorIndex* const GetBackgroundColorIndices() const override; + + /** * @copydoc ModelInterface::GetDefaultColor() */ virtual const Vector4& GetDefaultColor() const override; diff --git a/dali-toolkit/internal/text/text-view-interface.h b/dali-toolkit/internal/text/text-view-interface.h index 9e8020c..4aad47b 100755 --- a/dali-toolkit/internal/text/text-view-interface.h +++ b/dali-toolkit/internal/text/text-view-interface.h @@ -114,6 +114,20 @@ public: virtual const ColorIndex* const GetColorIndices() const = 0; /** + * @brief Retrieves the vector of background colors. + * + * @return Pointer to the vector of background colors. + */ + virtual const Vector4* const GetBackgroundColors() const = 0; + + /** + * @brief Retrieves the vector of indices to the vector of background colors. + * + * @return Pointer to a vector which stores for each glyph the index to the vector of background colors. + */ + virtual const ColorIndex* const GetBackgroundColorIndices() const = 0; + + /** * @brief Retrieves the text color * * @return The text color diff --git a/dali-toolkit/internal/text/text-view.cpp b/dali-toolkit/internal/text/text-view.cpp index 929c17c..9d9f991 100755 --- a/dali-toolkit/internal/text/text-view.cpp +++ b/dali-toolkit/internal/text/text-view.cpp @@ -326,6 +326,26 @@ const ColorIndex* const View::GetColorIndices() const return NULL; } +const Vector4* const View::GetBackgroundColors() const +{ + if( mImpl->mVisualModel ) + { + return mImpl->mVisualModel->mBackgroundColors.Begin(); + } + + return nullptr; +} + +const ColorIndex* const View::GetBackgroundColorIndices() const +{ + if( mImpl->mVisualModel ) + { + return mImpl->mVisualModel->mBackgroundColorIndices.Begin(); + } + + return nullptr; +} + const Vector4& View::GetTextColor() const { if( mImpl->mVisualModel ) diff --git a/dali-toolkit/internal/text/text-view.h b/dali-toolkit/internal/text/text-view.h index e7d1942..91b7867 100755 --- a/dali-toolkit/internal/text/text-view.h +++ b/dali-toolkit/internal/text/text-view.h @@ -90,6 +90,16 @@ public: virtual const ColorIndex* const GetColorIndices() const; /** + * @copydoc Dali::Toolkit::Text::ViewInterface::GetBackgroundColors() + */ + virtual const Vector4* const GetBackgroundColors() const; + + /** + * @copydoc Dali::Toolkit::Text::ViewInterface::GetBackgroundColorIndices() + */ + virtual const ColorIndex* const GetBackgroundColorIndices() const; + + /** * @copydoc Dali::Toolkit::Text::ViewInterface::GetTextColor() */ virtual const Vector4& GetTextColor() const; diff --git a/dali-toolkit/internal/text/visual-model-impl.h b/dali-toolkit/internal/text/visual-model-impl.h index 81ec9fe..853e946 100755 --- a/dali-toolkit/internal/text/visual-model-impl.h +++ b/dali-toolkit/internal/text/visual-model-impl.h @@ -389,6 +389,8 @@ public: Vector mUnderlineRuns; ///< Runs of glyphs that are underlined. Vector mColors; ///< Colors of the glyphs. Vector mColorIndices; ///< Indices to the vector of colors for each glyphs. + Vector mBackgroundColors; ///< Background colors of the glyphs. + Vector mBackgroundColorIndices; ///< Indices to the vector of background colors for each glyphs. Vector4 mTextColor; ///< The text color Vector4 mShadowColor; ///< Color of drop shadow -- 2.7.4