From 38217811ad89debdb195c12f6c059f265fe6d5cd Mon Sep 17 00:00:00 2001 From: Shrouq Sabah Date: Mon, 12 Apr 2021 16:01:32 +0300 Subject: [PATCH] Support Underline to Markup using underlined-character-run Change-Id: I21e5639a75a815204060e5d56c342794e23941ff --- .../src/dali-toolkit-internal/CMakeLists.txt | 1 + .../dali-toolkit-test-utils/toolkit-text-utils.cpp | 3 +- .../dali-toolkit-internal/utc-Dali-Text-Markup.cpp | 3 +- .../utc-Dali-TextEditor-internal.cpp | 39 +++++++++ .../utc-Dali-TextField-internal.cpp | 39 +++++++++ .../utc-Dali-TextLabel-internal.cpp | 69 ++++++++++++++++ dali-toolkit/devel-api/text/text-utils-devel.cpp | 3 +- dali-toolkit/internal/text/logical-model-impl.cpp | 9 +++ dali-toolkit/internal/text/logical-model-impl.h | 2 + dali-toolkit/internal/text/markup-processor.cpp | 34 +++++--- dali-toolkit/internal/text/markup-processor.h | 16 ++-- .../text/rendering/atlas/text-atlas-renderer.cpp | 46 ++++++++--- .../internal/text/rendering/text-typesetter.cpp | 47 +++++++++++ .../internal/text/rendering/text-typesetter.h | 21 +++++ .../internal/text/rendering/view-model.cpp | 5 ++ dali-toolkit/internal/text/rendering/view-model.h | 5 ++ .../internal/text/text-controller-impl.cpp | 92 +++++++++++++++++++--- dali-toolkit/internal/text/text-controller-impl.h | 7 ++ .../internal/text/text-controller-text-updater.cpp | 3 +- dali-toolkit/internal/text/text-controller.cpp | 2 + dali-toolkit/internal/text/text-model-interface.h | 7 ++ dali-toolkit/internal/text/text-model.cpp | 5 ++ dali-toolkit/internal/text/text-model.h | 5 ++ .../internal/text/underlined-character-run.h | 51 ++++++++++++ dali-toolkit/internal/text/visual-model-impl.cpp | 13 ++- dali-toolkit/internal/text/visual-model-impl.h | 15 ++++ dali-toolkit/internal/visuals/text/text-visual.cpp | 10 +-- 27 files changed, 507 insertions(+), 45 deletions(-) create mode 100755 automated-tests/src/dali-toolkit-internal/utc-Dali-TextLabel-internal.cpp create mode 100644 dali-toolkit/internal/text/underlined-character-run.h diff --git a/automated-tests/src/dali-toolkit-internal/CMakeLists.txt b/automated-tests/src/dali-toolkit-internal/CMakeLists.txt index cc18fe6..1162266 100755 --- a/automated-tests/src/dali-toolkit-internal/CMakeLists.txt +++ b/automated-tests/src/dali-toolkit-internal/CMakeLists.txt @@ -30,6 +30,7 @@ SET(TC_SOURCES utc-Dali-Text-ViewModel.cpp utc-Dali-TextField-internal.cpp utc-Dali-TextEditor-internal.cpp + utc-Dali-TextLabel-internal.cpp utc-Dali-TextSelectionPopup-internal.cpp utc-Dali-TextureManager.cpp utc-Dali-Visuals-internal.cpp diff --git a/automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/toolkit-text-utils.cpp b/automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/toolkit-text-utils.cpp index d98f397..1e745b1 100755 --- a/automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/toolkit-text-utils.cpp +++ b/automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/toolkit-text-utils.cpp @@ -109,7 +109,8 @@ void CreateTextModel( const std::string& text, MarkupProcessData markupProcessData( logicalModel->mColorRuns, logicalModel->mFontDescriptionRuns, logicalModel->mEmbeddedItems, - logicalModel->mAnchors ); + logicalModel->mAnchors, + logicalModel->mUnderlinedCharacterRuns); Length textSize = 0u; const uint8_t* utf8 = NULL; diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Markup.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Markup.cpp index 6e2d632..f46c401 100755 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Markup.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Markup.cpp @@ -185,7 +185,8 @@ namespace Vector fontRuns; Vector items; Vector anchors; - MarkupProcessData markupProcessData( colorRuns, fontRuns, items, anchors ); + Vector underlinedCharacterRuns; + MarkupProcessData markupProcessData( colorRuns, fontRuns, items, anchors, underlinedCharacterRuns ); ProcessMarkupString( data.xHTMLEntityString, markupProcessData ); for( Vector::Iterator it = items.Begin(), diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-TextEditor-internal.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-TextEditor-internal.cpp index 9445be6..ca724ff 100755 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-TextEditor-internal.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-TextEditor-internal.cpp @@ -70,3 +70,42 @@ int UtcDaliTextEditorSelectText(void) END_TEST; } + +int UtcDaliTextEditorMarkupUnderline(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliTextEditorMarkupUnderline "); + + TextEditor textEditor = TextEditor::New(); + + application.GetScene().Add( textEditor ); + + textEditor.SetProperty( TextEditor::Property::TEXT, "ABCEFGH" ); + textEditor.SetProperty( TextEditor ::Property::ENABLE_MARKUP, true ); + + application.SendNotification(); + application.Render(); + + uint32_t expectedNumberOfUnderlinedGlyphs = 5u; + + Toolkit::Internal::TextEditor& textEditorImpl = GetImpl( textEditor ); + const Text::Length numberOfUnderlineRuns = textEditorImpl.getController()->GetTextModel()->GetNumberOfUnderlineRuns(); + + DALI_TEST_EQUALS( numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION ); + + Vector underlineRuns; + underlineRuns.Resize(numberOfUnderlineRuns); + textEditorImpl.getController()->GetTextModel()->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns); + + //ABC are underlined + DALI_TEST_EQUALS( underlineRuns[0u].glyphIndex, 0u, TEST_LOCATION); + DALI_TEST_EQUALS( underlineRuns[1u].glyphIndex, 1u, TEST_LOCATION); + DALI_TEST_EQUALS( underlineRuns[2u].glyphIndex, 2u, TEST_LOCATION); + + //GH are underlined + DALI_TEST_EQUALS( underlineRuns[3u].glyphIndex, 5u, TEST_LOCATION); + DALI_TEST_EQUALS( underlineRuns[4u].glyphIndex, 6u, TEST_LOCATION); + + END_TEST; + +} \ No newline at end of file diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-TextField-internal.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-TextField-internal.cpp index 37d54e1..1d899d9 100755 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-TextField-internal.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-TextField-internal.cpp @@ -152,3 +152,42 @@ int UtcDaliTextFieldSelectText(void) END_TEST; } + +int UtcDaliTextFieldMarkupUnderline(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliTextFieldMarkupUnderline "); + + TextField textField = TextField::New(); + + application.GetScene().Add( textField ); + + textField.SetProperty( TextField::Property::TEXT, "ABCEFGH" ); + textField.SetProperty( TextField ::Property::ENABLE_MARKUP, true ); + + application.SendNotification(); + application.Render(); + + uint32_t expectedNumberOfUnderlinedGlyphs = 5u; + + Toolkit::Internal::TextField& textFieldImpl = GetImpl( textField ); + const Text::Length numberOfUnderlineRuns = textFieldImpl.getController()->GetTextModel()->GetNumberOfUnderlineRuns(); + + DALI_TEST_EQUALS( numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION ); + + Vector underlineRuns; + underlineRuns.Resize(numberOfUnderlineRuns); + textFieldImpl.getController()->GetTextModel()->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns); + + //ABC are underlined + DALI_TEST_EQUALS( underlineRuns[0u].glyphIndex, 0u, TEST_LOCATION); + DALI_TEST_EQUALS( underlineRuns[1u].glyphIndex, 1u, TEST_LOCATION); + DALI_TEST_EQUALS( underlineRuns[2u].glyphIndex, 2u, TEST_LOCATION); + + //GH are underlined + DALI_TEST_EQUALS( underlineRuns[3u].glyphIndex, 5u, TEST_LOCATION); + DALI_TEST_EQUALS( underlineRuns[4u].glyphIndex, 6u, TEST_LOCATION); + + END_TEST; + +} \ No newline at end of file diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-TextLabel-internal.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-TextLabel-internal.cpp new file mode 100755 index 0000000..e85ea21 --- /dev/null +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-TextLabel-internal.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include + +#include +#include + +#include +#include +#include + +using namespace Dali; +using namespace Toolkit; +using namespace Text; + +int UtcDaliTextLabelMarkupUnderline(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliTextLabelMarkupUnderline "); + + TextLabel textLabel = TextLabel::New(); + + application.GetScene().Add( textLabel ); + + textLabel.SetProperty( TextLabel::Property::TEXT, "ABCEFGH" ); + textLabel.SetProperty( TextLabel ::Property::ENABLE_MARKUP, true ); + + application.SendNotification(); + application.Render(); + + uint32_t expectedNumberOfUnderlinedGlyphs = 5u; + + Toolkit::Internal::TextLabel& textLabelImpl = GetImpl( textLabel ); + const Text::Length numberOfUnderlineRuns = textLabelImpl.getController()->GetTextModel()->GetNumberOfUnderlineRuns(); + + DALI_TEST_EQUALS( numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION ); + + Vector underlineRuns; + underlineRuns.Resize(numberOfUnderlineRuns); + textLabelImpl.getController()->GetTextModel()->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns); + + //ABC are underlined + DALI_TEST_EQUALS( underlineRuns[0u].glyphIndex, 0u, TEST_LOCATION); + DALI_TEST_EQUALS( underlineRuns[1u].glyphIndex, 1u, TEST_LOCATION); + DALI_TEST_EQUALS( underlineRuns[2u].glyphIndex, 2u, TEST_LOCATION); + + //GH are underlined + DALI_TEST_EQUALS( underlineRuns[3u].glyphIndex, 5u, TEST_LOCATION); + DALI_TEST_EQUALS( underlineRuns[4u].glyphIndex, 6u, TEST_LOCATION); + + END_TEST; + +} \ No newline at end of file diff --git a/dali-toolkit/devel-api/text/text-utils-devel.cpp b/dali-toolkit/devel-api/text/text-utils-devel.cpp index 1441dc4..787cc0f 100644 --- a/dali-toolkit/devel-api/text/text-utils-devel.cpp +++ b/dali-toolkit/devel-api/text/text-utils-devel.cpp @@ -173,7 +173,8 @@ void ShapeTextPreprocess(const RendererParameters& textParameters, TextAbstracti MarkupProcessData markupProcessData(colorRuns, fontDescriptionRuns, textModel->mLogicalModel->mEmbeddedItems, - textModel->mLogicalModel->mAnchors); + textModel->mLogicalModel->mAnchors, + textModel->mLogicalModel->mUnderlinedCharacterRuns); if(textParameters.markupEnabled) { diff --git a/dali-toolkit/internal/text/logical-model-impl.cpp b/dali-toolkit/internal/text/logical-model-impl.cpp index 12929fc..0de63d5 100644 --- a/dali-toolkit/internal/text/logical-model-impl.cpp +++ b/dali-toolkit/internal/text/logical-model-impl.cpp @@ -296,6 +296,15 @@ void LogicalModel::UpdateTextStyleRuns(CharacterIndex index, int numberOfCharact mColorRuns, removedColorRuns); + // This is needed until now for underline tag in mark-up processor + // Process the underlined runs. + Vector removedUnderlinedCharacterRuns; + UpdateCharacterRuns(index, + numberOfCharacters, + totalNumberOfCharacters, + mUnderlinedCharacterRuns, + removedUnderlinedCharacterRuns); + // Process the background color runs. Vector removedBackgroundColorRuns; UpdateCharacterRuns(index, diff --git a/dali-toolkit/internal/text/logical-model-impl.h b/dali-toolkit/internal/text/logical-model-impl.h index 921d911..80a1285 100644 --- a/dali-toolkit/internal/text/logical-model-impl.h +++ b/dali-toolkit/internal/text/logical-model-impl.h @@ -33,6 +33,7 @@ #include #include #include +#include namespace Dali { @@ -219,6 +220,7 @@ public: Vector mBidirectionalLineInfo; Vector mEmbeddedItems; Vector mAnchors; + Vector mUnderlinedCharacterRuns; ///< The underlined character run from markup-processor BidirectionalLineRunIndex mBidirectionalLineIndex; ///< The last fetched bidirectional line info. }; diff --git a/dali-toolkit/internal/text/markup-processor.cpp b/dali-toolkit/internal/text/markup-processor.cpp index a8a6ecc..ea7f869 100644 --- a/dali-toolkit/internal/text/markup-processor.cpp +++ b/dali-toolkit/internal/text/markup-processor.cpp @@ -156,6 +156,17 @@ void Initialize(ColorRun& colorRun) } /** + * @brief Initializes a underlined character run to its defaults. + * + * @param[in,out] underlinedCharacterRun The underelined character run to initialize. + */ +void Initialize(UnderlinedCharacterRun& underlinedCharacterRun) +{ + underlinedCharacterRun.characterRun.characterIndex = 0u; + underlinedCharacterRun.characterRun.numberOfCharacters = 0u; +} + +/** * @brief Splits the tag string into the tag name and its attributes. * * The attributes are stored in a vector in the tag. @@ -498,9 +509,9 @@ bool XHTMLNumericEntityToUtf8(const char* markupText, char* utf8) } /** - * @brief Processes a particular tag for the required run (color-run or font-run). + * @brief Processes a particular tag for the required run (color-run, font-run or underlined-character-run). * - * @tparam RunType Whether ColorRun or FontDescriptionRun + * @tparam RunType Whether ColorRun , FontDescriptionRun or UnderlinedCharacterRun * * @param[in/out] runsContainer The container containing all the runs * @param[in/out] styleStack The style stack @@ -619,11 +630,13 @@ void ProcessAnchorTag( * @param[in/out] markupProcessData The markup process data * @param[in] fontRunIndex The font run index * @param[in] colorRunIndex The color run index + * @param[in] underlinedCharacterRunIndex The underlined character run index */ -void ResizeModelVectors(MarkupProcessData& markupProcessData, const StyleStack::RunIndex fontRunIndex, const StyleStack::RunIndex colorRunIndex) +void ResizeModelVectors(MarkupProcessData& markupProcessData, const StyleStack::RunIndex fontRunIndex, const StyleStack::RunIndex colorRunIndex, const StyleStack::RunIndex underlinedCharacterRunIndex) { markupProcessData.fontRuns.Resize(fontRunIndex); markupProcessData.colorRuns.Resize(colorRunIndex); + markupProcessData.underlinedCharacterRuns.Resize(underlinedCharacterRunIndex); #ifdef DEBUG_ENABLED for(unsigned int i = 0; i < colorRunIndex; ++i) @@ -740,18 +753,21 @@ void ProcessMarkupString(const std::string& markupString, MarkupProcessData& mar StyleStack styleStack; // Points the next free position in the vector of runs. - StyleStack::RunIndex colorRunIndex = 0u; - StyleStack::RunIndex fontRunIndex = 0u; + StyleStack::RunIndex colorRunIndex = 0u; + StyleStack::RunIndex fontRunIndex = 0u; + StyleStack::RunIndex underlinedCharacterRunIndex = 0u; // check tag reference int colorTagReference = 0u; int fontTagReference = 0u; int iTagReference = 0u; int bTagReference = 0u; + int uTagReference = 0u; // Give an initial default value to the model's vectors. markupProcessData.colorRuns.Reserve(DEFAULT_VECTOR_SIZE); markupProcessData.fontRuns.Reserve(DEFAULT_VECTOR_SIZE); + markupProcessData.underlinedCharacterRuns.Reserve(DEFAULT_VECTOR_SIZE); // Get the mark-up string buffer. const char* markupStringBuffer = markupString.c_str(); @@ -781,9 +797,9 @@ void ProcessMarkupString(const std::string& markupString, MarkupProcessData& mar } // else if(TokenComparison(XHTML_U_TAG, tag.buffer, tag.length)) { - // TODO: If !tag.isEndTag, then create a new underline run. - // else Pop the top of the stack and set the number of characters of the run. - } // + ProcessTagForRun( + markupProcessData.underlinedCharacterRuns, styleStack, tag, characterIndex, underlinedCharacterRunIndex, uTagReference, [](const Tag& tag, UnderlinedCharacterRun& run) { }); + } // else if(TokenComparison(XHTML_B_TAG, tag.buffer, tag.length)) { ProcessTagForRun( @@ -836,7 +852,7 @@ void ProcessMarkupString(const std::string& markupString, MarkupProcessData& mar } // Resize the model's vectors. - ResizeModelVectors(markupProcessData, fontRunIndex, colorRunIndex); + ResizeModelVectors(markupProcessData, fontRunIndex, colorRunIndex, underlinedCharacterRunIndex); } } // namespace Text diff --git a/dali-toolkit/internal/text/markup-processor.h b/dali-toolkit/internal/text/markup-processor.h index c75ca0c..ec45957 100644 --- a/dali-toolkit/internal/text/markup-processor.h +++ b/dali-toolkit/internal/text/markup-processor.h @@ -27,6 +27,7 @@ #include #include #include +#include namespace Dali { @@ -42,20 +43,23 @@ struct MarkupProcessData MarkupProcessData(Vector& colorRuns, Vector& fontRuns, Vector& items, - Vector& anchors) + Vector& anchors, + Vector& underlinedCharacterRuns) : colorRuns(colorRuns), fontRuns(fontRuns), items(items), anchors(anchors), + underlinedCharacterRuns(underlinedCharacterRuns), markupProcessedText() { } - Vector& colorRuns; ///< The color runs. - Vector& fontRuns; ///< The font description runs. - Vector& items; ///< The embedded items. - Vector& anchors; ///< The anchors. - std::string markupProcessedText; ///< The mark-up string. + Vector& colorRuns; ///< The color runs. + Vector& fontRuns; ///< The font description runs. + Vector& items; ///< The embedded items. + Vector& anchors; ///< The anchors. + Vector& underlinedCharacterRuns; ///< The underlined character runs. + std::string markupProcessedText; ///< The mark-up string. }; /** diff --git a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp index 208460c..7b51d5b 100644 --- a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp +++ b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp @@ -85,7 +85,8 @@ struct AtlasRenderer::Impl mRight(0.0f), mUnderlinePosition(0.0f), mUnderlineThickness(0.0f), - mMeshRecordIndex(0u) + mMeshRecordIndex(0u), + mUnderlineChunkId(0u) { } @@ -95,6 +96,7 @@ struct AtlasRenderer::Impl float mUnderlinePosition; float mUnderlineThickness; uint32_t mMeshRecordIndex; + uint32_t mUnderlineChunkId; }; struct MaxBlockSize @@ -288,7 +290,8 @@ struct AtlasRenderer::Impl float currentUnderlineThickness, std::vector& meshContainer, Vector& newTextCache, - Vector& extents) + Vector& extents, + uint32_t underlineChunkId) { // Generate mesh data for this quad, plugging in our supplied position AtlasManager::Mesh2D newMesh; @@ -324,7 +327,8 @@ struct AtlasRenderer::Impl underlineGlyph, currentUnderlinePosition, currentUnderlineThickness, - slot); + slot, + underlineChunkId); } void CreateActors(const std::vector& meshContainer, @@ -458,6 +462,10 @@ struct AtlasRenderer::Impl const Vector2* const positionsBuffer = positions.Begin(); const Vector2 lineOffsetPosition(minLineOffset, 0.f); + //For septated underlined chunks. (this is for Markup case) + uint32_t underlineChunkId = 0u; // give id for each chunk. + bool isPreUnderlined = false; // status of underlined for previous glyph. + for(uint32_t i = 0, glyphSize = glyphs.Size(); i < glyphSize; ++i) { const GlyphInfo& glyph = *(glyphsBuffer + i); @@ -504,6 +512,7 @@ struct AtlasRenderer::Impl } lastUnderlinedFontId = glyph.fontId; + } // underline AtlasGlyphManager::GlyphStyle style; @@ -548,7 +557,8 @@ struct AtlasRenderer::Impl currentUnderlineThickness, meshContainer, newTextCache, - extents); + extents, + underlineChunkId); lastFontId = glyph.fontId; // Prevents searching for existing blocksizes when string of the same fontId. } @@ -565,8 +575,19 @@ struct AtlasRenderer::Impl currentUnderlineThickness, meshContainerOutline, newTextCache, - extents); + extents, + 0u); + } + + + //The new underlined chunk. Add new id if they are not consecutive indices (this is for Markup case) + // Examples: "Hello World Hello World", "World Hello World", " World Hello World" + if( isPreUnderlined && (isPreUnderlined != isGlyphUnderlined)) + { + underlineChunkId++; } + //Keep status of underlined for previous glyph to check consecutive indices + isPreUnderlined = isGlyphUnderlined; } } // glyphs @@ -717,7 +738,8 @@ struct AtlasRenderer::Impl bool underlineGlyph, float underlinePosition, float underlineThickness, - AtlasManager::AtlasSlot& slot) + AtlasManager::AtlasSlot& slot, + uint32_t underlineChunkId) { if(slot.mImageId) { @@ -745,7 +767,8 @@ struct AtlasRenderer::Impl right, baseLine, underlinePosition, - underlineThickness); + underlineThickness, + underlineChunkId); } return; @@ -768,7 +791,8 @@ struct AtlasRenderer::Impl right, baseLine, underlinePosition, - underlineThickness); + underlineThickness, + underlineChunkId); } } } @@ -780,7 +804,8 @@ struct AtlasRenderer::Impl float right, float baseLine, float underlinePosition, - float underlineThickness) + float underlineThickness, + uint32_t underlineChunkId) { bool foundExtent = false; for(Vector::Iterator eIt = extents.Begin(), @@ -788,7 +813,7 @@ struct AtlasRenderer::Impl eIt != eEndIt; ++eIt) { - if(Equals(baseLine, eIt->mBaseLine)) + if(Equals(baseLine, eIt->mBaseLine) && underlineChunkId == eIt->mUnderlineChunkId) { foundExtent = true; if(left < eIt->mLeft) @@ -819,6 +844,7 @@ struct AtlasRenderer::Impl extent.mUnderlinePosition = underlinePosition; extent.mUnderlineThickness = underlineThickness; extent.mMeshRecordIndex = index; + extent.mUnderlineChunkId = underlineChunkId; extents.PushBack(extent); } } diff --git a/dali-toolkit/internal/text/rendering/text-typesetter.cpp b/dali-toolkit/internal/text/rendering/text-typesetter.cpp index abf7325..60888db 100644 --- a/dali-toolkit/internal/text/rendering/text-typesetter.cpp +++ b/dali-toolkit/internal/text/rendering/text-typesetter.cpp @@ -595,6 +595,11 @@ PixelData Typesetter::Render(const Vector2& size, Toolkit::DevelText::TextDirect // Combine the two buffers imageBuffer = CombineImageBuffer(imageBuffer, backgroundImageBuffer, bufferWidth, bufferHeight); } + + // Markup-Processor + + imageBuffer = ApplyMarkupProcessorOnPixelBuffer(imageBuffer, bufferWidth, bufferHeight, ignoreHorizontalAlignment, pixelFormat, penX, penY); + } // Create the final PixelData for the combined image buffer @@ -906,6 +911,48 @@ Devel::PixelBuffer Typesetter::CombineImageBuffer(Devel::PixelBuffer topPixelBuf return combinedPixelBuffer; } +Devel::PixelBuffer Typesetter::ApplyMarkupProcessorOnPixelBuffer(Devel::PixelBuffer topPixelBuffer, const unsigned int bufferWidth, const unsigned int bufferHeight, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat, int horizontalOffset, int verticalOffset) +{ + // Apply the markup-Processor if enabled + const bool markupProcessorEnabled = mModel->IsMarkupProcessorEnabled(); + if(markupProcessorEnabled) + { + // Underline-tags (this is for Markup case) + // Get the underline runs. + const Length numberOfUnderlineRuns = mModel->GetNumberOfUnderlineRuns(); + Vector underlineRuns; + underlineRuns.Resize(numberOfUnderlineRuns); + mModel->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns); + + // Iterate on the consecutive underlined glyph run and connect them into one chunk of underlined characters. + Vector::ConstIterator itGlyphRun = underlineRuns.Begin(); + Vector::ConstIterator endItGlyphRun = underlineRuns.End(); + GlyphIndex startGlyphIndex, endGlyphIndex; + + //The outer loop to iterate on the separated chunks of underlined glyph runs + while(itGlyphRun != endItGlyphRun) + { + startGlyphIndex = itGlyphRun->glyphIndex; + endGlyphIndex = startGlyphIndex; + //The inner loop to make a connected underline for the consecutive characters + do + { + endGlyphIndex += itGlyphRun->numberOfGlyphs; + itGlyphRun++; + } while(itGlyphRun != endItGlyphRun && itGlyphRun->glyphIndex == endGlyphIndex); + + endGlyphIndex--; + + // Create the image buffer for underline + Devel::PixelBuffer underlineImageBuffer = CreateImageBuffer(bufferWidth, bufferHeight, Typesetter::STYLE_UNDERLINE, ignoreHorizontalAlignment, pixelFormat, horizontalOffset, verticalOffset, startGlyphIndex, endGlyphIndex); + // Combine the two buffers + topPixelBuffer = CombineImageBuffer(topPixelBuffer, underlineImageBuffer, bufferWidth, bufferHeight); + } + } + + return topPixelBuffer; +} + Typesetter::Typesetter(const ModelInterface* const model) : mModel(new ViewModel(model)) { diff --git a/dali-toolkit/internal/text/rendering/text-typesetter.h b/dali-toolkit/internal/text/rendering/text-typesetter.h index 2f29a47..c9cd4cc 100644 --- a/dali-toolkit/internal/text/rendering/text-typesetter.h +++ b/dali-toolkit/internal/text/rendering/text-typesetter.h @@ -163,6 +163,27 @@ private: */ Devel::PixelBuffer CombineImageBuffer(Devel::PixelBuffer topPixelBuffer, Devel::PixelBuffer bottomPixelBuffer, const unsigned int bufferWidth, const unsigned int bufferHeightbool); + /** + * @brief Apply behaviour of tags if the markup-processor is enabled. + * + * The properties on TextLabel override the behavior of Markup. + * Because the markup will be the bottom layer buffer + * - i.e: If you set property UNDERLINE to enabled and blue. + * And the TEXT is "Hello World Hello World". + * Then the output of the whole text is underlined by blue line. + * + * @param[in] topPixelBuffer The top layer buffer. + * @param[in] bufferWidth The width of the image buffer. + * @param[in] bufferHeight The height of the image buffer. + * @param[in] ignoreHorizontalAlignment Whether to ignore the horizontal alignment, not ignored by default. + * @param[in] pixelFormat The format of the pixel in the image that the text is rendered as (i.e. either Pixel::BGRA8888 or Pixel::L8). + * @param[in] horizontalOffset The horizontal offset to be added to the glyph's position. + * @param[in] verticalOffset The vertical offset to be added to the glyph's position. + * + * @return The image buffer with the markup. + */ + Devel::PixelBuffer ApplyMarkupProcessorOnPixelBuffer(Devel::PixelBuffer topPixelBuffer, const unsigned int bufferWidth, const unsigned int bufferHeight, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat, int horizontalOffset, int verticalOffset); + protected: /** * @brief A reference counted object may only be deleted by calling Unreference(). diff --git a/dali-toolkit/internal/text/rendering/view-model.cpp b/dali-toolkit/internal/text/rendering/view-model.cpp index e7b40a5..2ad03c5 100644 --- a/dali-toolkit/internal/text/rendering/view-model.cpp +++ b/dali-toolkit/internal/text/rendering/view-model.cpp @@ -225,6 +225,11 @@ bool ViewModel::IsBackgroundEnabled() const return mModel->IsBackgroundEnabled(); } +bool ViewModel::IsMarkupProcessorEnabled() const +{ + return mModel->IsMarkupProcessorEnabled(); +} + void ViewModel::ElideGlyphs() { mIsTextElided = false; diff --git a/dali-toolkit/internal/text/rendering/view-model.h b/dali-toolkit/internal/text/rendering/view-model.h index a84810a..1ea38ee 100644 --- a/dali-toolkit/internal/text/rendering/view-model.h +++ b/dali-toolkit/internal/text/rendering/view-model.h @@ -211,6 +211,11 @@ public: bool IsBackgroundEnabled() const override; /** + * @copydoc ModelInterface::IsMarkupProcessorEnabled() + */ + bool IsMarkupProcessorEnabled() const override; + + /** * @brief Does the text elide. * * It stores a copy of the visible glyphs and removes as many glyphs as needed diff --git a/dali-toolkit/internal/text/text-controller-impl.cpp b/dali-toolkit/internal/text/text-controller-impl.cpp index ec00903..8140c84 100644 --- a/dali-toolkit/internal/text/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/text-controller-impl.cpp @@ -587,7 +587,7 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired) Vector& srcCharacters = mModel->mLogicalModel->mText; Vector displayCharacters; bool useHiddenText = false; - if(mHiddenInput && mEventData != NULL && !mEventData->mIsShowingPlaceholderText) + if(mHiddenInput && mEventData != nullptr && !mEventData->mIsShowingPlaceholderText) { mHiddenInput->Substitute(srcCharacters, displayCharacters); useHiddenText = true; @@ -697,7 +697,7 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired) TextAbstraction::FontDescription defaultFontDescription; TextAbstraction::PointSize26Dot6 defaultPointSize = TextAbstraction::FontClient::DEFAULT_POINT_SIZE * mFontSizeScale; - if(IsShowingPlaceholderText() && mEventData && (NULL != mEventData->mPlaceholderFont)) + if(IsShowingPlaceholderText() && mEventData && (nullptr != mEventData->mPlaceholderFont)) { // If the placeholder font is set specifically, only placeholder font is changed. defaultFontDescription = mEventData->mPlaceholderFont->mFontDescription; @@ -706,7 +706,7 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired) defaultPointSize = mEventData->mPlaceholderFont->mDefaultPointSize * mFontSizeScale * 64u; } } - else if(NULL != mFontDefaults) + else if(nullptr != mFontDefaults) { // Set the normal font and the placeholder font. defaultFontDescription = mFontDefaults->mFontDescription; @@ -807,7 +807,8 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired) // Create the 'number of glyphs' per character and the glyph to character conversion tables. mModel->mVisualModel->CreateGlyphsPerCharacterTable(startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters); mModel->mVisualModel->CreateCharacterToGlyphTable(startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters); - updated = true; + + updated = true; } const Length numberOfGlyphs = glyphs.Count() - currentNumberOfGlyphs; @@ -830,7 +831,7 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired) updated = true; } - if((NULL != mEventData) && + if((nullptr != mEventData) && mEventData->mPreEditFlag && (0u != mModel->mVisualModel->mCharactersToGlyph.Count())) { @@ -858,6 +859,12 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired) underlineRun.glyphIndex = attrData.startIndex + numberOfCommit; underlineRun.numberOfGlyphs = numberOfIndices; mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun); + + //Mark-up processor case + if(mModel->mVisualModel->IsMarkupProcessorEnabled()) + { + CopyUnderlinedFromLogicalToVisualModels(false); + } break; } case Dali::InputMethodContext::PreeditStyle::REVERSE: @@ -902,6 +909,12 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired) underlineRun.glyphIndex = attrData.startIndex + numberOfCommit; underlineRun.numberOfGlyphs = numberOfIndices; mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun); + + //Mark-up processor case + if(mModel->mVisualModel->IsMarkupProcessorEnabled()) + { + CopyUnderlinedFromLogicalToVisualModels(false); + } break; } case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_2: @@ -917,6 +930,12 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired) underlineRun.glyphIndex = attrData.startIndex + numberOfCommit; underlineRun.numberOfGlyphs = numberOfIndices; mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun); + + //Mark-up processor case + if(mModel->mVisualModel->IsMarkupProcessorEnabled()) + { + CopyUnderlinedFromLogicalToVisualModels(false); + } break; } case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_3: @@ -932,6 +951,12 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired) underlineRun.glyphIndex = attrData.startIndex + numberOfCommit; underlineRun.numberOfGlyphs = numberOfIndices; mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun); + + //Mark-up processor case + if(mModel->mVisualModel->IsMarkupProcessorEnabled()) + { + CopyUnderlinedFromLogicalToVisualModels(false); + } break; } case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_4: @@ -947,6 +972,12 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired) underlineRun.glyphIndex = attrData.startIndex + numberOfCommit; underlineRun.numberOfGlyphs = numberOfIndices; mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun); + + //Mark-up processor case + if(mModel->mVisualModel->IsMarkupProcessorEnabled()) + { + CopyUnderlinedFromLogicalToVisualModels(false); + } break; } case Dali::InputMethodContext::PreeditStyle::NONE: @@ -985,6 +1016,21 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired) updated = true; } + if((NO_OPERATION != (SHAPE_TEXT & operations)) && + ! ((nullptr != mEventData) && + mEventData->mPreEditFlag && + (0u != mModel->mVisualModel->mCharactersToGlyph.Count()))) + { + //Mark-up processor case + if(mModel->mVisualModel->IsMarkupProcessorEnabled()) + { + CopyUnderlinedFromLogicalToVisualModels(true); + } + + updated = true; + } + + // The estimated number of lines. Used to avoid reallocations when layouting. mTextUpdateInfo.mEstimatedNumberOfLines = std::max(mModel->mVisualModel->mLines.Count(), mModel->mLogicalModel->mParagraphInfo.Count()); @@ -1064,7 +1110,7 @@ void Controller::Impl::RetrieveDefaultInputStyle(InputStyle& inputStyle) float Controller::Impl::GetDefaultFontLineHeight() { FontId defaultFontId = 0u; - if(NULL == mFontDefaults) + if(nullptr == mFontDefaults) { TextAbstraction::FontDescription fontDescription; defaultFontId = mFontClient.GetFontId(fontDescription, TextAbstraction::FontClient::DEFAULT_POINT_SIZE * mFontSizeScale); @@ -1384,7 +1430,7 @@ void Controller::Impl::SetPopupButtons() void Controller::Impl::ChangeState(EventData::State newState) { - if(NULL == mEventData) + if(nullptr == mEventData) { // Nothing to do if there is no text input. return; @@ -1700,7 +1746,7 @@ void Controller::Impl::GetCursorPosition(CharacterIndex logical, CharacterIndex Controller::Impl::CalculateNewCursorIndex(CharacterIndex index) const { - if(NULL == mEventData) + if(nullptr == mEventData) { // Nothing to do if there is no text input. return 0u; @@ -1750,7 +1796,7 @@ CharacterIndex Controller::Impl::CalculateNewCursorIndex(CharacterIndex index) c void Controller::Impl::UpdateCursorPosition(const CursorInfo& cursorInfo) { DALI_LOG_INFO(gLogFilter, Debug::Verbose, "-->Controller::UpdateCursorPosition %p\n", this); - if(NULL == mEventData) + if(nullptr == mEventData) { // Nothing to do if there is no text input. DALI_LOG_INFO(gLogFilter, Debug::Verbose, "<--Controller::UpdateCursorPosition no event data\n"); @@ -1925,7 +1971,7 @@ void Controller::Impl::ScrollTextToMatchCursor() void Controller::Impl::RequestRelayout() { - if(NULL != mControlInterface) + if(nullptr != mControlInterface) { mControlInterface->RequestTextRelayout(); } @@ -2095,6 +2141,32 @@ Actor Controller::Impl::CreateBackgroundActor() return actor; } +void Controller::Impl::CopyUnderlinedFromLogicalToVisualModels(bool shouldClearPreUnderlineRuns) +{ + //Underlined character runs for markup-processor + const Vector& underlinedCharacterRuns = mModel->mLogicalModel->mUnderlinedCharacterRuns; + const Vector& charactersToGlyph = mModel->mVisualModel->mCharactersToGlyph; + const Vector& glyphsPerCharacter = mModel->mVisualModel->mGlyphsPerCharacter; + + if(shouldClearPreUnderlineRuns) + { + mModel->mVisualModel->mUnderlineRuns.Clear(); + } + + for(Vector::ConstIterator it = underlinedCharacterRuns.Begin(), endIt = underlinedCharacterRuns.End(); it != endIt; ++it) + { + CharacterIndex characterIndex = it->characterRun.characterIndex; + Length numberOfCharacters = it->characterRun.numberOfCharacters; + for(Length index=0u; indexmVisualModel->mUnderlineRuns.PushBack(underlineGlyphRun); + } + } +} + } // namespace Text } // namespace Toolkit diff --git a/dali-toolkit/internal/text/text-controller-impl.h b/dali-toolkit/internal/text/text-controller-impl.h index ef4bb69..9f637d3 100644 --- a/dali-toolkit/internal/text/text-controller-impl.h +++ b/dali-toolkit/internal/text/text-controller-impl.h @@ -785,6 +785,13 @@ private: // Declared private and left undefined to avoid copies. Impl& operator=(const Impl&); + /** + * @brief Copy Underlined-Character-Runs from Logical-Model to Underlined-Glyph-Runs in Visual-Model + * + * @param shouldClearPreUnderlineRuns Whether should clear the existing Underlined-Glyph-Runs in Visual-Model + */ + void CopyUnderlinedFromLogicalToVisualModels(bool shouldClearPreUnderlineRuns); + public: ControlInterface* mControlInterface; ///< Reference to the text controller. EditableControlInterface* mEditableControlInterface; ///< Reference to the editable text controller. diff --git a/dali-toolkit/internal/text/text-controller-text-updater.cpp b/dali-toolkit/internal/text/text-controller-text-updater.cpp index 81adb8a..36a2133 100644 --- a/dali-toolkit/internal/text/text-controller-text-updater.cpp +++ b/dali-toolkit/internal/text/text-controller-text-updater.cpp @@ -82,7 +82,8 @@ void Controller::TextUpdater::SetText(Controller& controller, const std::string& MarkupProcessData markupProcessData(logicalModel->mColorRuns, logicalModel->mFontDescriptionRuns, logicalModel->mEmbeddedItems, - logicalModel->mAnchors); + logicalModel->mAnchors, + logicalModel->mUnderlinedCharacterRuns); Length textSize = 0u; const uint8_t* utf8 = NULL; diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index 15db50b..99c0264 100644 --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -124,6 +124,8 @@ void Controller::SetMarkupProcessorEnabled(bool enable) GetText(text); SetText(text); } + + mImpl->mModel->mVisualModel->SetMarkupProcessorEnabled(enable); } bool Controller::IsMarkupProcessorEnabled() const diff --git a/dali-toolkit/internal/text/text-model-interface.h b/dali-toolkit/internal/text/text-model-interface.h index aafd430..5c3fa1f 100644 --- a/dali-toolkit/internal/text/text-model-interface.h +++ b/dali-toolkit/internal/text/text-model-interface.h @@ -265,6 +265,13 @@ public: * @return The background state. */ virtual bool IsBackgroundEnabled() const = 0; + + /** + * @brief Returns whether markup-processor is enabled or not. + * + * @return The markup-processor state. + */ + virtual bool IsMarkupProcessorEnabled() const = 0; }; } // namespace Text diff --git a/dali-toolkit/internal/text/text-model.cpp b/dali-toolkit/internal/text/text-model.cpp index 2d60854..42a5795 100644 --- a/dali-toolkit/internal/text/text-model.cpp +++ b/dali-toolkit/internal/text/text-model.cpp @@ -184,6 +184,11 @@ bool Model::IsBackgroundEnabled() const return mVisualModel->IsBackgroundEnabled(); } +bool Model::IsMarkupProcessorEnabled() const +{ + return mVisualModel->IsMarkupProcessorEnabled(); +} + Model::Model() : mLogicalModel(), mVisualModel(), diff --git a/dali-toolkit/internal/text/text-model.h b/dali-toolkit/internal/text/text-model.h index d52809c..705adeb 100644 --- a/dali-toolkit/internal/text/text-model.h +++ b/dali-toolkit/internal/text/text-model.h @@ -207,6 +207,11 @@ public: */ bool IsBackgroundEnabled() const override; + /** + * @copydoc ModelInterface::IsMarkupProcessorEnabled() + */ + bool IsMarkupProcessorEnabled() const override; + private: // Private contructors & copy operator. /** * @brief Private constructor. diff --git a/dali-toolkit/internal/text/underlined-character-run.h b/dali-toolkit/internal/text/underlined-character-run.h new file mode 100644 index 0000000..99d5967 --- /dev/null +++ b/dali-toolkit/internal/text/underlined-character-run.h @@ -0,0 +1,51 @@ +#ifndef DALI_TOOLKIT_TEXT_UNDERLINED_CHARACTER_RUN_H +#define DALI_TOOLKIT_TEXT_UNDERLINED_CHARACTER_RUN_H + +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// EXTERNAL INCLUDES +#include + +// INTERNAL INCLUDES +#include +#include + +namespace Dali +{ +namespace Toolkit +{ +namespace Text +{ +/** + * @brief Run of underlined characters with same properties. + */ +struct UnderlinedCharacterRun +{ + CharacterRun characterRun; ///< The initial character index and the number of characters of the run. + //TODO: add properties like color, height and style + //Vector4 color; ///< The color of underline. + //float height; ///< The height of underline. +}; + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali + +#endif // DALI_TOOLKIT_TEXT_UNDERLINED_CHARACTER_RUN_H diff --git a/dali-toolkit/internal/text/visual-model-impl.cpp b/dali-toolkit/internal/text/visual-model-impl.cpp index eda5633..7edb428 100644 --- a/dali-toolkit/internal/text/visual-model-impl.cpp +++ b/dali-toolkit/internal/text/visual-model-impl.cpp @@ -384,6 +384,11 @@ void VisualModel::SetBackgroundEnabled(bool enabled) mBackgroundEnabled = enabled; } +void VisualModel::SetMarkupProcessorEnabled(bool enabled) +{ + mMarkupProcessorEnabled = enabled; +} + const Vector4& VisualModel::GetTextColor() const { return mTextColor; @@ -439,6 +444,11 @@ bool VisualModel::IsBackgroundEnabled() const return mBackgroundEnabled; } +bool VisualModel::IsMarkupProcessorEnabled() const +{ + return mMarkupProcessorEnabled; +} + Length VisualModel::GetNumberOfUnderlineRuns() const { return mUnderlineRuns.Count(); @@ -476,7 +486,8 @@ VisualModel::VisualModel() mCachedLineIndex(0u), mUnderlineEnabled(false), mUnderlineColorSet(false), - mBackgroundEnabled(false) + mBackgroundEnabled(false), + mMarkupProcessorEnabled(false) { } diff --git a/dali-toolkit/internal/text/visual-model-impl.h b/dali-toolkit/internal/text/visual-model-impl.h index 371b666..bf3ead2 100644 --- a/dali-toolkit/internal/text/visual-model-impl.h +++ b/dali-toolkit/internal/text/visual-model-impl.h @@ -353,6 +353,20 @@ public: */ bool IsBackgroundEnabled() const; + /** + * @brief Sets whether the text has a markup-processor or not. + * + * @param[in] enabled true if the text has a markup-processor. + */ + void SetMarkupProcessorEnabled(bool enabled); + + /** + * @brief Returns whether the text has a markup-processor or not. + * + * @return whether the text has a markup-processor or not. + */ + bool IsMarkupProcessorEnabled() const; + protected: /** * @brief A reference counted object may only be deleted by calling Unreference(). @@ -407,6 +421,7 @@ public: bool mUnderlineEnabled : 1; ///< Underline enabled flag bool mUnderlineColorSet : 1; ///< Has the underline color been explicitly set? bool mBackgroundEnabled : 1; ///< Background enabled flag + bool mMarkupProcessorEnabled : 1; ///< Markup-processor enabled flag }; } // namespace Text diff --git a/dali-toolkit/internal/visuals/text/text-visual.cpp b/dali-toolkit/internal/visuals/text/text-visual.cpp index 19e08b2..870ac09 100644 --- a/dali-toolkit/internal/visuals/text/text-visual.cpp +++ b/dali-toolkit/internal/visuals/text/text-visual.cpp @@ -528,12 +528,12 @@ void TextVisual::UpdateRenderer() shadowEnabled = true; } - const bool underlineEnabled = mController->GetTextModel()->IsUnderlineEnabled(); - const bool outlineEnabled = (mController->GetTextModel()->GetOutlineWidth() > Math::MACHINE_EPSILON_1); - const bool backgroundEnabled = mController->GetTextModel()->IsBackgroundEnabled(); - ; + const bool underlineEnabled = mController->GetTextModel()->IsUnderlineEnabled(); + const bool outlineEnabled = (mController->GetTextModel()->GetOutlineWidth() > Math::MACHINE_EPSILON_1); + const bool backgroundEnabled = mController->GetTextModel()->IsBackgroundEnabled(); + const bool markupProcessorEnabled = mController->IsMarkupProcessorEnabled(); - const bool styleEnabled = (shadowEnabled || underlineEnabled || outlineEnabled || backgroundEnabled); + const bool styleEnabled = (shadowEnabled || underlineEnabled || outlineEnabled || backgroundEnabled || markupProcessorEnabled); AddRenderer(control, relayoutSize, hasMultipleTextColors, containsColorGlyph, styleEnabled); -- 2.7.4