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=7ce455e6665eca6c3169e5ddc6aceb7a501f90fb;hp=2968f074d9d7f1f5f8f7bf1ca393e5540fd9e601;hb=723acb540264b5f3bfc98ec3284891aa58d765c4;hpb=5d9d55db30babd7cb6662b1cab287c2ff74430d9 diff --git a/dali-toolkit/internal/visuals/text/text-visual.cpp b/dali-toolkit/internal/visuals/text/text-visual.cpp index 2968f07..7ce455e 100644 --- a/dali-toolkit/internal/visuals/text/text-visual.cpp +++ b/dali-toolkit/internal/visuals/text/text-visual.cpp @@ -18,10 +18,6 @@ // CLASS HEADER #include -// EXTERNAL INCLUDES -#include -#include - // INTERNAL HEADER #include #include @@ -31,8 +27,6 @@ #include #include #include -#include -#include namespace Dali { @@ -55,8 +49,6 @@ 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 SHADOW_PROPERTY( "shadow" ); -const char * const UNDERLINE_PROPERTY( "underline" ); const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] = { @@ -98,14 +90,14 @@ const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( attribute mediump vec2 aPosition;\n uniform mediump mat4 uMvpMatrix;\n uniform mediump vec3 uSize;\n - uniform mediump vec4 pixelArea;\n + uniform mediump vec4 pixelArea; uniform mediump mat4 uModelMatrix;\n uniform mediump mat4 uViewMatrix;\n uniform mediump mat4 uProjection;\n varying mediump vec2 vTexCoord;\n - + \n //Visual size and offset uniform mediump vec2 offset;\n uniform mediump vec2 size;\n @@ -131,54 +123,19 @@ const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( }\n ); -const char* FRAGMENT_SHADER_ATLAS_CLAMP_RGBA = DALI_COMPOSE_SHADER( - varying mediump vec2 vTexCoord;\n - uniform sampler2D sTexture;\n - uniform sampler2D sStyle;\n - uniform sampler2D sMask;\n - uniform lowp float uHasMultipleTextColors;\n - uniform lowp vec4 uTextColorAnimatable;\n - uniform mediump vec4 uAtlasRect;\n - uniform lowp vec4 uColor;\n - uniform lowp vec3 mixColor;\n - uniform lowp float opacity;\n - \n - void main()\n - {\n - mediump vec2 texCoord = clamp( mix( uAtlasRect.xy, uAtlasRect.zw, vTexCoord ), uAtlasRect.xy, uAtlasRect.zw );\n - mediump vec4 textTexture = texture2D( sTexture, texCoord );\n - mediump vec4 styleTexture = texture2D( sStyle, texCoord );\n - mediump vec4 maskTexture = texture2D( sMask, texCoord );\n - - // Set the color of non-transparent pixel in text to what it is animated to. - // Markup text with multiple text colors are not animated (but can be supported later on if required). - // Emoji color are not animated. - mediump vec4 textColor = textTexture * textTexture.a;\n - mediump float vstep = step( 0.0001, textColor.a );\n - textColor.rgb = mix( textColor.rgb, uTextColorAnimatable.rgb, vstep * maskTexture.a * ( 1.0 - uHasMultipleTextColors ) );\n - - // Draw the text as overlay above the style - gl_FragColor = ( textColor + styleTexture * ( 1.0 - textTexture.a ) ) * uColor * vec4( mixColor, opacity );\n - }\n -); - -const char* FRAGMENT_SHADER_ATLAS_CLAMP_L8 = DALI_COMPOSE_SHADER( - varying mediump vec2 vTexCoord;\n - uniform sampler2D sTexture;\n - uniform lowp vec4 uTextColorAnimatable;\n - uniform mediump vec4 uAtlasRect;\n - uniform lowp vec4 uColor;\n - uniform lowp vec3 mixColor;\n - uniform lowp float opacity;\n - \n - void main()\n - {\n - mediump vec2 texCoord = clamp( mix( uAtlasRect.xy, uAtlasRect.zw, vTexCoord ), uAtlasRect.xy, uAtlasRect.zw );\n - mediump float textTexture = texture2D( sTexture, texCoord ).r;\n - - // Set the color of the text to what it is animated to. - gl_FragColor = uTextColorAnimatable * textTexture * uColor * vec4( mixColor, opacity );\n - }\n +const char* FRAGMENT_SHADER_ATLAS_CLAMP = DALI_COMPOSE_SHADER( + varying mediump vec2 vTexCoord;\n + uniform sampler2D sTexture;\n + uniform mediump vec4 uAtlasRect;\n + uniform lowp vec4 uColor;\n + uniform lowp vec3 mixColor;\n + uniform lowp float opacity;\n + \n + void main()\n + {\n + mediump vec2 texCoord = clamp( mix( uAtlasRect.xy, uAtlasRect.zw, vTexCoord ), uAtlasRect.xy, uAtlasRect.zw );\n + gl_FragColor = texture2D( sTexture, texCoord ) * uColor * vec4( mixColor, opacity );\n + }\n ); /** @@ -231,14 +188,6 @@ Dali::Property::Index StringKeyToIndexKey( const std::string& stringKey ) { result = Toolkit::TextVisual::Property::ENABLE_MARKUP; } - else if( stringKey == SHADOW_PROPERTY ) - { - result = Toolkit::TextVisual::Property::SHADOW; - } - else if( stringKey == UNDERLINE_PROPERTY ) - { - result = Toolkit::TextVisual::Property::UNDERLINE; - } return result; } @@ -310,12 +259,6 @@ void TextVisual::DoCreatePropertyMap( Property::Map& map ) const map.Insert( Toolkit::TextVisual::Property::TEXT_COLOR, mController->GetDefaultColor() ); map.Insert( Toolkit::TextVisual::Property::ENABLE_MARKUP, mController->IsMarkupProcessorEnabled() ); - - GetShadowProperties( mController, value, Text::EffectStyle::DEFAULT ); - map.Insert( Toolkit::TextVisual::Property::SHADOW, value ); - - GetUnderlineProperties( mController, value, Text::EffectStyle::DEFAULT ); - map.Insert( Toolkit::TextVisual::Property::UNDERLINE, value ); } void TextVisual::DoCreateInstancePropertyMap( Property::Map& map ) const @@ -331,9 +274,7 @@ void TextVisual::DoCreateInstancePropertyMap( Property::Map& map ) const TextVisual::TextVisual( VisualFactoryCache& factoryCache ) : Visual::Base( factoryCache ), mController( Text::Controller::New() ), - mTypesetter( Text::Typesetter::New( mController->GetTextModel() ) ), - mAnimatableTextColorPropertyIndex( Property::INVALID_INDEX ), - mRendererUpdateNeeded( false ) + mTypesetter( Text::Typesetter::New( mController->GetTextModel() ) ) { } @@ -372,29 +313,20 @@ void TextVisual::DoSetOnStage( Actor& actor ) mControl = actor; Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY ); - Shader shader = GetTextShader(mFactoryCache, true); - mImpl->mRenderer = Renderer::New( geometry, shader ); - mImpl->mRenderer.SetProperty( Dali::Renderer::Property::DEPTH_INDEX, Toolkit::DepthIndex::CONTENT ); - - const Vector4& defaultColor = mController->GetTextModel()->GetDefaultColor(); - Dali::Property::Index shaderTextColorIndex = mImpl->mRenderer.RegisterProperty( "uTextColorAnimatable", defaultColor ); - - if ( mAnimatableTextColorPropertyIndex != Property::INVALID_INDEX ) + Shader shader = mFactoryCache.GetShader( VisualFactoryCache::TEXT_SHADER ); + if( ! shader ) { - // Create constraint for the animatable text's color Property with uTextColorAnimatable in the renderer. - if( shaderTextColorIndex != Property::INVALID_INDEX ) - { - Constraint constraint = Constraint::New( mImpl->mRenderer, shaderTextColorIndex, EqualToConstraint() ); - constraint.AddSource( Source( actor, mAnimatableTextColorPropertyIndex ) ); - constraint.Apply(); - } + shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_CLAMP ); + shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); + + mFactoryCache.SaveShader( VisualFactoryCache::TEXT_SHADER, shader ); } - // Renderer needs textures and to be added to control - mRendererUpdateNeeded = true; + mImpl->mRenderer = Renderer::New( geometry, shader ); + mImpl->mRenderer.SetProperty( Dali::Renderer::Property::DEPTH_INDEX, Toolkit::DepthIndex::CONTENT ); - UpdateRenderer(); + UpdateRenderer( true ); // Renderer needs textures and to be added to control } void TextVisual::DoSetOffStage( Actor& actor ) @@ -416,7 +348,7 @@ void TextVisual::DoSetOffStage( Actor& actor ) void TextVisual::OnSetTransform() { - UpdateRenderer(); + UpdateRenderer( false ); } void TextVisual::DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue ) @@ -491,20 +423,10 @@ void TextVisual::DoSetProperty( Dali::Property::Index index, const Dali::Propert } break; } - case Toolkit::TextVisual::Property::SHADOW: - { - SetShadowProperties( mController, propertyValue, Text::EffectStyle::DEFAULT ); - break; - } - case Toolkit::TextVisual::Property::UNDERLINE: - { - SetUnderlineProperties( mController, propertyValue, Text::EffectStyle::DEFAULT ); - break; - } } } -void TextVisual::UpdateRenderer() +void TextVisual::UpdateRenderer( bool initializeRendererAndTexture ) { Actor control = mControl.GetHandle(); if( !control ) @@ -541,11 +463,8 @@ void TextVisual::UpdateRenderer() const Text::Controller::UpdateTextType updateTextType = mController->Relayout( relayoutSize ); - if( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) - || mRendererUpdateNeeded ) + if( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) || initializeRendererAndTexture ) { - mRendererUpdateNeeded = false; - // Removes the texture set. RemoveTextureSet(); @@ -558,133 +477,39 @@ void TextVisual::UpdateRenderer() if( ( relayoutSize.width > Math::MACHINE_EPSILON_1000 ) && ( relayoutSize.height > Math::MACHINE_EPSILON_1000 ) ) { - // Check whether it is a markup text with multiple text colors - const Vector4* const colorsBuffer = mController->GetTextModel()->GetColors(); - bool hasMultipleTextColors = ( NULL != colorsBuffer ); - - // Check whether the text contains any emoji - bool containsEmoji = false; - - Text::ScriptRunIndex numberOfScripts = mController->GetTextModel()->GetNumberOfScripts(); - const Text::ScriptRun* scripts = mController->GetTextModel()->GetScriptRuns(); - for ( Text::ScriptRunIndex scriptIndex = 0u; scriptIndex < numberOfScripts; scriptIndex++ ) - { - const Text::ScriptRun& scriptRun = *( scripts + scriptIndex ); - if( TextAbstraction::EMOJI == scriptRun.script ) - { - containsEmoji = true; - break; - } - } - - // Check whether the text contains any style colors (e.g. underline color, shadow color, etc.) - bool shadowEnabled = false; - const Vector2& shadowOffset = mController->GetTextModel()->GetShadowOffset(); - if ( fabsf( shadowOffset.x ) > Math::MACHINE_EPSILON_1 || fabsf( shadowOffset.y ) > Math::MACHINE_EPSILON_1 ) - { - shadowEnabled = true; - } - - const bool underlineEnabled = mController->GetTextModel()->IsUnderlineEnabled(); - - if ( hasMultipleTextColors || containsEmoji || shadowEnabled || underlineEnabled ) - { - // Create RGBA textures if the text contains emojis or styles or multiple text colors - - // Create a texture for the text without any styles - PixelData data = mTypesetter->Render( relayoutSize, Text::Typesetter::RENDER_NO_STYLES ); - - // 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. - - Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D, - data.GetPixelFormat(), - data.GetWidth(), - data.GetHeight() ); - - texture.Upload( data ); - - TextureSet textureSet = TextureSet::New(); - textureSet.SetTexture( 0u, texture ); - - // Create a texture for all the text styles (without the text itself) - PixelData styleData = mTypesetter->Render( relayoutSize, Text::Typesetter::RENDER_NO_TEXT ); + PixelData data = mTypesetter->Render( relayoutSize ); - Texture styleTexture = Texture::New( Dali::TextureType::TEXTURE_2D, - styleData.GetPixelFormat(), - styleData.GetWidth(), - styleData.GetHeight() ); - - styleTexture.Upload( styleData ); - - textureSet.SetTexture( 1u, styleTexture ); - - // Create a texture as a mask to avoid color glyphs (e.g. emojis) to be affected by text color animation - PixelData maskData = mTypesetter->Render( relayoutSize, Text::Typesetter::RENDER_MASK ); - - Texture maskTexture = Texture::New( Dali::TextureType::TEXTURE_2D, - styleData.GetPixelFormat(), - styleData.GetWidth(), - styleData.GetHeight() ); - - maskTexture.Upload( maskData ); - - textureSet.SetTexture( 2u, maskTexture ); - - // Filter mode needs to be set to nearest to produce better quality while static. - Sampler sampler = Sampler::New(); - sampler.SetFilterMode( FilterMode::LINEAR, FilterMode::LINEAR ); - textureSet.SetSampler( 0u, sampler ); - textureSet.SetSampler( 1u, sampler ); - textureSet.SetSampler( 2u, sampler ); - - mImpl->mRenderer.SetTextures( textureSet ); - - Shader shader = GetTextShader(mFactoryCache, true); // RGBA shader - mImpl->mRenderer.SetShader(shader); - } - else - { - // Create L8 texture if the text contains only single text color with no emoji and no style - - // Create a texture for the text without any styles - PixelData data = mTypesetter->Render( relayoutSize, Text::Typesetter::RENDER_NO_STYLES, false, Pixel::L8 ); - - // 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. - - Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D, - data.GetPixelFormat(), - data.GetWidth(), - data.GetHeight() ); + Vector4 atlasRect = FULL_TEXTURE_RECT; - texture.Upload( data ); + // Texture set not retrieved from Atlas Manager whilst pixel offset visible. - TextureSet textureSet = TextureSet::New(); - textureSet.SetTexture( 0u, texture ); + // 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. - // Filter mode needs to be set to nearest to produce better quality while static. - Sampler sampler = Sampler::New(); - sampler.SetFilterMode( FilterMode::NEAREST, FilterMode::NEAREST ); - textureSet.SetSampler( 0u, sampler ); + Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D, + data.GetPixelFormat(), + data.GetWidth(), + data.GetHeight() ); - mImpl->mRenderer.SetTextures( textureSet ); + texture.Upload( data ); - Shader shader = GetTextShader(mFactoryCache, false); // L8 shader - mImpl->mRenderer.SetShader(shader); - } + TextureSet textureSet = TextureSet::New(); + textureSet.SetTexture( 0u, texture ); mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED; - Vector4 atlasRect = FULL_TEXTURE_RECT; mImpl->mRenderer.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, atlasRect ); - mImpl->mRenderer.RegisterProperty( "uHasMultipleTextColors", static_cast( hasMultipleTextColors ) ); - - mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON); //Register transform properties mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT ); + // 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 ); + + mImpl->mRenderer.SetTextures( textureSet ); + control.AddRenderer( mImpl->mRenderer ); // Text rendered and ready to display @@ -712,33 +537,6 @@ void TextVisual::RemoveTextureSet() } } -Shader TextVisual::GetTextShader( VisualFactoryCache& factoryCache, bool isRgbaTexture ) -{ - Shader shader; - if( isRgbaTexture ) - { - shader = factoryCache.GetShader( VisualFactoryCache::TEXT_SHADER_RGBA ); - if( !shader ) - { - shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_CLAMP_RGBA ); - shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); - factoryCache.SaveShader( VisualFactoryCache::TEXT_SHADER_RGBA, shader ); - } - } - else - { - shader = factoryCache.GetShader( VisualFactoryCache::TEXT_SHADER_L8 ); - if( !shader ) - { - shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_CLAMP_L8 ); - shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); - factoryCache.SaveShader( VisualFactoryCache::TEXT_SHADER_L8, shader ); - } - } - - return shader; -} - } // namespace Internal } // namespace Toolkit