} // unnamed namespace
-TextVisualPtr TextVisual::New(VisualFactoryCache& factoryCache, const Property::Map& properties)
+TextVisualPtr TextVisual::New(VisualFactoryCache& factoryCache, TextVisualShaderFactory& shaderFactory, const Property::Map& properties)
{
- TextVisualPtr textVisualPtr(new TextVisual(factoryCache));
+ TextVisualPtr textVisualPtr(new TextVisual(factoryCache, shaderFactory));
textVisualPtr->SetProperties(properties);
textVisualPtr->Initialize();
return textVisualPtr;
}
}
-TextVisual::TextVisual(VisualFactoryCache& factoryCache)
+TextVisual::TextVisual(VisualFactoryCache& factoryCache, TextVisualShaderFactory& shaderFactory)
: Visual::Base(factoryCache, Visual::FittingMode::FIT_KEEP_ASPECT_RATIO, Toolkit::Visual::TEXT),
mController(Text::Controller::New()),
mTypesetter(Text::Typesetter::New(mController->GetTextModel())),
+ mTextVisualShaderFactory(shaderFactory),
+ mTextShaderFeatureCache(),
mAnimatableTextColorPropertyIndex(Property::INVALID_INDEX),
mTextColorAnimatableIndex(Property::INVALID_INDEX),
mRendererUpdateNeeded(false)
void TextVisual::OnInitialize()
{
Geometry geometry = mFactoryCache.GetGeometry(VisualFactoryCache::QUAD_GEOMETRY);
- Shader shader = GetTextShader(mFactoryCache, TextType::SINGLE_COLOR_TEXT, TextType::NO_EMOJI, TextType::NO_STYLES);
+ Shader shader = GetTextShader(mFactoryCache, TextVisualShaderFeature::FeatureBuilder());
mImpl->mRenderer = VisualRenderer::New(geometry, shader);
mImpl->mRenderer.ReserveCustomProperties(CUSTOM_PROPERTY_COUNT);
// Renderer needs textures and to be added to control
mRendererUpdateNeeded = true;
- mRendererList.push_back(mImpl->mRenderer);
-
UpdateRenderer();
}
return pixelData;
}
-void TextVisual::CreateTextureSet(TilingInfo& info, VisualRenderer& renderer, Sampler& sampler, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled, bool isOverlayStyle)
+void TextVisual::CreateTextureSet(TilingInfo& info, VisualRenderer& renderer, Sampler& sampler)
{
TextureSet textureSet = TextureSet::New();
unsigned int textureSetIndex = 0u;
++textureSetIndex;
}
- if(styleEnabled && info.styleBuffer && info.overlayStyleBuffer)
+ if(mTextShaderFeatureCache.IsEnabledStyle() && info.styleBuffer)
{
PixelData styleData = ConvertToPixelData(info.styleBuffer, info.width, info.height, info.offsetPosition, Pixel::RGBA8888);
AddTexture(textureSet, styleData, sampler, textureSetIndex);
++textureSetIndex;
+ }
- // TODO : We need to seperate whether use overlayStyle or not.
- // Current text visual shader required both of them.
-
+ if(mTextShaderFeatureCache.IsEnabledOverlay() && info.overlayStyleBuffer)
+ {
PixelData overlayStyleData = ConvertToPixelData(info.overlayStyleBuffer, info.width, info.height, info.offsetPosition, Pixel::RGBA8888);
AddTexture(textureSet, overlayStyleData, sampler, textureSetIndex);
++textureSetIndex;
}
- if(containsColorGlyph && !hasMultipleTextColors && info.maskBuffer)
+ if(mTextShaderFeatureCache.IsEnabledEmoji() && !mTextShaderFeatureCache.IsEnabledMultiColor() && info.maskBuffer)
{
PixelData maskData = ConvertToPixelData(info.maskBuffer, info.width, info.height, info.offsetPosition, Pixel::L8);
AddTexture(textureSet, maskData, sampler, textureSetIndex);
renderer.SetProperty(VisualRenderer::Property::TRANSFORM_SIZE, Vector2(info.width, info.height));
renderer.SetProperty(VisualRenderer::Property::TRANSFORM_OFFSET, Vector2(info.offSet.x, info.offSet.y));
renderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON);
- renderer.RegisterProperty("uHasMultipleTextColors", static_cast<float>(hasMultipleTextColors));
+ renderer.RegisterProperty("uHasMultipleTextColors", static_cast<float>(mTextShaderFeatureCache.IsEnabledMultiColor()));
mRendererList.push_back(renderer);
}
void TextVisual::AddRenderer(Actor& actor, const Vector2& size, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled, bool isOverlayStyle)
{
- Shader shader = GetTextShader(mFactoryCache, hasMultipleTextColors, containsColorGlyph, styleEnabled);
+ Shader shader = GetTextShader(mFactoryCache, TextVisualShaderFeature::FeatureBuilder().EnableMultiColor(hasMultipleTextColors).EnableEmoji(containsColorGlyph).EnableStyle(styleEnabled).EnableOverlay(isOverlayStyle));
mImpl->mRenderer.SetShader(shader);
// Get the maximum size.
// No tiling required. Use the default renderer.
if(size.height < maxTextureSize)
{
- TextureSet textureSet = GetTextTexture(size, hasMultipleTextColors, containsColorGlyph, styleEnabled, isOverlayStyle);
+ TextureSet textureSet = GetTextTexture(size);
mImpl->mRenderer.SetTextures(textureSet);
//Register transform properties
Dali::DevelPixelData::PixelDataBuffer textPixelData = Dali::DevelPixelData::ReleasePixelDataBuffer(data);
info.textBuffer = textPixelData.buffer;
- if(styleEnabled)
+ if(mTextShaderFeatureCache.IsEnabledStyle())
{
// 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);
Dali::DevelPixelData::PixelDataBuffer stylePixelData = Dali::DevelPixelData::ReleasePixelDataBuffer(styleData);
info.styleBuffer = stylePixelData.buffer;
+ }
- // TODO : We need to seperate whether use overlayStyle or not.
- // Current text visual shader required both of them.
-
+ if(mTextShaderFeatureCache.IsEnabledOverlay())
+ {
// Create RGBA texture for all the overlay styles
PixelData overlayStyleData = mTypesetter->Render(size, textDirection, Text::Typesetter::RENDER_OVERLAY_STYLE, false, Pixel::RGBA8888);
Dali::DevelPixelData::PixelDataBuffer overlayStylePixelData = Dali::DevelPixelData::ReleasePixelDataBuffer(overlayStyleData);
info.overlayStyleBuffer = overlayStylePixelData.buffer;
}
- if(containsColorGlyph && !hasMultipleTextColors)
+ if(mTextShaderFeatureCache.IsEnabledEmoji() && !mTextShaderFeatureCache.IsEnabledMultiColor())
{
// 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);
}
// Create a textureset in the default renderer.
- CreateTextureSet(info, mImpl->mRenderer, sampler, hasMultipleTextColors, containsColorGlyph, styleEnabled, isOverlayStyle);
+ CreateTextureSet(info, mImpl->mRenderer, sampler);
verifiedHeight -= maxTextureSize;
// New offset for tiling.
info.offSet.y += maxTextureSize;
// Create a textureset int the new tiling renderer.
- CreateTextureSet(info, tilingRenderer, sampler, hasMultipleTextColors, containsColorGlyph, styleEnabled, isOverlayStyle);
+ CreateTextureSet(info, tilingRenderer, sampler);
verifiedHeight -= maxTextureSize;
}
mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED;
+ const Vector4& defaultColor = mController->GetTextModel()->GetDefaultColor();
+
for(RendererContainer::iterator iter = mRendererList.begin(); iter != mRendererList.end(); ++iter)
{
Renderer renderer = (*iter);
if(renderer)
{
actor.AddRenderer(renderer);
+
+ if(renderer != mImpl->mRenderer)
+ {
+ // Set constraint for text label's color for non-default renderers.
+ if(mAnimatableTextColorPropertyIndex != Property::INVALID_INDEX)
+ {
+ // Register unique property, or get property for default renderer.
+ Property::Index index = renderer.RegisterUniqueProperty("uTextColorAnimatable", defaultColor);
+
+ // Create constraint for the animatable text's color Property with uTextColorAnimatable in the renderer.
+ if(index != Property::INVALID_INDEX)
+ {
+ Constraint colorConstraint = Constraint::New<Vector4>(renderer, index, TextColorConstraint);
+ colorConstraint.AddSource(Source(actor, mAnimatableTextColorPropertyIndex));
+ colorConstraint.Apply();
+ }
+
+ // Make zero if the alpha value of text color is zero to skip rendering text
+ // VisualRenderer::Property::OPACITY uses same animatable property internally.
+ Constraint opacityConstraint = Constraint::New<float>(renderer, Dali::DevelRenderer::Property::OPACITY, OpacityConstraint);
+ opacityConstraint.AddSource(Source(actor, mAnimatableTextColorPropertyIndex));
+ opacityConstraint.Apply();
+ }
+ }
}
}
}
-TextureSet TextVisual::GetTextTexture(const Vector2& size, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled, bool isOverlayStyle)
+TextureSet TextVisual::GetTextTexture(const Vector2& size)
{
// Filter mode needs to be set to linear to produce better quality while scaling.
Sampler sampler = Sampler::New();
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;
+ Pixel::Format textPixelFormat = (mTextShaderFeatureCache.IsEnabledEmoji() || mTextShaderFeatureCache.IsEnabledMultiColor()) ? Pixel::RGBA8888 : Pixel::L8;
// Check the text direction
Toolkit::DevelText::TextDirection::Type textDirection = mController->GetTextDirection();
AddTexture(textureSet, data, sampler, textureSetIndex);
++textureSetIndex;
- if(styleEnabled)
+ if(mTextShaderFeatureCache.IsEnabledStyle())
{
// Create RGBA texture for all the text styles that render in the background (without the text itself)
PixelData styleData = mTypesetter->Render(size, textDirection, Text::Typesetter::RENDER_NO_TEXT, false, Pixel::RGBA8888);
AddTexture(textureSet, styleData, sampler, textureSetIndex);
++textureSetIndex;
+ }
- // TODO : We need to seperate whether use overlayStyle or not.
- // Current text visual shader required both of them.
-
+ if(mTextShaderFeatureCache.IsEnabledOverlay())
+ {
// Create RGBA texture for overlay styles such as underline and strikethrough (without the text itself)
PixelData overlayStyleData = mTypesetter->Render(size, textDirection, Text::Typesetter::RENDER_OVERLAY_STYLE, false, Pixel::RGBA8888);
AddTexture(textureSet, overlayStyleData, sampler, textureSetIndex);
++textureSetIndex;
}
- if(containsColorGlyph && !hasMultipleTextColors)
+ if(mTextShaderFeatureCache.IsEnabledEmoji() && !mTextShaderFeatureCache.IsEnabledMultiColor())
{
// 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);
return textureSet;
}
-Shader TextVisual::GetTextShader(VisualFactoryCache& factoryCache, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled)
+Shader TextVisual::GetTextShader(VisualFactoryCache& factoryCache, const TextVisualShaderFeature::FeatureBuilder& featureBuilder)
{
- 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(SHADER_TEXT_VISUAL_SHADER_VERT, SHADER_TEXT_VISUAL_MULTI_COLOR_TEXT_SHADER_FRAG);
- 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(SHADER_TEXT_VISUAL_SHADER_VERT, SHADER_TEXT_VISUAL_MULTI_COLOR_TEXT_WITH_STYLE_SHADER_FRAG);
- 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(SHADER_TEXT_VISUAL_SHADER_VERT, SHADER_TEXT_VISUAL_SINGLE_COLOR_TEXT_SHADER_FRAG);
- 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(SHADER_TEXT_VISUAL_SHADER_VERT, SHADER_TEXT_VISUAL_SINGLE_COLOR_TEXT_WITH_STYLE_SHADER_FRAG);
- 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(SHADER_TEXT_VISUAL_SHADER_VERT, SHADER_TEXT_VISUAL_SINGLE_COLOR_TEXT_WITH_EMOJI_SHADER_FRAG);
- 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(SHADER_TEXT_VISUAL_SHADER_VERT, SHADER_TEXT_VISUAL_SINGLE_COLOR_TEXT_WITH_STYLE_AND_EMOJI_SHADER_FRAG);
- shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT);
- factoryCache.SaveShader(VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_EMOJI, shader);
- }
- }
+ // Cache feature builder informations.
+ mTextShaderFeatureCache = featureBuilder;
+ Shader shader = mTextVisualShaderFactory.GetShader(factoryCache, mTextShaderFeatureCache);
+ shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT);
return shader;
}