namespace
{
constexpr uint32_t MAX_UINT32 = std::numeric_limits<uint32_t>::max();
+const float VERTICAL_ALIGNMENT_TABLE[Text::VerticalAlignment::BOTTOM + 1] =
+{
+ 0.0f, // VerticalAlignment::TOP
+ 0.5f, // VerticalAlignment::CENTER
+ 1.0f // VerticalAlignment::BOTTOM
+};
} // namespace
namespace Text
mTextModel->mVisualModel->SetOutlineOffset(parameters.outlineOffset);
}
+ mTextModel->mVisualModel->SetCutoutEnabled(parameters.cutout);
+ mTextModel->mVisualModel->SetBackgroundWithCutoutEnabled(parameters.backgroundWithCutoutEnabled);
+ mTextModel->mVisualModel->SetBackgroundColorWithCutout(parameters.backgroundColorWithCutout);
+
mTextModel->mRemoveFrontInset = parameters.removeFrontInset;
mTextModel->mRemoveBackInset = parameters.removeBackInset;
shadowEnabled = true;
}
- const bool outlineEnabled = mTextModel->GetOutlineWidth() > Math::MACHINE_EPSILON_1;
- const bool backgroundEnabled = mTextModel->IsBackgroundEnabled();
- const bool markupOrSpannedText = parameters.enableMarkup || mTextModel->IsSpannedTextPlaced();
- const bool markupUnderlineEnabled = markupOrSpannedText && mTextModel->IsMarkupUnderlineSet();
- const bool markupStrikethroughEnabled = markupOrSpannedText && mTextModel->IsMarkupStrikethroughSet();
- const bool underlineEnabled = mTextModel->IsUnderlineEnabled() || markupUnderlineEnabled;
- const bool strikethroughEnabled = mTextModel->IsStrikethroughEnabled() || markupStrikethroughEnabled;
- const bool backgroundMarkupSet = mTextModel->IsMarkupBackgroundColorSet();
- const bool styleEnabled = (shadowEnabled || outlineEnabled || backgroundEnabled || markupOrSpannedText || backgroundMarkupSet);
- const bool isOverlayStyle = underlineEnabled || strikethroughEnabled;
+ const bool outlineEnabled = mTextModel->GetOutlineWidth() > Math::MACHINE_EPSILON_1;
+ const bool backgroundEnabled = mTextModel->IsBackgroundEnabled();
+ const bool markupOrSpannedText = parameters.enableMarkup || mTextModel->IsSpannedTextPlaced();
+ const bool markupUnderlineEnabled = markupOrSpannedText && mTextModel->IsMarkupUnderlineSet();
+ const bool markupStrikethroughEnabled = markupOrSpannedText && mTextModel->IsMarkupStrikethroughSet();
+ const bool underlineEnabled = mTextModel->IsUnderlineEnabled() || markupUnderlineEnabled;
+ const bool strikethroughEnabled = mTextModel->IsStrikethroughEnabled() || markupStrikethroughEnabled;
+ const bool backgroundMarkupSet = mTextModel->IsMarkupBackgroundColorSet();
+ const bool cutoutEnabled = mTextModel->IsCutoutEnabled();
+ const bool backgroundWithCutoutEnabled = mTextModel->IsBackgroundWithCutoutEnabled();
+ const bool styleEnabled = (shadowEnabled || outlineEnabled || backgroundEnabled || markupOrSpannedText || backgroundMarkupSet || cutoutEnabled || backgroundWithCutoutEnabled);
+ const bool isOverlayStyle = underlineEnabled || strikethroughEnabled;
// 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 = (containsColorGlyph || hasMultipleTextColors || cutoutEnabled) ? Pixel::RGBA8888 : Pixel::L8;
// The width is the control's width, height is the minimum height of the text.
// This calculated layout size determines the size of the pixel data buffer.
layoutSize.y += outlineWidth * 2.0f;
layoutSize.y = std::min(layoutSize.y, static_cast<float>(parameters.textHeight));
+ if(cutoutEnabled)
+ {
+ // We need to store the offset including padding and vertical alignment.
+ float xOffset = parameters.padding.start;
+ float yOffset = parameters.padding.top + std::round((static_cast<float>(parameters.textHeight) - layoutSize.y) * VERTICAL_ALIGNMENT_TABLE[parameters.verticalAlignment]);
+ mTextModel->mVisualModel->SetOffsetWithCutout(Vector2(xOffset, yOffset));
+
+ // The layout size is set to the text control size including padding.
+ layoutSize.x = static_cast<float>(parameters.textWidth) + (parameters.padding.start + parameters.padding.end);
+ layoutSize.y = static_cast<float>(parameters.textHeight) + (parameters.padding.top + parameters.padding.bottom);
+ }
+
DALI_LOG_RELEASE_INFO("-->AsyncTextLoader::Render ControlSize : %f, %f, LayoutSize : %f, %f\n", static_cast<float>(parameters.textWidth), static_cast<float>(parameters.textHeight), layoutSize.x, layoutSize.y);
// Check the text direction
Toolkit::DevelText::TextDirection::Type textDirection = mIsTextDirectionRTL ? Toolkit::DevelText::TextDirection::RIGHT_TO_LEFT : Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT;
- // Create a pixel data for the text without any styles
- PixelData data = mTypesetter->Render(layoutSize, textDirection, Text::Typesetter::RENDER_NO_STYLES, false, textPixelFormat);
-
// Set information for creating pixel datas.
AsyncTextRenderInfo renderInfo;
renderInfo.width = static_cast<uint32_t>(layoutSize.x);
renderInfo.height = static_cast<uint32_t>(layoutSize.y);
- // Get the pixel data of text.
- renderInfo.textPixelData = data;
-
// Set the direction of text.
renderInfo.isTextDirectionRTL = mIsTextDirectionRTL;
+ Devel::PixelBuffer cutoutData;
+ if(cutoutEnabled)
+ {
+ cutoutData = mTypesetter->RenderWithPixelBuffer(layoutSize, textDirection, Text::Typesetter::RENDER_NO_STYLES, false, textPixelFormat);
+
+ // Make transparent buffer.
+ // If the cutout is enabled, a separate texture is not used for the text.
+ Devel::PixelBuffer buffer = mTypesetter->CreateFullBackgroundBuffer(1, 1, Color::TRANSPARENT);
+ renderInfo.textPixelData = Devel::PixelBuffer::Convert(buffer);
+
+ // Set the flag of cutout.
+ renderInfo.isCutout = cutoutEnabled && (cutoutData != nullptr);
+ }
+ else
+ {
+ // Create a pixel data for the text without any styles
+ renderInfo.textPixelData = mTypesetter->Render(layoutSize, textDirection, Text::Typesetter::RENDER_NO_STYLES, false, textPixelFormat);
+ }
+
if(styleEnabled)
{
- // Create RGBA pixel data for all the text styles (without the text itself)
- renderInfo.stylePixelData = mTypesetter->Render(layoutSize, textDirection, Text::Typesetter::RENDER_NO_TEXT, false, Pixel::RGBA8888);
+ if(renderInfo.isCutout)
+ {
+ float cutoutAlpha = mTextModel->GetDefaultColor().a;
+ renderInfo.stylePixelData = mTypesetter->RenderWithCutout(layoutSize, textDirection, cutoutData, Text::Typesetter::RENDER_NO_TEXT, false, Pixel::RGBA8888, cutoutAlpha);
+ }
+ else
+ {
+ // Create RGBA pixel data for all the text styles (without the text itself)
+ renderInfo.stylePixelData = mTypesetter->Render(layoutSize, textDirection, Text::Typesetter::RENDER_NO_TEXT, false, Pixel::RGBA8888);
+ }
}
if(isOverlayStyle)
{
alignmentOffset.x = 0.0f;
alignmentOffset.y = (static_cast<float>(parameters.textHeight) - layoutSize.y) * VERTICAL_ALIGNMENT_TABLE[parameters.verticalAlignment];
- // This affects font rendering quality.
- // It need to be integerized.
- Vector2 visualTransformOffset;
- visualTransformOffset.x = roundf(parameters.padding.start + alignmentOffset.x);
- visualTransformOffset.y = roundf(parameters.padding.top + alignmentOffset.y);
-
// Size of the text control including padding.
Vector2 textControlSize(static_cast<float>(parameters.textWidth) + (parameters.padding.start + parameters.padding.end), static_cast<float>(parameters.textHeight) + (parameters.padding.top + parameters.padding.bottom));
+ Vector2 visualTransformOffset;
+ if(renderInfo.isCutout)
+ {
+ // When Cutout Enabled, the current visual must draw the entire control.
+ // so set the size to controlSize and offset to 0.
+ visualTransformOffset.x = 0.0f;
+ visualTransformOffset.y = 0.0f;
+
+ // The layout size is set to the text control size including padding.
+ layoutSize = textControlSize;
+ }
+ else
+ {
+ // This affects font rendering quality.
+ // It need to be integerized.
+ visualTransformOffset.x = roundf(parameters.padding.start + alignmentOffset.x);
+ visualTransformOffset.y = roundf(parameters.padding.top + alignmentOffset.y);
+ }
+
// Transform offset is used for subpixel data upload in text tiling.
// We should set the transform before creating a tiling texture.
Property::Map visualTransform;