+TextureSet TextVisual::GetTextTexture( const Vector2& size, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled )
+{
+ // Filter mode needs to be set to linear to produce better quality while scaling.
+ Sampler sampler = Sampler::New();
+ sampler.SetFilterMode( FilterMode::LINEAR, FilterMode::LINEAR );
+
+ TextureSet textureSet = TextureSet::New();
+
+ // Create RGBA texture if the text contains emojis or multiple text colors, otherwise L8 texture
+ Pixel::Format textPixelFormat = ( containsColorGlyph || 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, 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.
+
+ Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D,
+ data.GetPixelFormat(),
+ data.GetWidth(),
+ data.GetHeight() );
+
+ texture.Upload( data );
+
+ textureSet.SetTexture( 0u, texture );
+ textureSet.SetSampler( 0u, sampler );
+
+ if ( styleEnabled )
+ {
+ // Create RGBA texture for all the text styles (without the text itself)
+ PixelData styleData = mTypesetter->Render( size, textDirection, Text::Typesetter::RENDER_NO_TEXT, false, Pixel::RGBA8888 );
+
+ Texture styleTexture = Texture::New( Dali::TextureType::TEXTURE_2D,
+ styleData.GetPixelFormat(),
+ styleData.GetWidth(),
+ styleData.GetHeight() );
+
+ styleTexture.Upload( styleData );
+
+ textureSet.SetTexture( 1u, styleTexture );
+ textureSet.SetSampler( 1u, sampler );
+ }
+
+ if ( containsColorGlyph && !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, textDirection, Text::Typesetter::RENDER_MASK, false, Pixel::L8 );
+
+ Texture maskTexture = Texture::New( Dali::TextureType::TEXTURE_2D,
+ maskData.GetPixelFormat(),
+ maskData.GetWidth(),
+ maskData.GetHeight() );
+
+ maskTexture.Upload( maskData );
+
+ if ( !styleEnabled )
+ {
+ textureSet.SetTexture( 1u, maskTexture );
+ textureSet.SetSampler( 1u, sampler );
+ }
+ else
+ {
+ textureSet.SetTexture( 2u, maskTexture );
+ textureSet.SetSampler( 2u, sampler );
+ }
+ }
+
+ return textureSet;
+}
+
+Shader TextVisual::GetTextShader( VisualFactoryCache& factoryCache, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled )
+{
+ Shader shader;
+
+ if( hasMultipleTextColors && !styleEnabled )
+ {
+ // We don't animate text color if the text contains multiple colors
+ shader = factoryCache.GetShader( VisualFactoryCache::TEXT_SHADER_MULTI_COLOR_TEXT );
+ if( !shader )
+ {
+ shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_MULTI_COLOR_TEXT );
+ shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
+ factoryCache.SaveShader( VisualFactoryCache::TEXT_SHADER_MULTI_COLOR_TEXT, shader );
+ }
+ }
+ else if( hasMultipleTextColors && styleEnabled )
+ {
+ // We don't animate text color if the text contains multiple colors
+ shader = factoryCache.GetShader( VisualFactoryCache::TEXT_SHADER_MULTI_COLOR_TEXT_WITH_STYLE );
+ if( !shader )
+ {
+ shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_MULTI_COLOR_TEXT_WITH_STYLE );
+ shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
+ factoryCache.SaveShader( VisualFactoryCache::TEXT_SHADER_MULTI_COLOR_TEXT_WITH_STYLE, shader );
+ }
+ }
+ else if( !hasMultipleTextColors && !containsColorGlyph && !styleEnabled )
+ {
+ shader = factoryCache.GetShader( VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT );
+ if( !shader )
+ {
+ shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_SINGLE_COLOR_TEXT );
+ shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
+ factoryCache.SaveShader( VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT, shader );
+ }
+ }
+ else if( !hasMultipleTextColors && !containsColorGlyph && styleEnabled )
+ {
+ shader = factoryCache.GetShader( VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE );
+ if( !shader )
+ {
+ shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE );
+ shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
+ factoryCache.SaveShader( VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE, shader );
+ }
+ }
+ else if( !hasMultipleTextColors && containsColorGlyph && !styleEnabled )
+ {
+ shader = factoryCache.GetShader( VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_EMOJI );
+ if( !shader )
+ {
+ shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_SINGLE_COLOR_TEXT_WITH_EMOJI );
+ shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
+ factoryCache.SaveShader( VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_EMOJI, shader );
+ }
+ }
+ else // if( !hasMultipleTextColors && containsColorGlyph && styleEnabled )
+ {
+ shader = factoryCache.GetShader( VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_EMOJI );
+ if( !shader )
+ {
+ shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_EMOJI );
+ shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
+ factoryCache.SaveShader( VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_EMOJI, shader );
+ }
+ }
+
+ return shader;
+}
+