X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fvisuals%2Ftext%2Ftext-visual.cpp;h=e7b40a88fb263eb57de0411e4da4f55c7a92519a;hp=31dc8bb2f721e0faa9e3d885da7adc3162dcf385;hb=0b4c2e43605425eb9f676824515370f541712d3f;hpb=5b71e5d95f63c4aad74ffefe112fd13813cd90dc diff --git a/dali-toolkit/internal/visuals/text/text-visual.cpp b/dali-toolkit/internal/visuals/text/text-visual.cpp index 31dc8bb..e7b40a8 100644 --- a/dali-toolkit/internal/visuals/text/text-visual.cpp +++ b/dali-toolkit/internal/visuals/text/text-visual.cpp @@ -18,22 +18,15 @@ // CLASS HEADER #include -// EXTERNAL HEADER -#include -// #include - // INTERNAL HEADER -#include -#include +#include +#include #include -#include -#include +#include #include #include +#include #include -#include - -using Dali::Toolkit::Text::LayoutEngine; namespace Dali { @@ -48,7 +41,6 @@ namespace { // Property names. -const char * const RENDERING_BACKEND_PROPERTY( "renderingBackend" ); const char * const TEXT_PROPERTY( "text" ); const char * const FONT_FAMILY_PROPERTY( "fontFamily" ); const char * const FONT_STYLE_PROPERTY( "fontStyle" ); @@ -58,46 +50,41 @@ const char * const HORIZONTAL_ALIGNMENT_PROPERTY( "horizontalAlignment" ); const char * const VERTICAL_ALIGNMENT_PROPERTY( "verticalAlignment" ); const char * const TEXT_COLOR_PROPERTY( "textColor" ); const char * const ENABLE_MARKUP_PROPERTY( "enableMarkup" ); -const char * const ENABLE_AUTO_SCROLL_PROPERTY( "enableAutoScroll" ); -const char * const AUTO_SCROLL_SPEED_PROPERTY( "autoScrollSpeed" ); -const char * const AUTO_SCROLL_LOOP_COUNT_PROPERTY( "autoScrollLoopCount" ); -const char * const AUTO_SCROLL_GAP_PROPERTY( "autoScrollGap" ); -const char * const LINE_SPACING_PROPERTY( "lineSpacing" ); -const char * const UNDERLINE_PROPERTY( "underline" ); -const char * const SHADOW_PROPERTY( "shadow" ); -const char * const OUTLINE_PROPERTY( "outline" ); -const char * const BATCHING_ENABLED_PROPERTY( "batchingEnabled" ); + +const std::string PIXEL_AREA_UNIFORM_NAME = "pixelArea"; const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] = { - { "BEGIN", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_BEGIN }, - { "CENTER", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_CENTER }, - { "END", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_END }, + { "BEGIN", Toolkit::Text::Layout::HORIZONTAL_ALIGN_BEGIN }, + { "CENTER", Toolkit::Text::Layout::HORIZONTAL_ALIGN_CENTER }, + { "END", Toolkit::Text::Layout::HORIZONTAL_ALIGN_END }, }; const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] ); const Scripting::StringEnum VERTICAL_ALIGNMENT_STRING_TABLE[] = { - { "TOP", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_TOP }, - { "CENTER", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_CENTER }, - { "BOTTOM", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_BOTTOM }, + { "TOP", Toolkit::Text::Layout::VERTICAL_ALIGN_TOP }, + { "CENTER", Toolkit::Text::Layout::VERTICAL_ALIGN_CENTER }, + { "BOTTOM", Toolkit::Text::Layout::VERTICAL_ALIGN_BOTTOM }, }; const unsigned int VERTICAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( VERTICAL_ALIGNMENT_STRING_TABLE ) / sizeof( VERTICAL_ALIGNMENT_STRING_TABLE[0] ); -std::string GetHorizontalAlignment( LayoutEngine::HorizontalAlignment alignment ) +const Vector4 FULL_TEXTURE_RECT( 0.f, 0.f, 1.f, 1.f ); + +std::string GetHorizontalAlignment( Toolkit::Text::Layout::HorizontalAlignment alignment ) { - const char* name = Scripting::GetEnumerationName( alignment, - HORIZONTAL_ALIGNMENT_STRING_TABLE, - HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT ); + const char* name = Scripting::GetEnumerationName( alignment, + HORIZONTAL_ALIGNMENT_STRING_TABLE, + HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT ); return std::string( name ); } -std::string GetVerticalAlignment( LayoutEngine::VerticalAlignment alignment ) +std::string GetVerticalAlignment( Toolkit::Text::Layout::VerticalAlignment alignment ) { - const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( alignment, - VERTICAL_ALIGNMENT_STRING_TABLE, - VERTICAL_ALIGNMENT_STRING_TABLE_COUNT ); + const char* name = Scripting::GetEnumerationName< Toolkit::Text::Layout::VerticalAlignment >( alignment, + VERTICAL_ALIGNMENT_STRING_TABLE, + VERTICAL_ALIGNMENT_STRING_TABLE_COUNT ); return std::string( name ); } @@ -109,12 +96,24 @@ const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( uniform mediump vec4 pixelArea; varying mediump vec2 vTexCoord;\n \n + + //Visual size and offset + uniform mediump vec2 offset;\n + uniform mediump vec2 size;\n + uniform mediump vec4 offsetSizeMode;\n + uniform mediump vec2 origin;\n + uniform mediump vec2 anchorPoint;\n + + vec4 ComputeVertexPosition()\n + {\n + vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw );\n + vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n + return vec4( (aPosition + anchorPoint)*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n + }\n + void main()\n {\n - mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n - vertexPosition.xyz *= uSize;\n - vertexPosition = uMvpMatrix * vertexPosition;\n - \n + mediump vec4 vertexPosition = uMvpMatrix *ComputeVertexPosition();\n vTexCoord = pixelArea.xy+pixelArea.zw*(aPosition + vec2(0.5) );\n gl_Position = vertexPosition;\n }\n @@ -133,27 +132,6 @@ const char* FRAGMENT_SHADER_ATLAS_CLAMP = DALI_COMPOSE_SHADER( }\n ); -Geometry CreateGeometry( VisualFactoryCache& factoryCache, ImageDimensions gridSize ) -{ - Geometry geometry; - - if( gridSize == ImageDimensions( 1, 1 ) ) - { - geometry = factoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY ); - if( !geometry ) - { - geometry = VisualFactoryCache::CreateQuadGeometry(); - factoryCache.SaveGeometry( VisualFactoryCache::QUAD_GEOMETRY, geometry ); - } - } - else - { - geometry = VisualFactoryCache::CreateGridGeometry( gridSize ); - } - - return geometry; -} - } // unnamed namespace TextVisualPtr TextVisual::New( VisualFactoryCache& factoryCache ) @@ -161,36 +139,12 @@ TextVisualPtr TextVisual::New( VisualFactoryCache& factoryCache ) return new TextVisual( factoryCache ); } -void TextVisual::SetTextControlInterface( Text::ControlInterface* controlInterface ) -{ - if( mController ) - { - mController->SetTextControlInterface( controlInterface ); - } -} - -void TextVisual::SetSize( const Vector2& size ) -{ - const Text::Controller::UpdateTextType updateTextType = mController->Relayout( size ); - - if( ( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) ) || - !mRenderer ) - { - if( !mRenderer ) - { - mRenderer = Text::Backend::Get().NewRenderer( mRenderingBackend ); - } - - RenderText(); - } -} - float TextVisual::GetHeightForWidth( float width ) const { return mController->GetHeightForWidth( width ); } -void TextVisual::GetNaturalSize( Vector2& naturalSize ) const +void TextVisual::GetNaturalSize( Vector2& naturalSize ) { naturalSize = mController->GetNaturalSize().GetVectorXY(); } @@ -200,9 +154,7 @@ void TextVisual::DoCreatePropertyMap( Property::Map& map ) const Property::Value value; map.Clear(); - map.Insert( Toolkit::Visual::Property::TYPE, Toolkit::Visual::TEXT ); - - map.Insert( Toolkit::TextVisual::Property::RENDERING_BACKEND, mRenderingBackend ); + map.Insert( Toolkit::DevelVisual::Property::TYPE, Toolkit::DevelVisual::TEXT ); std::string text; mController->GetText( text ); @@ -221,37 +173,15 @@ void TextVisual::DoCreatePropertyMap( Property::Map& map ) const map.Insert( Toolkit::TextVisual::Property::VERTICAL_ALIGNMENT, GetVerticalAlignment( mController->GetVerticalAlignment() ) ); - map.Insert( Toolkit::TextVisual::Property::TEXT_COLOR, mController->GetTextColor() ); + map.Insert( Toolkit::TextVisual::Property::TEXT_COLOR, mController->GetDefaultColor() ); map.Insert( Toolkit::TextVisual::Property::ENABLE_MARKUP, mController->IsMarkupProcessorEnabled() ); - - map.Insert( Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL, mController->IsAutoScrollEnabled() ); - - map.Insert( Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED, mController->GetAutoScrollSpeed() ); - - map.Insert( Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT, mController->GetAutoScrollLoopCount() ); - - map.Insert( Toolkit::TextVisual::Property::AUTO_SCROLL_GAP, mController->GetAutoScrollWrapGap() ); - - map.Insert( Toolkit::TextVisual::Property::LINE_SPACING, mController->GetDefaultLineSpacing() ); - - GetUnderlineProperties( mController, value, Text::EffectStyle::DEFAULT ); - map.Insert( Toolkit::TextVisual::Property::UNDERLINE, value ); - - GetShadowProperties( mController, value, Text::EffectStyle::DEFAULT ); - map.Insert( Toolkit::TextVisual::Property::SHADOW, value ); - - GetOutlineProperties( mController, value, Text::EffectStyle::DEFAULT ); - map.Insert( Toolkit::TextVisual::Property::OUTLINE, value ); - - map.Insert( Toolkit::TextVisual::Property::BATCHING_ENABLED, false ); // TODO } TextVisual::TextVisual( VisualFactoryCache& factoryCache ) : Visual::Base( factoryCache ), mController( Text::Controller::New() ), - mRenderingBackend( Toolkit::Text::DEFAULT_RENDERING_BACKEND ), - mHasBeenStaged( false ) + mTypesetter( Text::Typesetter::New( mController->GetTextModel() ) ) { } @@ -269,19 +199,12 @@ void TextVisual::DoSetProperties( const Property::Map& propertyMap ) { case Property::Key::INDEX: { - if( Toolkit::Visual::Property::TYPE != keyValue.first.indexKey ) // Toolkit::Visual::Property::TYPE is not a TextVisual's property. - { - DoSetProperty( keyValue.first.indexKey, keyValue.second ); - } + DoSetProperty( keyValue.first.indexKey, keyValue.second ); break; } case Property::Key::STRING: { - if( keyValue.first.stringKey == RENDERING_BACKEND_PROPERTY ) - { - DoSetProperty( Toolkit::TextVisual::Property::RENDERING_BACKEND, keyValue.second ); - } - else if( keyValue.first.stringKey == TEXT_PROPERTY ) + if( keyValue.first.stringKey == TEXT_PROPERTY ) { DoSetProperty( Toolkit::TextVisual::Property::TEXT, keyValue.second ); } @@ -317,52 +240,16 @@ void TextVisual::DoSetProperties( const Property::Map& propertyMap ) { DoSetProperty( Toolkit::TextVisual::Property::ENABLE_MARKUP, keyValue.second ); } - else if( keyValue.first.stringKey == ENABLE_AUTO_SCROLL_PROPERTY ) - { - DoSetProperty( Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL, keyValue.second ); - } - else if( keyValue.first.stringKey == AUTO_SCROLL_SPEED_PROPERTY ) - { - DoSetProperty( Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED, keyValue.second ); - } - else if( keyValue.first.stringKey == AUTO_SCROLL_LOOP_COUNT_PROPERTY ) - { - DoSetProperty( Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT, keyValue.second ); - } - else if( keyValue.first.stringKey == AUTO_SCROLL_GAP_PROPERTY ) - { - DoSetProperty( Toolkit::TextVisual::Property::AUTO_SCROLL_GAP, keyValue.second ); - } - else if( keyValue.first.stringKey == LINE_SPACING_PROPERTY ) - { - DoSetProperty( Toolkit::TextVisual::Property::LINE_SPACING, keyValue.second ); - } - else if( keyValue.first.stringKey == UNDERLINE_PROPERTY ) - { - DoSetProperty( Toolkit::TextVisual::Property::UNDERLINE, keyValue.second ); - } - else if( keyValue.first.stringKey == SHADOW_PROPERTY ) - { - DoSetProperty( Toolkit::TextVisual::Property::SHADOW, keyValue.second ); - } - else if( keyValue.first.stringKey == OUTLINE_PROPERTY ) - { - DoSetProperty( Toolkit::TextVisual::Property::OUTLINE, keyValue.second ); - } - else if( keyValue.first.stringKey == BATCHING_ENABLED_PROPERTY ) - { - DoSetProperty( Toolkit::TextVisual::Property::BATCHING_ENABLED, keyValue.second ); - } break; } } } - // Retrieve the layout engine to set whether to elide the text and set the cursor's width. - Text::LayoutEngine& engine = mController->GetLayoutEngine(); - // Elide the text if it exceeds the boundaries. - engine.SetTextEllipsisEnabled( true ); + mController->SetTextElideEnabled( true ); + + // Retrieve the layout engine to set the cursor's width. + Text::Layout::Engine& engine = mController->GetLayoutEngine(); // Sets 0 as cursor's width. engine.SetCursorWidth( 0u ); // Do not layout space for the cursor. @@ -370,62 +257,59 @@ void TextVisual::DoSetProperties( const Property::Map& propertyMap ) void TextVisual::DoSetOnStage( Actor& actor ) { - // TODO Create the actual renderer(s) for the text!!!! - // Will crash if no mImpl->mRenderer is set. - Geometry geometry; - Shader shader; + mControl = actor; - geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) ); + Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY ); + if( !geometry ) + { + geometry = VisualFactoryCache::CreateQuadGeometry(); + mFactoryCache.SaveGeometry( VisualFactoryCache::QUAD_GEOMETRY , geometry ); + } - shader = mFactoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_DEFAULT_WRAP ); + Shader shader = mFactoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_DEFAULT_WRAP ); if( !shader ) { shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_CLAMP ); mFactoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_DEFAULT_WRAP, shader ); } + shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); mImpl->mRenderer = Renderer::New( geometry, shader ); + mImpl->mRenderer.SetProperty( Dali::Renderer::Property::DEPTH_INDEX, Toolkit::DepthIndex::TEXT ); - mSelf = actor; + UpdateRenderer(); +} - if( mHasBeenStaged ) - { - RenderText(); - } - else +void TextVisual::DoSetOffStage( Actor& actor ) +{ + if( mImpl->mRenderer ) { - mHasBeenStaged = true; + // Removes the renderer from the actor. + actor.RemoveRenderer( mImpl->mRenderer ); + + RemoveTextureSet(); + + // Resets the renderer. + mImpl->mRenderer.Reset(); } + + // Resets the control handle. + mControl.Reset(); } -void TextVisual::DoSetOffStage( Actor& actor ) +void TextVisual::OnSetTransform() { - mSelf.Reset(); + UpdateRenderer(); } void TextVisual::DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue ) { switch( index ) { - case Toolkit::TextVisual::Property::RENDERING_BACKEND: + case Toolkit::TextVisual::Property::ENABLE_MARKUP: { - int backend = propertyValue.Get(); - -#ifndef ENABLE_VECTOR_BASED_TEXT_RENDERING - if( Text::RENDERING_VECTOR_BASED == backend ) - { - backend = TextAbstraction::BITMAP_GLYPH; // Fallback to bitmap-based rendering - } -#endif - if( mRenderingBackend != backend ) - { - mRenderingBackend = backend; - mRenderer.Reset(); - - // When using the vector-based rendering, the size of the GLyphs are different - TextAbstraction::GlyphType glyphType = ( Text::RENDERING_VECTOR_BASED == mRenderingBackend ) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH; - mController->SetGlyphType( glyphType ); - } + const bool enableMarkup = propertyValue.Get(); + mController->SetMarkupProcessorEnabled( enableMarkup ); break; } case Toolkit::TextVisual::Property::TEXT: @@ -446,7 +330,6 @@ void TextVisual::DoSetProperty( Dali::Property::Index index, const Dali::Propert case Toolkit::TextVisual::Property::POINT_SIZE: { const float pointSize = propertyValue.Get(); - if( !Equals( mController->GetDefaultPointSize(), pointSize ) ) { mController->SetDefaultPointSize( pointSize ); @@ -460,11 +343,11 @@ void TextVisual::DoSetProperty( Dali::Property::Index index, const Dali::Propert } case Toolkit::TextVisual::Property::HORIZONTAL_ALIGNMENT: { - LayoutEngine::HorizontalAlignment alignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN ); - if( Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::HorizontalAlignment >( propertyValue.Get< std::string >().c_str(), - HORIZONTAL_ALIGNMENT_STRING_TABLE, - HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT, - alignment ) ) + Toolkit::Text::Layout::HorizontalAlignment alignment( Toolkit::Text::Layout::HORIZONTAL_ALIGN_BEGIN ); + if( Scripting::GetEnumeration< Toolkit::Text::Layout::HorizontalAlignment >( propertyValue.Get< std::string >().c_str(), + HORIZONTAL_ALIGNMENT_STRING_TABLE, + HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT, + alignment ) ) { mController->SetHorizontalAlignment( alignment ); } @@ -472,11 +355,11 @@ void TextVisual::DoSetProperty( Dali::Property::Index index, const Dali::Propert } case Toolkit::TextVisual::Property::VERTICAL_ALIGNMENT: { - LayoutEngine::VerticalAlignment alignment( LayoutEngine::VERTICAL_ALIGN_BOTTOM ); - if( Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::VerticalAlignment >( propertyValue.Get< std::string >().c_str(), - VERTICAL_ALIGNMENT_STRING_TABLE, - VERTICAL_ALIGNMENT_STRING_TABLE_COUNT, - alignment ) ) + Toolkit::Text::Layout::VerticalAlignment alignment( Toolkit::Text::Layout::VERTICAL_ALIGN_BOTTOM ); + if( Scripting::GetEnumeration< Toolkit::Text::Layout::VerticalAlignment >( propertyValue.Get< std::string >().c_str(), + VERTICAL_ALIGNMENT_STRING_TABLE, + VERTICAL_ALIGNMENT_STRING_TABLE_COUNT, + alignment ) ) { mController->SetVerticalAlignment( alignment ); } @@ -484,398 +367,126 @@ void TextVisual::DoSetProperty( Dali::Property::Index index, const Dali::Propert } case Toolkit::TextVisual::Property::TEXT_COLOR: { - const Vector4 textColor = propertyValue.Get< Vector4 >(); - if( mController->GetTextColor() != textColor ) - { - mController->SetTextColor( textColor ); - mRenderer.Reset(); - } - break; - } - case Toolkit::TextVisual::Property::ENABLE_MARKUP: - { - const bool enableMarkup = propertyValue.Get(); - mController->SetMarkupProcessorEnabled( enableMarkup ); - break; - } - case Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL: - { - const bool enableAutoScroll = propertyValue.Get(); - - // If request to auto scroll is the same as current state then do nothing. - if( enableAutoScroll != mController->IsAutoScrollEnabled() ) - { - // If request is disable (false) and auto scrolling is enabled then need to stop it - if( !enableAutoScroll ) - { - StopTextAutoScrolling(); // Causes the current animation to finish playing. - } - // If request is enable (true) then start autoscroll as not already running - else - { - mController->GetLayoutEngine().SetTextEllipsisEnabled( false ); - mController->SetAutoScrollEnabled( enableAutoScroll ); - mController->RequestRelayout(); - } - } - break; - } - case Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED: - { - mController->SetAutoscrollSpeed( propertyValue.Get() ); - break; - } - case Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT: - { - const int loopCount = propertyValue.Get(); - if( loopCount > 0 ) - { - mController->SetAutoScrollLoopCount( loopCount ); - } - else - { - StopTextAutoScrolling(); // Causes the current animation to finish playing. - } - break; - } - case Toolkit::TextVisual::Property::AUTO_SCROLL_GAP: - { - mController->SetAutoScrollWrapGap( propertyValue.Get() ); - break; - } - case Toolkit::TextVisual::Property::LINE_SPACING: - { - const float lineSpacing = propertyValue.Get(); - mController->SetDefaultLineSpacing( lineSpacing ); - mRenderer.Reset(); - break; - } - case Toolkit::TextVisual::Property::UNDERLINE: - { - // TODO : This switch can be removed when the deprecated SHADOW_OFFSET and SHADOW_COLOR properties are finally removed. - // Only the code for the STRING case should be kept. - switch( propertyValue.GetType() ) - { - case Property::VECTOR4: - { - const Vector4 color = propertyValue.Get(); - if( mController->GetUnderlineColor() != color ) - { - mController->SetUnderlineColor( color ); - mRenderer.Reset(); - } - break; - } - case Property::FLOAT: - { - float height = propertyValue.Get(); - if( fabsf( mController->GetUnderlineHeight() - height ) > Math::MACHINE_EPSILON_1000 ) - { - mController->SetUnderlineHeight( height ); - mRenderer.Reset(); - } - break; - } - case Property::BOOLEAN: - { - const bool enabled = propertyValue.Get(); - if( mController->IsUnderlineEnabled() != enabled ) - { - mController->SetUnderlineEnabled( enabled ); - mRenderer.Reset(); - } - break; - } - case Property::STRING: - { - const bool update = SetUnderlineProperties( mController, propertyValue, Text::EffectStyle::DEFAULT ); - if( update ) - { - mRenderer.Reset(); - } - break; - } - default: - { - // Nothing to do. - break; - } - } - - break; - } - case Toolkit::TextVisual::Property::SHADOW: - { - // TODO : This switch can be removed when the deprecated SHADOW_OFFSET and SHADOW_COLOR properties are finally removed. - // Only the code for the STRING case should be kept. - switch( propertyValue.GetType() ) + const Vector4& textColor = propertyValue.Get< Vector4 >(); + if( mController->GetDefaultColor() != textColor ) { - case Property::VECTOR2: - { - const Vector2 shadowOffset = propertyValue.Get(); - if( mController->GetShadowOffset() != shadowOffset ) - { - mController->SetShadowOffset( shadowOffset ); - mRenderer.Reset(); - } - break; - } - case Property::VECTOR4: - { - const Vector4 shadowColor = propertyValue.Get(); - if( mController->GetShadowColor() != shadowColor ) - { - mController->SetShadowColor( shadowColor ); - mRenderer.Reset(); - } - break; - } - case Property::STRING: - { - const bool update = SetShadowProperties( mController, propertyValue, Text::EffectStyle::DEFAULT ); - if( update ) - { - mRenderer.Reset(); - } - break; - } - default: - { - // Nothing to do. - break; - } + mController->SetDefaultColor( textColor ); } break; } - case Toolkit::TextVisual::Property::EMBOSS: - { - const bool update = SetEmbossProperties( mController, propertyValue, Text::EffectStyle::DEFAULT ); - if( update ) - { - mRenderer.Reset(); - } - break; - } - case Toolkit::TextVisual::Property::OUTLINE: - { - const bool update = SetOutlineProperties( mController, propertyValue, Text::EffectStyle::DEFAULT ); - if( update ) - { - mRenderer.Reset(); - } - break; - } - case Toolkit::TextVisual::Property::BATCHING_ENABLED: - { - // TODO - break; - } - default: - { - // Should not arrive here. - DALI_ASSERT_DEBUG( false ); - } } } -Dali::Property::Value TextVisual::DoGetProperty( Dali::Property::Index index ) +void TextVisual::UpdateRenderer() { - Dali::Property::Value value; + Actor control = mControl.GetHandle(); + if( !control ) + { + // Nothing to do. + return; + } - switch( index ) + // Calculates the size to be used to relayout. + Vector2 relayoutSize; + + const bool isWidthRelative = fabsf( mImpl->mTransform.mOffsetSizeMode.z ) < Math::MACHINE_EPSILON_1000; + const bool isHeightRelative = fabsf( mImpl->mTransform.mOffsetSizeMode.w ) < Math::MACHINE_EPSILON_1000; + + // Round the size and offset to avoid pixel alignement issues. + relayoutSize.width = floorf( 0.5f + ( isWidthRelative ? mImpl->mControlSize.width * mImpl->mTransform.mSize.x : mImpl->mTransform.mSize.width ) ); + relayoutSize.height = floorf( 0.5f + ( isHeightRelative ? mImpl->mControlSize.height * mImpl->mTransform.mSize.y : mImpl->mTransform.mSize.height ) ); + + if( ( fabsf( relayoutSize.width ) < Math::MACHINE_EPSILON_1000 ) || ( fabsf( relayoutSize.height ) < Math::MACHINE_EPSILON_1000 ) ) { - case Toolkit::TextVisual::Property::RENDERING_BACKEND: - { - value = mRenderingBackend; - break; - } - case Toolkit::TextVisual::Property::TEXT: - { - std::string text; - mController->GetText( text ); - value = text; - break; - } - case Toolkit::TextVisual::Property::FONT_FAMILY: - { - value = mController->GetDefaultFontFamily(); - break; - } - case Toolkit::TextVisual::Property::FONT_STYLE: - { - GetFontStyleProperty( mController, value, Text::FontStyle::DEFAULT ); - break; - } - case Toolkit::TextVisual::Property::POINT_SIZE: + // Removes the texture set. + RemoveTextureSet(); + + // Remove any renderer previously set. + if( mImpl->mRenderer ) { - value = mController->GetDefaultPointSize(); - break; + control.RemoveRenderer( mImpl->mRenderer ); } - case Toolkit::TextVisual::Property::MULTI_LINE: + + // Nothing else to do if the relayout size is zero. + return; + } + + const Text::Controller::UpdateTextType updateTextType = mController->Relayout( relayoutSize ); + + if( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) ) + { + // Removes the texture set. + RemoveTextureSet(); + + // Remove any renderer previously set. + if( mImpl->mRenderer ) { - value = mController->IsMultiLineEnabled(); - break; + control.RemoveRenderer( mImpl->mRenderer ); } - case Toolkit::TextVisual::Property::HORIZONTAL_ALIGNMENT: + + if( ( relayoutSize.width > Math::MACHINE_EPSILON_1000 ) && + ( relayoutSize.height > Math::MACHINE_EPSILON_1000 ) ) { - const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( mController->GetHorizontalAlignment(), - HORIZONTAL_ALIGNMENT_STRING_TABLE, - HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT ); - if( name ) + PixelData data = mTypesetter->Render( relayoutSize ); + + Vector4 atlasRect = FULL_TEXTURE_RECT; + TextureSet textureSet = mFactoryCache.GetAtlasManager()->Add( atlasRect, data ); + + if( textureSet ) { - value = std::string( name ); + mImpl->mFlags |= Impl::IS_ATLASING_APPLIED; } - break; - } - case Toolkit::TextVisual::Property::VERTICAL_ALIGNMENT: - { - const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( mController->GetVerticalAlignment(), - VERTICAL_ALIGNMENT_STRING_TABLE, - VERTICAL_ALIGNMENT_STRING_TABLE_COUNT ); - if( name ) + else { - value = std::string( name ); - } - break; - } - case Toolkit::TextVisual::Property::TEXT_COLOR: - { - value = mController->GetTextColor(); - break; - } - case Toolkit::TextVisual::Property::ENABLE_MARKUP: - { - value = mController->IsMarkupProcessorEnabled(); - break; - } - case Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL: - { - value = mController->IsAutoScrollEnabled(); - break; - } - case Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED: - { - value = mController->GetAutoScrollSpeed(); - break; - } - case Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT: - { - value = mController->GetAutoScrollLoopCount(); - break; - } - case Toolkit::TextVisual::Property::AUTO_SCROLL_GAP: - { - value = mController->GetAutoScrollWrapGap(); - break; - } - case Toolkit::TextVisual::Property::LINE_SPACING: - { - value = mController->GetDefaultLineSpacing(); - break; - } - case Toolkit::TextVisual::Property::UNDERLINE: - { - GetUnderlineProperties( mController, value, Text::EffectStyle::DEFAULT ); - break; - } - case Toolkit::TextVisual::Property::SHADOW: - { - GetShadowProperties( mController, value, Text::EffectStyle::DEFAULT ); - break; - } - case Toolkit::TextVisual::Property::EMBOSS: - { - GetEmbossProperties( mController, value, Text::EffectStyle::DEFAULT ); - break; - } - case Toolkit::TextVisual::Property::OUTLINE: - { - GetOutlineProperties( mController, value, Text::EffectStyle::DEFAULT ); - break; - } - case Toolkit::TextVisual::Property::BATCHING_ENABLED: - { - // TODO - break; - } - default: - { - // Should not arrive here. - DALI_ASSERT_DEBUG( false ); - } - } + // 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. - return value; -} + Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D, + data.GetPixelFormat(), + data.GetWidth(), + data.GetHeight() ); -void TextVisual::RenderText() -{ - Actor self = mSelf.GetHandle(); - if( !self ) - { - // Nothing to do if the handle is not initialized. - return; - } + texture.Upload( data ); - Actor renderableActor; + textureSet = TextureSet::New(); + textureSet.SetTexture( 0u, texture ); - if( mRenderer ) - { - renderableActor = mRenderer->Render( mController->GetView(), Toolkit::DepthIndex::TEXT ); - } + mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED; + } - if( renderableActor != mRenderableActor ) - { - UnparentAndReset( mRenderableActor ); + mImpl->mRenderer.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, atlasRect ); - if( renderableActor ) - { - const Vector2& scrollOffset = mController->GetScrollPosition(); - renderableActor.SetPosition( scrollOffset.x, scrollOffset.y ); + //Register transform properties + mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT ); - self.Add( renderableActor ); - } - mRenderableActor = renderableActor; + // Filter mode needs to be set to nearest to avoid blurry text. + Sampler sampler = Sampler::New(); + sampler.SetFilterMode( FilterMode::NEAREST, FilterMode::NEAREST ); + textureSet.SetSampler( 0u, sampler ); - if( mController->IsAutoScrollEnabled() ) - { - SetUpAutoScrolling(); - } - } -} + mImpl->mRenderer.SetTextures( textureSet ); -void TextVisual::StopTextAutoScrolling() -{ - if( mTextScroller ) - { - mTextScroller->StopScrolling(); + control.AddRenderer( mImpl->mRenderer ); + } } } -void TextVisual::SetUpAutoScrolling() +void TextVisual::RemoveTextureSet() { - Actor self = mSelf.GetHandle(); - if( !self ) + if( mImpl->mFlags & Impl::IS_ATLASING_APPLIED ) { - // Nothing to do if the handle is not initialized. - return; - } - - const Text::ScrollerData* const data = mController->GetAutoScrollData(); + // Removes the text's image from the texture atlas. + Vector4 atlasRect; - if( NULL != data ) - { - if( !mTextScroller ) + const Property::Index index = mImpl->mRenderer.GetPropertyIndex( ATLAS_RECT_UNIFORM_NAME ); + if( index != Property::INVALID_INDEX ) { - // If speed, loopCount or gap not set via property system then will need to create a TextScroller with defaults - mTextScroller = Text::TextScroller::New( *mController ); - } + const Property::Value& atlasRectValue = mImpl->mRenderer.GetProperty( index ); + atlasRectValue.Get( atlasRect ); - mTextScroller->StartScrolling( mRenderableActor, - *data ); - - self.Add( mTextScroller->GetScrollingText() ); - self.Add( mTextScroller->GetSourceCamera() ); + const TextureSet& textureSet = mImpl->mRenderer.GetTextures(); + mFactoryCache.GetAtlasManager()->Remove( textureSet, atlasRect ); + } } }