From 04194fd795542d80b5cf7c1b954ca14593e536d4 Mon Sep 17 00:00:00 2001 From: abdullah Date: Wed, 23 Jun 2021 15:45:00 +0300 Subject: [PATCH] support strikethrough markup tag using namespace Dali; using namespace Dali::Toolkit; class SimpleApp : public ConnectionTracker { public: SimpleApp(Application& application) : mApplication(application) { mApplication.InitSignal().Connect(this, &SimpleApp::Create); } void Create(Application& application) { Window window = application.GetWindow(); window.SetBackgroundColor(Vector4(0.04f, 0.345f, 0.392f, 1.0f)); mEditor = TextEditor::New(); mEditor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER); mEditor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER); mEditor.SetProperty(Actor::Property::POSITION, Vector3(0.f, 0.0f, 0.f)); mEditor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 100.0f)); mEditor.SetProperty(TextEditor::Property::TEXT_COLOR, Vector4(0.00f, 0.0f, 1.0f, 1.0f)); mEditor.SetBackgroundColor(Vector4(0.04f, 0.345f, 0.392f, 1.0f)); mEditor.SetProperty(TextEditor::Property::ENABLE_MARKUP, true); mEditor.SetProperty(TextEditor::Property::TEXT, "Hello World"); window.Add(mEditor); } private: Application& mApplication; TextEditor mEditor; }; int DALI_EXPORT_API main(int argc, char** argv) { Application application = Application::New(&argc, &argv); SimpleApp test(application); application.MainLoop(); return 0; } Change-Id: I4ad7c2ea2f65bc54765ffcc2b2aa177ea84138df --- .../dali-toolkit-test-utils/toolkit-text-utils.cpp | 400 +++++++------ .../dali-toolkit-internal/utc-Dali-Text-Markup.cpp | 639 +++++++++------------ .../utc-Dali-TextEditor-internal.cpp | 41 +- .../utc-Dali-TextField-internal.cpp | 250 ++++---- .../utc-Dali-TextLabel-internal.cpp | 152 +++-- dali-toolkit/devel-api/text/text-utils-devel.cpp | 5 +- dali-toolkit/internal/file.list | 1 + dali-toolkit/internal/text/logical-model-impl.cpp | 18 +- dali-toolkit/internal/text/logical-model-impl.h | 6 +- .../text/markup-processor-strikethrough.cpp | 59 ++ .../internal/text/markup-processor-strikethrough.h | 44 ++ dali-toolkit/internal/text/markup-processor.cpp | 33 +- dali-toolkit/internal/text/markup-processor.h | 32 +- .../text/rendering/atlas/text-atlas-renderer.cpp | 88 ++- .../internal/text/rendering/text-typesetter.cpp | 140 +++-- .../internal/text/rendering/text-typesetter.h | 40 +- .../internal/text/rendering/view-model.cpp | 12 +- dali-toolkit/internal/text/rendering/view-model.h | 12 +- .../internal/text/strikethrough-character-run.h | 49 ++ .../internal/text/strikethrough-glyph-run.h | 49 ++ .../text/text-controller-impl-model-updater.cpp | 1 + .../internal/text/text-controller-impl.cpp | 28 + dali-toolkit/internal/text/text-controller-impl.h | 6 + .../internal/text/text-controller-text-updater.cpp | 3 +- dali-toolkit/internal/text/text-definitions.h | 3 +- dali-toolkit/internal/text/text-model-interface.h | 19 +- dali-toolkit/internal/text/text-model.cpp | 12 +- dali-toolkit/internal/text/text-model.h | 12 +- dali-toolkit/internal/text/text-view-interface.h | 21 +- dali-toolkit/internal/text/text-view.cpp | 22 + dali-toolkit/internal/text/text-view.h | 14 +- dali-toolkit/internal/text/visual-model-impl.cpp | 16 +- dali-toolkit/internal/text/visual-model-impl.h | 76 ++- 33 files changed, 1456 insertions(+), 847 deletions(-) mode change 100755 => 100644 automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/toolkit-text-utils.cpp mode change 100755 => 100644 automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Markup.cpp mode change 100755 => 100644 automated-tests/src/dali-toolkit-internal/utc-Dali-TextField-internal.cpp mode change 100755 => 100644 automated-tests/src/dali-toolkit-internal/utc-Dali-TextLabel-internal.cpp create mode 100644 dali-toolkit/internal/text/markup-processor-strikethrough.cpp create mode 100644 dali-toolkit/internal/text/markup-processor-strikethrough.h create mode 100644 dali-toolkit/internal/text/strikethrough-character-run.h create mode 100644 dali-toolkit/internal/text/strikethrough-glyph-run.h 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 old mode 100755 new mode 100644 index cc0288c..e9d0ef0 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -19,48 +19,45 @@ #include "toolkit-text-utils.h" // EXTERNAL INCLUDES -#include #include +#include // INTERNAL INCLUDES #include #include +#include #include #include +#include #include #include #include #include -#include -#include namespace Dali { - namespace Toolkit { - namespace Text { - /** * @brief Frees previously allocated bidirectional resources. * * @param[in] bidirectionalLineInfo Bidirectional info per line. * @param[in] index Index to the first line with bidirectional info to be freed. */ -void FreeBidirectionalLineInfoResources( Vector bidirectionalLineInfo, - uint32_t index ) +void FreeBidirectionalLineInfoResources(Vector bidirectionalLineInfo, + uint32_t index) { // Free the allocated memory used to store the conversion table in the bidirectional line info run. - for( Vector::Iterator it = bidirectionalLineInfo.Begin() + index, - endIt = bidirectionalLineInfo.End(); - it != endIt; - ++it ) + for(Vector::Iterator it = bidirectionalLineInfo.Begin() + index, + endIt = bidirectionalLineInfo.End(); + it != endIt; + ++it) { BidirectionalLineInfoRun& bidiLineInfo = *it; - free( bidiLineInfo.visualToLogicalMap ); + free(bidiLineInfo.visualToLogicalMap); } } @@ -69,14 +66,14 @@ void FreeBidirectionalLineInfoResources( Vector bidire * * @param[in] characterIndex Clear data starting from the index. */ -void ClearModelData( CharacterIndex characterIndex, - LogicalModelPtr logicalModel, - VisualModelPtr visualModel ) +void ClearModelData(CharacterIndex characterIndex, + LogicalModelPtr logicalModel, + VisualModelPtr visualModel) { // n.b. This does not Clear the mText from mLogicalModel // Frees previously allocated resources. - FreeBidirectionalLineInfoResources( logicalModel->mBidirectionalLineInfo, 0u ); + FreeBidirectionalLineInfoResources(logicalModel->mBidirectionalLineInfo, 0u); logicalModel->mScriptRuns.Clear(); logicalModel->mFontRuns.Clear(); @@ -94,73 +91,74 @@ void ClearModelData( CharacterIndex characterIndex, visualModel->ClearCaches(); } -void CreateTextModel( const std::string& text, - const Size& textArea, - const Vector& fontDescriptions, - const LayoutOptions& options, - Size& layoutSize, - ModelPtr& textModel, - MetricsPtr& metrics, - bool markupProcessorEnabled, - LineWrap::Mode wrapMode, - bool ellipsisEnabled, - DevelText::EllipsisPosition::Type ellipsisPosition, - float lineSpacing) +void CreateTextModel(const std::string& text, + const Size& textArea, + const Vector& fontDescriptions, + const LayoutOptions& options, + Size& layoutSize, + ModelPtr& textModel, + MetricsPtr& metrics, + bool markupProcessorEnabled, + LineWrap::Mode wrapMode, + bool ellipsisEnabled, + DevelText::EllipsisPosition::Type ellipsisPosition, + float lineSpacing) { - textModel = Model::New(); ///< Pointer to the text's model. + textModel = Model::New(); ///< Pointer to the text's model. LogicalModelPtr logicalModel = textModel->mLogicalModel; - VisualModelPtr visualModel = textModel->mVisualModel; - - MarkupProcessData markupProcessData( logicalModel->mColorRuns, - logicalModel->mFontDescriptionRuns, - logicalModel->mEmbeddedItems, - logicalModel->mAnchors, - logicalModel->mUnderlinedCharacterRuns, - logicalModel->mBackgroundColorRuns); - - Length textSize = 0u; - const uint8_t* utf8 = NULL; - if( markupProcessorEnabled ) + VisualModelPtr visualModel = textModel->mVisualModel; + + MarkupProcessData markupProcessData(logicalModel->mColorRuns, + logicalModel->mFontDescriptionRuns, + logicalModel->mEmbeddedItems, + logicalModel->mAnchors, + logicalModel->mUnderlinedCharacterRuns, + logicalModel->mBackgroundColorRuns, + logicalModel->mStrikethroughCharacterRuns); + + Length textSize = 0u; + const uint8_t* utf8 = NULL; + if(markupProcessorEnabled) { - ProcessMarkupString( text, markupProcessData ); + ProcessMarkupString(text, markupProcessData); textSize = markupProcessData.markupProcessedText.size(); // This is a bit horrible but std::string returns a (signed) char* - utf8 = reinterpret_cast( markupProcessData.markupProcessedText.c_str() ); + utf8 = reinterpret_cast(markupProcessData.markupProcessedText.c_str()); } else { textSize = text.size(); // This is a bit horrible but std::string returns a (signed) char* - utf8 = reinterpret_cast( text.c_str() ); + utf8 = reinterpret_cast(text.c_str()); } //Ellipsis - textModel-> mElideEnabled = ellipsisEnabled; - textModel-> mVisualModel->SetTextElideEnabled(ellipsisEnabled); - textModel-> mEllipsisPosition = ellipsisPosition; - textModel-> mVisualModel->SetEllipsisPosition(ellipsisPosition); + textModel->mElideEnabled = ellipsisEnabled; + textModel->mVisualModel->SetTextElideEnabled(ellipsisEnabled); + textModel->mEllipsisPosition = ellipsisPosition; + textModel->mVisualModel->SetEllipsisPosition(ellipsisPosition); // 1) Convert to utf32 Vector& utf32Characters = logicalModel->mText; - utf32Characters.Resize( textSize ); + utf32Characters.Resize(textSize); // Transform a text array encoded in utf8 into an array encoded in utf32. // It returns the actual number of characters. - Length characterCount = Utf8ToUtf32( utf8, textSize, utf32Characters.Begin() ); - utf32Characters.Resize( characterCount ); + Length characterCount = Utf8ToUtf32(utf8, textSize, utf32Characters.Begin()); + utf32Characters.Resize(characterCount); // 2) Set the break and paragraph info. Vector& lineBreakInfo = logicalModel->mLineBreakInfo; - lineBreakInfo.Resize( characterCount ); + lineBreakInfo.Resize(characterCount); - SetLineBreakInfo( utf32Characters, - 0u, - characterCount, - lineBreakInfo ); + SetLineBreakInfo(utf32Characters, + 0u, + characterCount, + lineBreakInfo); - if( 0u == characterCount ) + if(0u == characterCount) { // Nothing else to do if the number of characters is zero. return; @@ -169,7 +167,7 @@ void CreateTextModel( const std::string& text, textModel->mLineWrapMode = wrapMode; if(textModel->mLineWrapMode == ((Text::LineWrap::Mode)DevelText::LineWrap::HYPHENATION) || - textModel->mLineWrapMode == ((Text::LineWrap::Mode)DevelText::LineWrap::MIXED)) + textModel->mLineWrapMode == ((Text::LineWrap::Mode)DevelText::LineWrap::MIXED)) { CharacterIndex end = characterCount; LineBreakInfo* lineBreakInfoBuffer = lineBreakInfo.Begin(); @@ -205,71 +203,70 @@ void CreateTextModel( const std::string& text, MultilanguageSupport multilanguageSupport = MultilanguageSupport::Get(); Vector& scripts = logicalModel->mScriptRuns; - multilanguageSupport.SetScripts( utf32Characters, - 0u, - characterCount, - scripts ); + multilanguageSupport.SetScripts(utf32Characters, + 0u, + characterCount, + scripts); // 4) Set the font info Vector& fontDescriptionRuns = logicalModel->mFontDescriptionRuns; - fontDescriptionRuns = fontDescriptions; - Vector& validFonts = logicalModel->mFontRuns; + fontDescriptionRuns = fontDescriptions; + Vector& validFonts = logicalModel->mFontRuns; // The default font description. TextAbstraction::FontDescription fontDescription; TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get(); - fontClient.SetDpi( 96u, 96u ); + fontClient.SetDpi(96u, 96u); // Validates the fonts. If there is a character with no assigned font it sets a default one. // After this call, fonts are validated. - multilanguageSupport.ValidateFonts( utf32Characters, - scripts, - fontDescriptionRuns, - fontDescription, - TextAbstraction::FontClient::DEFAULT_POINT_SIZE, - 0u, - characterCount, - validFonts ); + multilanguageSupport.ValidateFonts(utf32Characters, + scripts, + fontDescriptionRuns, + fontDescription, + TextAbstraction::FontClient::DEFAULT_POINT_SIZE, + 0u, + characterCount, + validFonts); // 5) Set the bidirectional info per paragraph. Vector mirroredUtf32Characters; - bool textMirrored = false; + bool textMirrored = false; // Reserve some space for the vector of paragraph's bidirectional info. Vector& bidirectionalInfo = logicalModel->mBidirectionalParagraphInfo; // Calculates the bidirectional info for the whole paragraph if it contains right to left scripts. - SetBidirectionalInfo( utf32Characters, - scripts, - lineBreakInfo, - 0u, - characterCount, - bidirectionalInfo ); + SetBidirectionalInfo(utf32Characters, + scripts, + lineBreakInfo, + 0u, + characterCount, + bidirectionalInfo); // Create the paragraph info. - logicalModel->CreateParagraphInfo( 0u, - characterCount ); + logicalModel->CreateParagraphInfo(0u, + characterCount); // 6) Set character directions. Vector& characterDirections = logicalModel->mCharacterDirections; - if( 0u != bidirectionalInfo.Count() ) + if(0u != bidirectionalInfo.Count()) { // Only set the character directions if there is right to left characters. - GetCharactersDirection( bidirectionalInfo, - characterCount, - 0u, - characterCount, - characterDirections ); - + GetCharactersDirection(bidirectionalInfo, + characterCount, + 0u, + characterCount, + characterDirections); // This paragraph has right to left text. Some characters may need to be mirrored. - textMirrored = GetMirroredText( utf32Characters, - characterDirections, - bidirectionalInfo, - 0u, - characterCount, - mirroredUtf32Characters ); + textMirrored = GetMirroredText(utf32Characters, + characterDirections, + bidirectionalInfo, + 0u, + characterCount, + mirroredUtf32Characters); } else { @@ -279,223 +276,220 @@ void CreateTextModel( const std::string& text, // 7) Shape the text. - Vector& glyphs = visualModel->mGlyphs; + Vector& glyphs = visualModel->mGlyphs; Vector& glyphsToCharactersMap = visualModel->mGlyphsToCharacters; - Vector& charactersPerGlyph = visualModel->mCharactersPerGlyph; - Vector newParagraphGlyphs; + Vector& charactersPerGlyph = visualModel->mCharactersPerGlyph; + Vector newParagraphGlyphs; const Vector& textToShape = textMirrored ? mirroredUtf32Characters : utf32Characters; - ShapeText( textToShape, - lineBreakInfo, - scripts, - validFonts, - 0u, - 0u, - characterCount, - glyphs, - glyphsToCharactersMap, - charactersPerGlyph, - newParagraphGlyphs ); + ShapeText(textToShape, + lineBreakInfo, + scripts, + validFonts, + 0u, + 0u, + characterCount, + glyphs, + glyphsToCharactersMap, + charactersPerGlyph, + newParagraphGlyphs); // Create the 'number of glyphs' per character and the glyph to character conversion tables. - visualModel->CreateGlyphsPerCharacterTable( 0u, 0u, characterCount ); - visualModel->CreateCharacterToGlyphTable( 0u, 0u, characterCount ); + visualModel->CreateGlyphsPerCharacterTable(0u, 0u, characterCount); + visualModel->CreateCharacterToGlyphTable(0u, 0u, characterCount); const Length numberOfGlyphs = glyphs.Count(); // 8) Get the glyph metrics - metrics = Metrics::New( fontClient ); + metrics = Metrics::New(fontClient); GlyphInfo* glyphsBuffer = glyphs.Begin(); - metrics->GetGlyphMetrics( glyphsBuffer, numberOfGlyphs ); + metrics->GetGlyphMetrics(glyphsBuffer, numberOfGlyphs); // Update the width and advance of all new paragraph characters. - for( Vector::ConstIterator it = newParagraphGlyphs.Begin(), - endIt = newParagraphGlyphs.End(); - it != endIt; - ++it ) + for(Vector::ConstIterator it = newParagraphGlyphs.Begin(), + endIt = newParagraphGlyphs.End(); + it != endIt; + ++it) { const GlyphIndex index = *it; - GlyphInfo& glyph = *( glyphsBuffer + index ); + GlyphInfo& glyph = *(glyphsBuffer + index); glyph.xBearing = 0.f; - glyph.width = 0.f; - glyph.advance = 0.f; + glyph.width = 0.f; + glyph.advance = 0.f; } // 9) Layout the text Layout::Engine layoutEngine; - layoutEngine.SetMetrics( metrics ); - layoutEngine.SetLayout( Layout::Engine::MULTI_LINE_BOX ); + layoutEngine.SetMetrics(metrics); + layoutEngine.SetLayout(Layout::Engine::MULTI_LINE_BOX); layoutEngine.SetDefaultLineSpacing(lineSpacing); // Set the layout parameters. - textModel->mHorizontalAlignment = Text::HorizontalAlignment::BEGIN; + textModel->mHorizontalAlignment = Text::HorizontalAlignment::BEGIN; textModel->mIgnoreSpacesAfterText = true; - Layout::Parameters layoutParameters( textArea, - textModel ); + Layout::Parameters layoutParameters(textArea, + textModel); Vector& lines = visualModel->mLines; Vector& glyphPositions = visualModel->mGlyphPositions; - glyphPositions.Resize( numberOfGlyphs ); + glyphPositions.Resize(numberOfGlyphs); - layoutParameters.isLastNewParagraph = TextAbstraction::IsNewParagraph( *( utf32Characters.Begin() + ( characterCount - 1u ) ) ); + layoutParameters.isLastNewParagraph = TextAbstraction::IsNewParagraph(*(utf32Characters.Begin() + (characterCount - 1u))); // The initial glyph and the number of glyphs to layout. - layoutParameters.startGlyphIndex = 0u; - layoutParameters.numberOfGlyphs = numberOfGlyphs; - layoutParameters.startLineIndex = 0u; + layoutParameters.startGlyphIndex = 0u; + layoutParameters.numberOfGlyphs = numberOfGlyphs; + layoutParameters.startLineIndex = 0u; layoutParameters.estimatedNumberOfLines = logicalModel->mParagraphInfo.Count(); bool isAutoScroll = false; - layoutEngine.LayoutText( layoutParameters, - layoutSize, - false, - isAutoScroll, - ellipsisPosition); + layoutEngine.LayoutText(layoutParameters, + layoutSize, + false, + isAutoScroll, + ellipsisPosition); - if( options.align ) + if(options.align) { float alignmentOffset = 0.f; - layoutEngine.Align( textArea, - 0u, - characterCount, - Text::HorizontalAlignment::BEGIN, - lines, - alignmentOffset, - Dali::LayoutDirection::LEFT_TO_RIGHT, - false ); + layoutEngine.Align(textArea, + 0u, + characterCount, + Text::HorizontalAlignment::BEGIN, + lines, + alignmentOffset, + Dali::LayoutDirection::LEFT_TO_RIGHT, + false); } } -void ConfigureTextLabel( ControllerPtr controller ) +void ConfigureTextLabel(ControllerPtr controller) { TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get(); - fontClient.SetDpi( 93u, 93u ); + fontClient.SetDpi(93u, 93u); // Set the text layout as multi-line. - controller->GetLayoutEngine().SetLayout( Layout::Engine::MULTI_LINE_BOX ); + controller->GetLayoutEngine().SetLayout(Layout::Engine::MULTI_LINE_BOX); // Set cursor's width to zero. - controller->GetLayoutEngine().SetCursorWidth( 0 ); + controller->GetLayoutEngine().SetCursorWidth(0); InputMethodContext inputMethodContext = InputMethodContext::New(); // Disables the text input. - controller->EnableTextInput( NULL, inputMethodContext ); + controller->EnableTextInput(NULL, inputMethodContext); // Disables the vertical scrolling. - controller->SetVerticalScrollEnabled( false ); + controller->SetVerticalScrollEnabled(false); // Disables the horizontal scrolling. - controller->SetHorizontalScrollEnabled( false ); + controller->SetHorizontalScrollEnabled(false); // Enable the text elide. - controller->SetTextElideEnabled( true ); + controller->SetTextElideEnabled(true); // Disable match system language direction controller->SetMatchLayoutDirection(DevelText::MatchLayoutDirection::CONTENTS); } -void ConfigureTextField( ControllerPtr controller ) +void ConfigureTextField(ControllerPtr controller) { TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get(); - fontClient.SetDpi( 93u, 93u ); + fontClient.SetDpi(93u, 93u); // Creates a decorator. - Text::DecoratorPtr decorator = Text::Decorator::New( *controller, - *controller ); + Text::DecoratorPtr decorator = Text::Decorator::New(*controller, + *controller); // Set the text layout as multi-line. - controller->GetLayoutEngine().SetLayout( Layout::Engine::SINGLE_LINE_BOX ); + controller->GetLayoutEngine().SetLayout(Layout::Engine::SINGLE_LINE_BOX); InputMethodContext inputMethodContext = InputMethodContext::New(); // Enables the text input. - controller->EnableTextInput( decorator, inputMethodContext ); + controller->EnableTextInput(decorator, inputMethodContext); // Enables the vertical scrolling after the text input has been enabled. - controller->SetVerticalScrollEnabled( false ); + controller->SetVerticalScrollEnabled(false); // Disables the horizontal scrolling. - controller->SetHorizontalScrollEnabled( true ); + controller->SetHorizontalScrollEnabled(true); // No maximum number of characters. - controller->SetMaximumNumberOfCharacters( 50u ); + controller->SetMaximumNumberOfCharacters(50u); // Disable the text elide. - controller->SetTextElideEnabled( false ); + controller->SetTextElideEnabled(false); // Disable match system language direction controller->SetMatchLayoutDirection(DevelText::MatchLayoutDirection::CONTENTS); } -void ConfigureTextEditor( ControllerPtr controller ) +void ConfigureTextEditor(ControllerPtr controller) { TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get(); - fontClient.SetDpi( 93u, 93u ); + fontClient.SetDpi(93u, 93u); // Creates a decorator. - Text::DecoratorPtr decorator = Text::Decorator::New( *controller, - *controller ); + Text::DecoratorPtr decorator = Text::Decorator::New(*controller, + *controller); // Set the text layout as multi-line. - controller->GetLayoutEngine().SetLayout( Layout::Engine::MULTI_LINE_BOX ); + controller->GetLayoutEngine().SetLayout(Layout::Engine::MULTI_LINE_BOX); InputMethodContext inputMethodContext = InputMethodContext::New(); // Enables the text input. - controller->EnableTextInput( decorator, inputMethodContext ); + controller->EnableTextInput(decorator, inputMethodContext); // Enables the vertical scrolling after the text input has been enabled. - controller->SetVerticalScrollEnabled( true ); + controller->SetVerticalScrollEnabled(true); // Disables the horizontal scrolling. - controller->SetHorizontalScrollEnabled( false ); + controller->SetHorizontalScrollEnabled(false); // No maximum number of characters. - controller->SetMaximumNumberOfCharacters( std::numeric_limits::max() ); + controller->SetMaximumNumberOfCharacters(std::numeric_limits::max()); // Disable the text elide. - controller->SetTextElideEnabled( false ); + controller->SetTextElideEnabled(false); // Disable match system language direction controller->SetMatchLayoutDirection(DevelText::MatchLayoutDirection::CONTENTS); } - Vector CreateSingleFontDescription( - const CharacterRun& characterRun, - const std::string fontFamilyName, - const FontWeight weight, - const FontWidth width, - const FontSlant slant, - const PointSize26Dot6 size, - const bool familyDefined, - const bool weightDefined, - const bool widthDefined, - const bool slantDefined, - const bool sizeDefined) + const CharacterRun& characterRun, + const std::string fontFamilyName, + const FontWeight weight, + const FontWidth width, + const FontSlant slant, + const PointSize26Dot6 size, + const bool familyDefined, + const bool weightDefined, + const bool widthDefined, + const bool slantDefined, + const bool sizeDefined) { - FontDescriptionRun fontDescriptionRun = - { - characterRun, - nullptr, - 0u, - weight, - width, - slant, - size, - familyDefined, - weightDefined, - widthDefined, - slantDefined, - sizeDefined - }; + { + characterRun, + nullptr, + 0u, + weight, + width, + slant, + size, + familyDefined, + weightDefined, + widthDefined, + slantDefined, + sizeDefined}; fontDescriptionRun.familyLength = fontFamilyName.size(); - fontDescriptionRun.familyName = new char[fontDescriptionRun.familyLength]; - memcpy( fontDescriptionRun.familyName, fontFamilyName.c_str(), fontDescriptionRun.familyLength ); + fontDescriptionRun.familyName = new char[fontDescriptionRun.familyLength]; + memcpy(fontDescriptionRun.familyName, fontFamilyName.c_str(), fontDescriptionRun.familyLength); Vector fontDescriptionRuns; fontDescriptionRuns.PushBack(fontDescriptionRun); 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 old mode 100755 new mode 100644 index 1a4b5e1..67299b4 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Markup.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Markup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -22,13 +22,13 @@ #include #include -#include -#include -#include #include #include +#include +#include #include #include +#include using namespace Dali; using namespace Toolkit; @@ -36,179 +36,177 @@ using namespace Text; namespace { +/////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////// - - struct TokenComparisonData - { - std::string description; - std::string string1; ///< must be in lower case!!!! - std::string string2; - bool expectedResult; - }; - - bool TokenComparisonTest( const TokenComparisonData& data ) - { - std::cout << " testing " << data.description << std::endl; +struct TokenComparisonData +{ + std::string description; + std::string string1; ///< must be in lower case!!!! + std::string string2; + bool expectedResult; +}; - const bool result = TokenComparison( data.string1, - data.string2.c_str(), - data.string2.size() ); +bool TokenComparisonTest(const TokenComparisonData& data) +{ + std::cout << " testing " << data.description << std::endl; - if( result != data.expectedResult ) - { - std::cout << " different conparison result : " << result << ", expected : " << data.expectedResult << std::endl; - std::cout << " comparing : [" << data.string1 << "] and [" << data.string2 << "]" << std::endl; + const bool result = TokenComparison(data.string1, + data.string2.c_str(), + data.string2.size()); - return false; - } + if(result != data.expectedResult) + { + std::cout << " different conparison result : " << result << ", expected : " << data.expectedResult << std::endl; + std::cout << " comparing : [" << data.string1 << "] and [" << data.string2 << "]" << std::endl; - return true; + return false; } - /////////////////////////////////////////////////////////// + return true; +} - struct ColorStringToVector4Data - { - std::string description; - std::string colorStr; - Vector4 expectedColor; - }; +/////////////////////////////////////////////////////////// - bool ColorStringToVector4Test( const ColorStringToVector4Data& data ) - { - std::cout << " testing " << data.description << std::endl; +struct ColorStringToVector4Data +{ + std::string description; + std::string colorStr; + Vector4 expectedColor; +}; - Vector4 color; - ColorStringToVector4( data.colorStr.c_str(), data.colorStr.size(), color ); +bool ColorStringToVector4Test(const ColorStringToVector4Data& data) +{ + std::cout << " testing " << data.description << std::endl; - if( color != data.expectedColor ) - { - std::cout << " different color : " << color << ", expected : " << data.expectedColor << std::endl; - return false; - } + Vector4 color; + ColorStringToVector4(data.colorStr.c_str(), data.colorStr.size(), color); - return true; + if(color != data.expectedColor) + { + std::cout << " different color : " << color << ", expected : " << data.expectedColor << std::endl; + return false; } - /////////////////////////////////////////////////////////// + return true; +} - struct Vector4ToColorStringData - { - std::string description; - Vector4 color; - std::string expectedColorStr; - }; +/////////////////////////////////////////////////////////// - bool Vector4ToColorStringTest( const Vector4ToColorStringData& data ) - { - std::cout << " testing " << data.description << std::endl; +struct Vector4ToColorStringData +{ + std::string description; + Vector4 color; + std::string expectedColorStr; +}; - std::string colorStr; - Vector4ToColorString( data.color, colorStr ); +bool Vector4ToColorStringTest(const Vector4ToColorStringData& data) +{ + std::cout << " testing " << data.description << std::endl; - if( colorStr != data.expectedColorStr ) - { - std::cout << " different color : [" << colorStr << "], expected : [" << data.expectedColorStr << "]" << std::endl; - return false; - } + std::string colorStr; + Vector4ToColorString(data.color, colorStr); - return true; + if(colorStr != data.expectedColorStr) + { + std::cout << " different color : [" << colorStr << "], expected : [" << data.expectedColorStr << "]" << std::endl; + return false; } - /////////////////////////////////////////////////////////// + return true; +} - struct StringToVector2Data - { - std::string description; - std::string vector2Str; - Vector2 expectedVector2; - }; +/////////////////////////////////////////////////////////// - bool StringToVector2Test( const StringToVector2Data& data ) - { - std::cout << " testing " << data.description << std::endl; +struct StringToVector2Data +{ + std::string description; + std::string vector2Str; + Vector2 expectedVector2; +}; - Vector2 vector2; - StringToVector2( data.vector2Str.c_str(), data.vector2Str.size(), vector2 ); +bool StringToVector2Test(const StringToVector2Data& data) +{ + std::cout << " testing " << data.description << std::endl; - if( vector2 != data.expectedVector2 ) - { - std::cout << " different vector2 : " << vector2 << ", expected : " << data.expectedVector2 << std::endl; - return false; - } + Vector2 vector2; + StringToVector2(data.vector2Str.c_str(), data.vector2Str.size(), vector2); - return true; + if(vector2 != data.expectedVector2) + { + std::cout << " different vector2 : " << vector2 << ", expected : " << data.expectedVector2 << std::endl; + return false; } - /////////////////////////////////////////////////////////// - + return true; +} - struct Vector2ToStringData - { - std::string description; - Vector2 vector2; - std::string expectedVector2Str; - }; +/////////////////////////////////////////////////////////// - bool Vector2ToStringTest( const Vector2ToStringData& data ) - { - std::cout << " testing " << data.description << std::endl; +struct Vector2ToStringData +{ + std::string description; + Vector2 vector2; + std::string expectedVector2Str; +}; - std::string vector2Str; - Vector2ToString( data.vector2, vector2Str ); +bool Vector2ToStringTest(const Vector2ToStringData& data) +{ + std::cout << " testing " << data.description << std::endl; - if( vector2Str != data.expectedVector2Str ) - { - std::cout << " different vector2 : [" << vector2Str << "], expected : [" << data.expectedVector2Str << "]" << std::endl; - return false; - } + std::string vector2Str; + Vector2ToString(data.vector2, vector2Str); - return true; + if(vector2Str != data.expectedVector2Str) + { + std::cout << " different vector2 : [" << vector2Str << "], expected : [" << data.expectedVector2Str << "]" << std::endl; + return false; } - /////////////////////////////////////////////////////////// + return true; +} +/////////////////////////////////////////////////////////// - struct XHTMLEntityToUTF8Data - { - std::string description; - std::string xHTMLEntityString; - std::string expectedString; - }; +struct XHTMLEntityToUTF8Data +{ + std::string description; + std::string xHTMLEntityString; + std::string expectedString; +}; - bool XHTMLEntityToUTF8Test( const XHTMLEntityToUTF8Data& data ) +bool XHTMLEntityToUTF8Test(const XHTMLEntityToUTF8Data& data) +{ + std::cout << " testing " << data.description << std::endl; + + Vector colorRuns; + Vector fontRuns; + Vector items; + Vector anchors; + Vector underlinedCharacterRuns; + Vector backgroundColorRuns; + Vector strikethroughCharacterRuns; + MarkupProcessData markupProcessData(colorRuns, fontRuns, items, anchors, underlinedCharacterRuns, backgroundColorRuns, strikethroughCharacterRuns); + ProcessMarkupString(data.xHTMLEntityString, markupProcessData); + + for(Vector::Iterator it = items.Begin(), + endIt = items.End(); + it != endIt; + ++it) { - std::cout << " testing " << data.description << std::endl; - - Vector colorRuns; - Vector fontRuns; - Vector items; - Vector anchors; - Vector underlinedCharacterRuns; - Vector backgroundColorRuns; - MarkupProcessData markupProcessData( colorRuns, fontRuns, items, anchors, underlinedCharacterRuns, backgroundColorRuns ); - ProcessMarkupString( data.xHTMLEntityString, markupProcessData ); - - for( Vector::Iterator it = items.Begin(), - endIt = items.End(); - it != endIt; - ++it ) - { - EmbeddedItem& item = *it; - delete[] item.url; - } - items.Clear(); - - if( markupProcessData.markupProcessedText != data.expectedString ) - { - std::cout << " different output string : " << markupProcessData.markupProcessedText << ", expected : " << data.expectedString << " " << std::endl; - return false; - } + EmbeddedItem& item = *it; + delete[] item.url; + } + items.Clear(); - return true; + if(markupProcessData.markupProcessedText != data.expectedString) + { + std::cout << " different output string : " << markupProcessData.markupProcessedText << ", expected : " << data.expectedString << " " << std::endl; + return false; } + return true; +} + } // namespace int UtcDaliTextTokenComparison(void) @@ -216,45 +214,35 @@ int UtcDaliTextTokenComparison(void) tet_infoline(" UtcDaliTextTokenComparison"); const TokenComparisonData data[] = - { - { - "void texts", - "", - "", - true - }, - { - "different size text", - "hello", - "world!", - false - }, { - "different texts", - "hello", - "world", - false - }, - { - "same texts", - "world", - "wOrLD", - true - }, - { - "some punctuation characters, numbers, ...", - "hello0123456789.![?]", - "Hello0123456789.![?]", - true - } - - }; + {"void texts", + "", + "", + true}, + {"different size text", + "hello", + "world!", + false}, + {"different texts", + "hello", + "world", + false}, + {"same texts", + "world", + "wOrLD", + true}, + {"some punctuation characters, numbers, ...", + "hello0123456789.![?]", + "Hello0123456789.![?]", + true} + + }; const unsigned int numberOfTests = 5u; - for( unsigned int index = 0u; index < numberOfTests; ++index ) + for(unsigned int index = 0u; index < numberOfTests; ++index) { ToolkitTestApplication application; - if( !TokenComparisonTest( data[index] ) ) + if(!TokenComparisonTest(data[index])) { tet_result(TET_FAIL); } @@ -269,84 +257,56 @@ int UtcDaliTextColorStringToVector4(void) tet_infoline(" UtcDaliTextColorStringToVector4"); const ColorStringToVector4Data data[] = - { - { - "black string", - "bLack", - Color::BLACK - }, - { - "white string", - "White", - Color::WHITE - }, - { - "red string", - "reD", - Color::RED - }, - { - "green string", - "green", - Color::GREEN - }, - { - "blue string", - "blue", - Color::BLUE - }, - { - "yellow string", - "yeLloW", - Color::YELLOW - }, - { - "magenta string", - "MagEnta", - Color::MAGENTA - }, - { - "cyan string", - "CyaN", - Color::CYAN - }, - { - "transparent string", - "transparent", - Color::TRANSPARENT - }, - { - "3 component web color", - "#F00", - Color::RED - }, - { - "6 component web color", - "#fF0000", - Color::RED - }, { - "hex color red (ARGB)", - "0xffff0000", - Color::RED - }, - { - "hex color green (ARGB)", - "0xFf00FF00", - Color::GREEN - }, - { - "undefined color", - "undefined", - Vector4::ZERO - }, - }; + {"black string", + "bLack", + Color::BLACK}, + {"white string", + "White", + Color::WHITE}, + {"red string", + "reD", + Color::RED}, + {"green string", + "green", + Color::GREEN}, + {"blue string", + "blue", + Color::BLUE}, + {"yellow string", + "yeLloW", + Color::YELLOW}, + {"magenta string", + "MagEnta", + Color::MAGENTA}, + {"cyan string", + "CyaN", + Color::CYAN}, + {"transparent string", + "transparent", + Color::TRANSPARENT}, + {"3 component web color", + "#F00", + Color::RED}, + {"6 component web color", + "#fF0000", + Color::RED}, + {"hex color red (ARGB)", + "0xffff0000", + Color::RED}, + {"hex color green (ARGB)", + "0xFf00FF00", + Color::GREEN}, + {"undefined color", + "undefined", + Vector4::ZERO}, + }; const unsigned int numberOfTests = 14u; - for( unsigned int index = 0u; index < numberOfTests; ++index ) + for(unsigned int index = 0u; index < numberOfTests; ++index) { ToolkitTestApplication application; - if( !ColorStringToVector4Test( data[index] ) ) + if(!ColorStringToVector4Test(data[index])) { tet_result(TET_FAIL); } @@ -361,64 +321,46 @@ int UtcDaliTextVector4ToColorString(void) tet_infoline(" UtcDaliTextVector4ToColorString"); const Vector4ToColorStringData data[] = - { - { - "black color", - Color::BLACK, - "black" - }, - { - "white string", - Color::WHITE, - "white" - }, - { - "red string", - Color::RED, - "red" - }, - { - "green string", - Color::GREEN, - "green" - }, { - "blue string", - Color::BLUE, - "blue" - }, - { - "yellow string", - Color::YELLOW, - "yellow" - }, - { - "magenta string", - Color::MAGENTA, - "magenta", - }, - { - "cyan string", - Color::CYAN, - "cyan" - }, - { - "transparent string", - Color::TRANSPARENT, - "transparent" - }, - { - "hex color", - Vector4( 0.4f, 0.5f, 0.6f, 1.f ), - "0xff667f99" - }, - }; + {"black color", + Color::BLACK, + "black"}, + {"white string", + Color::WHITE, + "white"}, + {"red string", + Color::RED, + "red"}, + {"green string", + Color::GREEN, + "green"}, + {"blue string", + Color::BLUE, + "blue"}, + {"yellow string", + Color::YELLOW, + "yellow"}, + { + "magenta string", + Color::MAGENTA, + "magenta", + }, + {"cyan string", + Color::CYAN, + "cyan"}, + {"transparent string", + Color::TRANSPARENT, + "transparent"}, + {"hex color", + Vector4(0.4f, 0.5f, 0.6f, 1.f), + "0xff667f99"}, + }; const unsigned int numberOfTests = 10u; - for( unsigned int index = 0u; index < numberOfTests; ++index ) + for(unsigned int index = 0u; index < numberOfTests; ++index) { ToolkitTestApplication application; - if( !Vector4ToColorStringTest( data[index] ) ) + if(!Vector4ToColorStringTest(data[index])) { tet_result(TET_FAIL); } @@ -432,29 +374,22 @@ int UtcDaliTextStringToVector2(void) { tet_infoline(" UtcDaliTextStringToVector2"); const StringToVector2Data data[] = - { { - "void text", - "", - Vector2::ZERO - }, - { - "zero zero", - "0 0", - Vector2::ZERO - }, - { - "five four", - "5 4", - Vector2(5.f, 4.f) - } - }; + {"void text", + "", + Vector2::ZERO}, + {"zero zero", + "0 0", + Vector2::ZERO}, + {"five four", + "5 4", + Vector2(5.f, 4.f)}}; const unsigned int numberOfTests = 3u; - for( unsigned int index = 0u; index < numberOfTests; ++index ) + for(unsigned int index = 0u; index < numberOfTests; ++index) { ToolkitTestApplication application; - if( !StringToVector2Test( data[index] ) ) + if(!StringToVector2Test(data[index])) { tet_result(TET_FAIL); } @@ -468,24 +403,23 @@ int UtcDaliTextVector2ToString(void) { tet_infoline(" UtcDaliTextVector2ToString"); const Vector2ToStringData data[] = - { { - "zero zero", - Vector2::ZERO, - "0 0", - }, - { - "five four", - Vector2(5.f, 4.f), - "5 4", - } - }; + { + "zero zero", + Vector2::ZERO, + "0 0", + }, + { + "five four", + Vector2(5.f, 4.f), + "5 4", + }}; const unsigned int numberOfTests = 2u; - for( unsigned int index = 0u; index < numberOfTests; ++index ) + for(unsigned int index = 0u; index < numberOfTests; ++index) { ToolkitTestApplication application; - if( !Vector2ToStringTest( data[index] ) ) + if(!Vector2ToStringTest(data[index])) { tet_result(TET_FAIL); } @@ -499,44 +433,31 @@ int UtcDaliTextXHTMLEntityToUTF8(void) { tet_infoline(" UtcDaliTextXHTMLEntityToUTF8"); const XHTMLEntityToUTF8Data data[] = - { { - "Text Without XHTML Entity", - "Checking XHTML Entitities", - "Checking XHTML Entitities" - }, - { - "Text With XHTML Entity in Numeric form", - "Checking Numeric Entitities & ' < > ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å æ Ç È É Ê Ë Ì Í Î Ï ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ý þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ σ τ υ φ χ ψ ω … € ← ↑ → ↓ ↔ ← → ∀ ∃ ∇ ∏ ∑ ∧ ∨ ∫ ≠ ≡ ⊕ ⊥ † ‡ • ", - "Checking Numeric Entitities & ' < > ¡ ¢ £ ¤ Â¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å æ Ç È É Ê Ë Ì Í Î Ï ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ý þ ß à á â ã ä Ã¥ æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ σ τ υ φ χ ψ ω … € ← ↑ → ↓ ↔ ← → ∀ ∃ ∇ ∏ ∑ ∧ ∨ ∫ ≠ ≡ ⊕ ⊥ † ‡ • " - }, - { - "Text With XHTML Named Entities", - "Checking Named Entitities & ' < > ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å æ Ç È É Ê Ë Ì Í Î Ï ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ý þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ σ τ υ φ χ ψ ω … € ← ↑ → ↓ ↔ ← → ∀ ∃ ∇ ∏ ∑ ∧ ∨ ∫ ≠ ≡ ⊕ ⊥ † ‡ • ", - "Checking Named Entitities & ' < > ¡ ¢ £ ¤ Â¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å æ Ç È É Ê Ë Ì Í Î Ï ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ý þ ß à á â ã ä Ã¥ æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ σ τ υ φ χ ψ ω … € ← ↑ → ↓ ↔ ← → ∀ ∃ ∇ ∏ ∑ ∧ ∨ ∫ ≠ ≡ ⊕ ⊥ † ‡ • " - }, - { - "Testing of < special character", - "Testing of < special character", - "Testing of " - }, - { - "Testing of & special character", - "Testing of & special character", - "Testing of " - }, - { - "Testing of & < > special character", - "Testing of \\& \\< \\> special character", - "Testing of & < > special character" - } - }; + {"Text Without XHTML Entity", + "Checking XHTML Entitities", + "Checking XHTML Entitities"}, + {"Text With XHTML Entity in Numeric form", + "Checking Numeric Entitities & ' < > ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å æ Ç È É Ê Ë Ì Í Î Ï ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ý þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ σ τ υ φ χ ψ ω … € ← ↑ → ↓ ↔ ← → ∀ ∃ ∇ ∏ ∑ ∧ ∨ ∫ ≠ ≡ ⊕ ⊥ † ‡ • ", + "Checking Numeric Entitities & ' < > ¡ ¢ £ ¤ Â¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å æ Ç È É Ê Ë Ì Í Î Ï ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ý þ ß à á â ã ä Ã¥ æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ σ τ υ φ χ ψ ω … € ← ↑ → ↓ ↔ ← → ∀ ∃ ∇ ∏ ∑ ∧ ∨ ∫ ≠ ≡ ⊕ ⊥ † ‡ • "}, + {"Text With XHTML Named Entities", + "Checking Named Entitities & ' < > ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å æ Ç È É Ê Ë Ì Í Î Ï ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ý þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ σ τ υ φ χ ψ ω … € ← ↑ → ↓ ↔ ← → ∀ ∃ ∇ ∏ ∑ ∧ ∨ ∫ ≠ ≡ ⊕ ⊥ † ‡ • ", + "Checking Named Entitities & ' < > ¡ ¢ £ ¤ Â¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å æ Ç È É Ê Ë Ì Í Î Ï ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ý þ ß à á â ã ä Ã¥ æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ σ τ υ φ χ ψ ω … € ← ↑ → ↓ ↔ ← → ∀ ∃ ∇ ∏ ∑ ∧ ∨ ∫ ≠ ≡ ⊕ ⊥ † ‡ • "}, + {"Testing of < special character", + "Testing of < special character", + "Testing of "}, + {"Testing of & special character", + "Testing of & special character", + "Testing of "}, + {"Testing of & < > special character", + "Testing of \\& \\< \\> special character", + "Testing of & < > special character"}}; const unsigned int numberOfTests = 6u; - for( unsigned int index = 0u; index < numberOfTests; ++index ) + for(unsigned int index = 0u; index < numberOfTests; ++index) { ToolkitTestApplication application; - if( !XHTMLEntityToUTF8Test( data[index] ) ) + if(!XHTMLEntityToUTF8Test(data[index])) { tet_result(TET_FAIL); } 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 e588998..0c55d97 100644 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-TextEditor-internal.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-TextEditor-internal.cpp @@ -336,4 +336,43 @@ int UtcDaliTextEditorTextPositionWithMinLineAndBigFont(void) DALI_TEST_EQUALS(positions[2].y, 165.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION); END_TEST; -} \ No newline at end of file +} + +int UtcDaliTextEditorMarkupStrikethrough(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliTextEditorMarkupStrikethrough "); + + 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 expectedNumberOfStrikethroughGlyphs = 2u; + + Toolkit::Internal::TextEditor& textEditorImpl = GetImpl(textEditor); + const Text::Length numberOfStrikethroughRuns = textEditorImpl.GetTextController()->GetTextModel()->GetNumberOfStrikethroughRuns(); + + DALI_TEST_EQUALS(numberOfStrikethroughRuns, expectedNumberOfStrikethroughGlyphs, TEST_LOCATION); + + Vector strikethroughRuns; + strikethroughRuns.Resize(numberOfStrikethroughRuns); + textEditorImpl.GetTextController()->GetTextModel()->GetStrikethroughRuns(strikethroughRuns.Begin(), 0u, numberOfStrikethroughRuns); + + //ABC have strikethrough + DALI_TEST_EQUALS(strikethroughRuns[0u].glyphRun.glyphIndex, 0u, TEST_LOCATION); + DALI_TEST_EQUALS(strikethroughRuns[0u].glyphRun.numberOfGlyphs, 3u, TEST_LOCATION); + DALI_TEST_CHECK(!strikethroughRuns[0u].isColorSet); + + //GH have strikethrough + DALI_TEST_EQUALS(strikethroughRuns[1u].glyphRun.glyphIndex, 5u, TEST_LOCATION); + DALI_TEST_EQUALS(strikethroughRuns[1u].glyphRun.numberOfGlyphs, 2u, TEST_LOCATION); + DALI_TEST_CHECK(strikethroughRuns[1u].isColorSet); + + END_TEST; +} 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 old mode 100755 new mode 100644 index 7cf4084..57fb32b --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-TextField-internal.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-TextField-internal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -15,16 +15,16 @@ * */ -#include #include +#include #include #include -#include #include -#include +#include #include +#include using namespace Dali; using namespace Toolkit; @@ -33,64 +33,64 @@ using namespace Text; int UtcDaliTextFieldMultipleBackgroundText(void) { ToolkitTestApplication application; - tet_infoline( "UtcDaliTextFieldMultipleBackgroundText" ); + tet_infoline("UtcDaliTextFieldMultipleBackgroundText"); // Create a text field TextField textField = TextField::New(); - textField.SetProperty( Actor::Property::SIZE, Vector2( 400.f, 60.f ) ); - textField.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT ); - textField.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT ); + textField.SetProperty(Actor::Property::SIZE, Vector2(400.f, 60.f)); + textField.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT); + textField.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); // Add the text field to the stage - application.GetScene().Add( textField ); + application.GetScene().Add(textField); application.SendNotification(); application.Render(); - Toolkit::Internal::TextField& textFieldImpl = GetImpl( textField ); - ControllerPtr controller = textFieldImpl.GetTextController(); - Controller::Impl& controllerImpl = Controller::Impl::GetImplementation( *controller.Get() ); + Toolkit::Internal::TextField& textFieldImpl = GetImpl(textField); + ControllerPtr controller = textFieldImpl.GetTextController(); + Controller::Impl& controllerImpl = Controller::Impl::GetImplementation(*controller.Get()); // Add multiple background colors for the text. ColorRun backgroundColorRun1; - backgroundColorRun1.characterRun.characterIndex = 0u; + backgroundColorRun1.characterRun.characterIndex = 0u; backgroundColorRun1.characterRun.numberOfCharacters = 1u; - backgroundColorRun1.color = Color::RED; - controllerImpl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack( backgroundColorRun1 ); + backgroundColorRun1.color = Color::RED; + controllerImpl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun1); ColorRun backgroundColorRun2; - backgroundColorRun2.characterRun.characterIndex = 5u; + backgroundColorRun2.characterRun.characterIndex = 5u; backgroundColorRun2.characterRun.numberOfCharacters = 8u; - backgroundColorRun2.color = Color::CYAN; - controllerImpl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack( backgroundColorRun2 ); + backgroundColorRun2.color = Color::CYAN; + controllerImpl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun2); ColorRun backgroundColorRun3; - backgroundColorRun3.characterRun.characterIndex = 23u; + backgroundColorRun3.characterRun.characterIndex = 23u; backgroundColorRun3.characterRun.numberOfCharacters = 6u; - backgroundColorRun3.color = Color::GREEN; - controllerImpl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack( backgroundColorRun3 ); + backgroundColorRun3.color = Color::GREEN; + controllerImpl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun3); // Check the case where there is only one character in the text - controller->SetText( "S" ); + controller->SetText("S"); application.SendNotification(); application.Render(); // The offscreen root actor should have one child: the renderable. - Actor stencil = textField.GetChildAt( 0u ); - DALI_TEST_CHECK( stencil.GetChildCount() == 1u ); + Actor stencil = textField.GetChildAt(0u); + DALI_TEST_CHECK(stencil.GetChildCount() == 1u); // The renderable actor should have two children: the text and the background. - Actor renderableActor = stencil.GetChildAt( 0u ); - DALI_TEST_CHECK( renderableActor.GetChildCount() == 2u ); + Actor renderableActor = stencil.GetChildAt(0u); + DALI_TEST_CHECK(renderableActor.GetChildCount() == 2u); // Check that the background is created - Actor backgroundActor = renderableActor.GetChildAt( 0u ); - DALI_TEST_CHECK( backgroundActor ); - DALI_TEST_CHECK( backgroundActor.GetProperty< std::string >( Dali::Actor::Property::NAME ) == "TextBackgroundColorActor" ); + Actor backgroundActor = renderableActor.GetChildAt(0u); + DALI_TEST_CHECK(backgroundActor); + DALI_TEST_CHECK(backgroundActor.GetProperty(Dali::Actor::Property::NAME) == "TextBackgroundColorActor"); // Change the text to contain more characters - controller->SetText( "Text Multiple Background Test" ); + controller->SetText("Text Multiple Background Test"); application.SendNotification(); application.Render(); @@ -102,14 +102,14 @@ int UtcDaliTextFieldMultipleBackgroundText(void) application.Render(); // Now the offscreen root actor should have three children: the renderable, the highlight, and the background. - DALI_TEST_CHECK( stencil.GetChildCount() == 3u ); + DALI_TEST_CHECK(stencil.GetChildCount() == 3u); // The renderable actor should have one child only: the text - DALI_TEST_CHECK( renderableActor.GetChildCount() == 1u ); + DALI_TEST_CHECK(renderableActor.GetChildCount() == 1u); // The background should now be lowered below the highlight - backgroundActor = stencil.GetChildAt( 0u ); - DALI_TEST_CHECK( backgroundActor ); - DALI_TEST_CHECK( backgroundActor.GetProperty< std::string >( Dali::Actor::Property::NAME ) == "TextBackgroundColorActor" ); + backgroundActor = stencil.GetChildAt(0u); + DALI_TEST_CHECK(backgroundActor); + DALI_TEST_CHECK(backgroundActor.GetProperty(Dali::Actor::Property::NAME) == "TextBackgroundColorActor"); END_TEST; } @@ -117,20 +117,20 @@ int UtcDaliTextFieldMultipleBackgroundText(void) int UtcDaliTextFieldSelectText(void) { ToolkitTestApplication application; - tet_infoline( "UtcDaliTextFieldSelectText" ); + tet_infoline("UtcDaliTextFieldSelectText"); // Create a text field TextField textField = TextField::New(); - textField.SetProperty( Actor::Property::SIZE, Vector2( 400.f, 60.f ) ); - textField.SetProperty( TextField::Property::TEXT, "Hello World" ); + textField.SetProperty(Actor::Property::SIZE, Vector2(400.f, 60.f)); + textField.SetProperty(TextField::Property::TEXT, "Hello World"); // Add the text field to the stage - application.GetScene().Add( textField ); + application.GetScene().Add(textField); application.SendNotification(); application.Render(); - Toolkit::Internal::TextField& textFieldImpl = GetImpl( textField ); + Toolkit::Internal::TextField& textFieldImpl = GetImpl(textField); application.SendNotification(); application.Render(); @@ -141,7 +141,7 @@ int UtcDaliTextFieldSelectText(void) application.SendNotification(); application.Render(); - DALI_TEST_CHECK( textFieldImpl.GetSelectedText() == "Hello World" ); + DALI_TEST_CHECK(textFieldImpl.GetSelectedText() == "Hello World"); // Select None textFieldImpl.SelectNone(); @@ -149,7 +149,7 @@ int UtcDaliTextFieldSelectText(void) application.SendNotification(); application.Render(); - DALI_TEST_CHECK( textFieldImpl.GetSelectedText() == "" ); + DALI_TEST_CHECK(textFieldImpl.GetSelectedText() == ""); END_TEST; } @@ -161,36 +161,35 @@ int UtcDaliTextFieldMarkupUnderline(void) TextField textField = TextField::New(); - application.GetScene().Add( textField ); + application.GetScene().Add(textField); - textField.SetProperty( TextField::Property::TEXT, "ABCEFGH" ); - textField.SetProperty( TextField ::Property::ENABLE_MARKUP, true ); + 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.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns(); + Toolkit::Internal::TextField& textFieldImpl = GetImpl(textField); + const Text::Length numberOfUnderlineRuns = textFieldImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns(); - DALI_TEST_EQUALS( numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION ); + DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION); Vector underlineRuns; underlineRuns.Resize(numberOfUnderlineRuns); textFieldImpl.GetTextController()->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); + 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); + DALI_TEST_EQUALS(underlineRuns[3u].glyphIndex, 5u, TEST_LOCATION); + DALI_TEST_EQUALS(underlineRuns[4u].glyphIndex, 6u, TEST_LOCATION); END_TEST; - } int UtcDaliTextFieldFontPointSizeLargerThanAtlas(void) @@ -201,23 +200,22 @@ int UtcDaliTextFieldFontPointSizeLargerThanAtlas(void) // Create a Text field TextField textField = TextField::New(); //Set size to avoid automatic eliding - textField.SetProperty( Actor::Property::SIZE, Vector2(1025, 1025)); + textField.SetProperty(Actor::Property::SIZE, Vector2(1025, 1025)); //Set very large font-size using point-size - textField.SetProperty( TextField::Property::POINT_SIZE, 1000) ; + textField.SetProperty(TextField::Property::POINT_SIZE, 1000); //Specify font-family - textField.SetProperty( TextField::Property::FONT_FAMILY, "DejaVu Sans"); + textField.SetProperty(TextField::Property::FONT_FAMILY, "DejaVu Sans"); //Set text to check if appear or not - textField.SetProperty( TextField::Property::TEXT, "A"); + textField.SetProperty(TextField::Property::TEXT, "A"); - application.GetScene().Add( textField ); + application.GetScene().Add(textField); application.SendNotification(); application.Render(); //Check if Glyph is added to AtlasGlyphManger or not int countAtlas = AtlasGlyphManager::Get().GetMetrics().mAtlasMetrics.mAtlasCount; - DALI_TEST_EQUALS( countAtlas, 1, TEST_LOCATION ); - + DALI_TEST_EQUALS(countAtlas, 1, TEST_LOCATION); END_TEST; } @@ -229,26 +227,25 @@ int UtcDaliTextFieldFontPointSizeLargerThanAtlasPlaceholderCase(void) //Set Map of placeholder: text, font-family and point-size Property::Map placeholderMapSet; - placeholderMapSet["text"] = "A"; + placeholderMapSet["text"] = "A"; placeholderMapSet["fontFamily"] = "DejaVu Sans"; - placeholderMapSet["pixelSize"] = 1000.0f; + placeholderMapSet["pixelSize"] = 1000.0f; // Create a text editor TextField textField = TextField::New(); //Set size to avoid automatic eliding - textField.SetProperty( Actor::Property::SIZE, Vector2(1025, 1025)); + textField.SetProperty(Actor::Property::SIZE, Vector2(1025, 1025)); //Set placeholder - textField.SetProperty( TextField::Property::PLACEHOLDER, placeholderMapSet) ; + textField.SetProperty(TextField::Property::PLACEHOLDER, placeholderMapSet); - application.GetScene().Add( textField ); + application.GetScene().Add(textField); application.SendNotification(); application.Render(); //Check if Glyph is added to AtlasGlyphManger or not int countAtlas = AtlasGlyphManager::Get().GetMetrics().mAtlasMetrics.mAtlasCount; - DALI_TEST_EQUALS( countAtlas, 1, TEST_LOCATION ); - + DALI_TEST_EQUALS(countAtlas, 1, TEST_LOCATION); END_TEST; } @@ -259,27 +256,27 @@ int UtcDaliTextFieldBackgroundTag(void) tet_infoline("UtcDaliTextFieldBackgroundTag\n"); TextField field = TextField::New(); - DALI_TEST_CHECK( field ); + DALI_TEST_CHECK(field); - field.SetProperty( TextField ::Property::ENABLE_MARKUP, true ); - field.SetProperty( TextField::Property::TEXT, "He World" ); - application.GetScene().Add( field ); + field.SetProperty(TextField ::Property::ENABLE_MARKUP, true); + field.SetProperty(TextField::Property::TEXT, "He World"); + application.GetScene().Add(field); application.SendNotification(); application.Render(); - Toolkit::Internal::TextField& fieldImpl = GetImpl( field ); - const ColorIndex* const backgroundColorIndicesBuffer = fieldImpl.GetTextController()->GetTextModel()->GetBackgroundColorIndices(); + Toolkit::Internal::TextField& fieldImpl = GetImpl(field); + const ColorIndex* const backgroundColorIndicesBuffer = fieldImpl.GetTextController()->GetTextModel()->GetBackgroundColorIndices(); - DALI_TEST_CHECK( backgroundColorIndicesBuffer ); + DALI_TEST_CHECK(backgroundColorIndicesBuffer); //default color - DALI_TEST_EQUALS( backgroundColorIndicesBuffer[0], 0u, TEST_LOCATION); + DALI_TEST_EQUALS(backgroundColorIndicesBuffer[0], 0u, TEST_LOCATION); //red color - DALI_TEST_EQUALS( backgroundColorIndicesBuffer[1], 1u, TEST_LOCATION); + DALI_TEST_EQUALS(backgroundColorIndicesBuffer[1], 1u, TEST_LOCATION); //yellow color - DALI_TEST_EQUALS( backgroundColorIndicesBuffer[7], 2u, TEST_LOCATION); + DALI_TEST_EQUALS(backgroundColorIndicesBuffer[7], 2u, TEST_LOCATION); END_TEST; } @@ -290,31 +287,30 @@ int UtcDaliToolkitTextFieldEllipsisInternalAPIs(void) tet_infoline(" UtcDaliToolkitTextFieldEllipsisInternalAPIs "); TextField textField = TextField::New(); - Toolkit::Internal::TextField& textFieldImpl = GetImpl( textField ); - Text::ViewInterface& view = textFieldImpl.GetTextController()->GetView(); + Toolkit::Internal::TextField& textFieldImpl = GetImpl(textField); + Text::ViewInterface& view = textFieldImpl.GetTextController()->GetView(); tet_infoline(" UtcDaliToolkitTextFieldEllipsisInternalAPIs - ELLIPSIS Disabled"); textField.SetProperty(DevelTextField::Property::ELLIPSIS, false); - DALI_TEST_EQUALS( textField.GetProperty< bool >( DevelTextField::Property::ELLIPSIS ), false, TEST_LOCATION ); + DALI_TEST_EQUALS(textField.GetProperty(DevelTextField::Property::ELLIPSIS), false, TEST_LOCATION); DALI_TEST_CHECK(!(view.IsTextElideEnabled())); tet_infoline(" UtcDaliToolkitTextFieldEllipsisInternalAPIs - ELLIPSIS Enabled"); textField.SetProperty(DevelTextField::Property::ELLIPSIS, true); - DALI_TEST_EQUALS( textField.GetProperty< bool >( DevelTextField::Property::ELLIPSIS ), true, TEST_LOCATION ); + DALI_TEST_EQUALS(textField.GetProperty(DevelTextField::Property::ELLIPSIS), true, TEST_LOCATION); DALI_TEST_CHECK(view.IsTextElideEnabled()); tet_infoline(" UtcDaliToolkitTextFieldEllipsisInternalAPIs - GetStartIndexOfElidedGlyphs Default"); - DALI_TEST_EQUALS( view.GetStartIndexOfElidedGlyphs(), 0u, TEST_LOCATION ); + DALI_TEST_EQUALS(view.GetStartIndexOfElidedGlyphs(), 0u, TEST_LOCATION); tet_infoline(" UtcDaliToolkitTextFieldEllipsisInternalAPIs - GetEndIndexOfElidedGlyphs Default"); - DALI_TEST_EQUALS( view.GetEndIndexOfElidedGlyphs(), 0u, TEST_LOCATION ); + DALI_TEST_EQUALS(view.GetEndIndexOfElidedGlyphs(), 0u, TEST_LOCATION); tet_infoline(" UtcDaliToolkitTextFieldEllipsisInternalAPIs - GetFirstMiddleIndexOfElidedGlyphs Default"); - DALI_TEST_EQUALS( view.GetFirstMiddleIndexOfElidedGlyphs(), 0u, TEST_LOCATION ); + DALI_TEST_EQUALS(view.GetFirstMiddleIndexOfElidedGlyphs(), 0u, TEST_LOCATION); tet_infoline(" UtcDaliToolkitTextFieldEllipsisInternalAPIs - GetSecondMiddleIndexOfElidedGlyphs Default"); - DALI_TEST_EQUALS( view.GetSecondMiddleIndexOfElidedGlyphs(), 0u, TEST_LOCATION ); - + DALI_TEST_EQUALS(view.GetSecondMiddleIndexOfElidedGlyphs(), 0u, TEST_LOCATION); END_TEST; } @@ -324,17 +320,17 @@ int UtcDaliTextFieldTextWithSpan(void) tet_infoline("UtcDaliTextFieldTextWithSpan\n"); TextField field = TextField::New(); - DALI_TEST_CHECK( field ); + DALI_TEST_CHECK(field); - field.SetProperty( TextField ::Property::ENABLE_MARKUP, true ); - field.SetProperty( TextField::Property::TEXT, "Hello Span" ); - application.GetScene().Add( field ); + field.SetProperty(TextField ::Property::ENABLE_MARKUP, true); + field.SetProperty(TextField::Property::TEXT, "Hello Span"); + application.GetScene().Add(field); application.SendNotification(); application.Render(); Vector3 originalSize = field.GetNaturalSize(); - field.SetProperty( TextField::Property::TEXT, "Hello Span" ); + field.SetProperty(TextField::Property::TEXT, "Hello Span"); application.SendNotification(); application.Render(); @@ -343,41 +339,40 @@ int UtcDaliTextFieldTextWithSpan(void) DALI_TEST_GREATER(spanSize.width, originalSize.width, TEST_LOCATION); - Toolkit::Internal::TextField& fieldImpl = GetImpl( field ); - const ColorIndex* const colorIndicesBuffer1 = fieldImpl.GetTextController()->GetTextModel()->GetColorIndices(); + Toolkit::Internal::TextField& fieldImpl = GetImpl(field); + const ColorIndex* const colorIndicesBuffer1 = fieldImpl.GetTextController()->GetTextModel()->GetColorIndices(); - DALI_TEST_CHECK( colorIndicesBuffer1 ); + DALI_TEST_CHECK(colorIndicesBuffer1); //default color - DALI_TEST_EQUALS( colorIndicesBuffer1[0], 0u, TEST_LOCATION); + DALI_TEST_EQUALS(colorIndicesBuffer1[0], 0u, TEST_LOCATION); //span color - DALI_TEST_EQUALS( colorIndicesBuffer1[1], 1u, TEST_LOCATION); + DALI_TEST_EQUALS(colorIndicesBuffer1[1], 1u, TEST_LOCATION); //default color - DALI_TEST_EQUALS( colorIndicesBuffer1[6], 0u, TEST_LOCATION); - + DALI_TEST_EQUALS(colorIndicesBuffer1[6], 0u, TEST_LOCATION); - field.SetProperty( TextField::Property::TEXT, "Hello Span" ); + field.SetProperty(TextField::Property::TEXT, "Hello Span"); application.SendNotification(); application.Render(); const ColorIndex* const colorIndicesBuffer2 = fieldImpl.GetTextController()->GetTextModel()->GetColorIndices(); - DALI_TEST_CHECK( colorIndicesBuffer2 ); + DALI_TEST_CHECK(colorIndicesBuffer2); //default color - DALI_TEST_EQUALS( colorIndicesBuffer2[0], 0u, TEST_LOCATION); + DALI_TEST_EQUALS(colorIndicesBuffer2[0], 0u, TEST_LOCATION); //default color - DALI_TEST_EQUALS( colorIndicesBuffer2[1], 0u, TEST_LOCATION); + DALI_TEST_EQUALS(colorIndicesBuffer2[1], 0u, TEST_LOCATION); //span color - DALI_TEST_EQUALS( colorIndicesBuffer2[6], 1u, TEST_LOCATION); + DALI_TEST_EQUALS(colorIndicesBuffer2[6], 1u, TEST_LOCATION); //default color - DALI_TEST_EQUALS( colorIndicesBuffer2[7], 0u, TEST_LOCATION); + DALI_TEST_EQUALS(colorIndicesBuffer2[7], 0u, TEST_LOCATION); END_TEST; } @@ -397,9 +392,9 @@ int UtcDaliTextFieldControlBackgroundColor(void) application.SendNotification(); application.Render(); - Toolkit::Internal::TextField& fieldImpl = GetImpl(field); - ControllerPtr controller = fieldImpl.GetTextController(); - Controller::Impl& controllerImpl = Controller::Impl::GetImplementation(*controller.Get()); + Toolkit::Internal::TextField& fieldImpl = GetImpl(field); + ControllerPtr controller = fieldImpl.GetTextController(); + Controller::Impl& controllerImpl = Controller::Impl::GetImplementation(*controller.Get()); // Default color is transparent controllerImpl.mEditableControlInterface->GetControlBackgroundColor(backgroundColor); @@ -416,3 +411,42 @@ int UtcDaliTextFieldControlBackgroundColor(void) END_TEST; } + +int UtcDaliTextFieldMarkupStrikethrough(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliTextFieldMarkupStrikethrough "); + + 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 expectedNumberOfStrikethroughGlyphs = 2u; + + Toolkit::Internal::TextField& textFieldImpl = GetImpl(textField); + const Text::Length numberOfStrikethroughRuns = textFieldImpl.GetTextController()->GetTextModel()->GetNumberOfStrikethroughRuns(); + + DALI_TEST_EQUALS(numberOfStrikethroughRuns, expectedNumberOfStrikethroughGlyphs, TEST_LOCATION); + + Vector strikethroughRuns; + strikethroughRuns.Resize(numberOfStrikethroughRuns); + textFieldImpl.GetTextController()->GetTextModel()->GetStrikethroughRuns(strikethroughRuns.Begin(), 0u, numberOfStrikethroughRuns); + + //ABC have strikethrough + DALI_TEST_EQUALS(strikethroughRuns[0u].glyphRun.glyphIndex, 0u, TEST_LOCATION); + DALI_TEST_EQUALS(strikethroughRuns[0u].glyphRun.numberOfGlyphs, 3u, TEST_LOCATION); + DALI_TEST_CHECK(!strikethroughRuns[0u].isColorSet); + + //GH have strikethrough + DALI_TEST_EQUALS(strikethroughRuns[1u].glyphRun.glyphIndex, 5u, TEST_LOCATION); + DALI_TEST_EQUALS(strikethroughRuns[1u].glyphRun.numberOfGlyphs, 2u, TEST_LOCATION); + DALI_TEST_CHECK(strikethroughRuns[1u].isColorSet); + + END_TEST; +} 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 old mode 100755 new mode 100644 index b72dcb4..5af84d4 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-TextLabel-internal.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-TextLabel-internal.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -15,17 +15,17 @@ * */ -#include #include +#include #include #include #include -#include -#include #include #include +#include +#include using namespace Dali; using namespace Toolkit; @@ -38,36 +38,35 @@ int UtcDaliTextLabelMarkupUnderline(void) TextLabel textLabel = TextLabel::New(); - application.GetScene().Add( textLabel ); + application.GetScene().Add(textLabel); - textLabel.SetProperty( TextLabel::Property::TEXT, "ABCEFGH" ); - textLabel.SetProperty( TextLabel ::Property::ENABLE_MARKUP, true ); + 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.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns(); + Toolkit::Internal::TextLabel& textLabelImpl = GetImpl(textLabel); + const Text::Length numberOfUnderlineRuns = textLabelImpl.GetTextController()->GetTextModel()->GetNumberOfUnderlineRuns(); - DALI_TEST_EQUALS( numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION ); + DALI_TEST_EQUALS(numberOfUnderlineRuns, expectedNumberOfUnderlinedGlyphs, TEST_LOCATION); Vector underlineRuns; underlineRuns.Resize(numberOfUnderlineRuns); textLabelImpl.GetTextController()->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); + 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); + DALI_TEST_EQUALS(underlineRuns[3u].glyphIndex, 5u, TEST_LOCATION); + DALI_TEST_EQUALS(underlineRuns[4u].glyphIndex, 6u, TEST_LOCATION); END_TEST; - } int UtcDaliTextLabelBackgroundTag(void) @@ -76,27 +75,27 @@ int UtcDaliTextLabelBackgroundTag(void) tet_infoline("UtcDaliTextLabelBackgroundTag\n"); TextLabel label = TextLabel::New(); - DALI_TEST_CHECK( label ); + DALI_TEST_CHECK(label); - label.SetProperty( TextLabel ::Property::ENABLE_MARKUP, true ); - label.SetProperty( TextLabel::Property::TEXT, "He World" ); - application.GetScene().Add( label ); + label.SetProperty(TextLabel ::Property::ENABLE_MARKUP, true); + label.SetProperty(TextLabel::Property::TEXT, "He World"); + application.GetScene().Add(label); application.SendNotification(); application.Render(); - Toolkit::Internal::TextLabel& labelImpl = GetImpl( label ); - const ColorIndex* const backgroundColorIndicesBuffer = labelImpl.GetTextController()->GetTextModel()->GetBackgroundColorIndices(); + Toolkit::Internal::TextLabel& labelImpl = GetImpl(label); + const ColorIndex* const backgroundColorIndicesBuffer = labelImpl.GetTextController()->GetTextModel()->GetBackgroundColorIndices(); - DALI_TEST_CHECK( backgroundColorIndicesBuffer ); + DALI_TEST_CHECK(backgroundColorIndicesBuffer); //default color - DALI_TEST_EQUALS( backgroundColorIndicesBuffer[0], 0u, TEST_LOCATION); + DALI_TEST_EQUALS(backgroundColorIndicesBuffer[0], 0u, TEST_LOCATION); //red color - DALI_TEST_EQUALS( backgroundColorIndicesBuffer[1], 1u, TEST_LOCATION); + DALI_TEST_EQUALS(backgroundColorIndicesBuffer[1], 1u, TEST_LOCATION); //yellow color - DALI_TEST_EQUALS( backgroundColorIndicesBuffer[7], 2u, TEST_LOCATION); + DALI_TEST_EQUALS(backgroundColorIndicesBuffer[7], 2u, TEST_LOCATION); END_TEST; } @@ -107,34 +106,33 @@ int UtcDaliToolkitTextlabelEllipsisInternalAPIs(void) tet_infoline(" UtcDaliToolkitTextlabelEllipsisInternalAPIs "); TextLabel textLabel = TextLabel::New(); - Toolkit::Internal::TextLabel& textLabelImpl = GetImpl( textLabel ); - const ModelInterface* const textModel = textLabelImpl.GetTextController()->GetTextModel(); - + Toolkit::Internal::TextLabel& textLabelImpl = GetImpl(textLabel); + const ModelInterface* const textModel = textLabelImpl.GetTextController()->GetTextModel(); tet_infoline(" UtcDaliToolkitTextlabelEllipsisInternalAPIs - ELLIPSIS Disabled"); textLabel.SetProperty(DevelTextLabel::Property::ELLIPSIS, false); - DALI_TEST_EQUALS( textLabel.GetProperty< bool >( DevelTextLabel::Property::ELLIPSIS ), false, TEST_LOCATION ); + DALI_TEST_EQUALS(textLabel.GetProperty(DevelTextLabel::Property::ELLIPSIS), false, TEST_LOCATION); DALI_TEST_CHECK(!(textModel->IsTextElideEnabled())); tet_infoline(" UtcDaliToolkitTextlabelEllipsisInternalAPIs - ELLIPSIS Enabled"); textLabel.SetProperty(DevelTextLabel::Property::ELLIPSIS, true); - DALI_TEST_EQUALS( textLabel.GetProperty< bool >( DevelTextLabel::Property::ELLIPSIS ), true, TEST_LOCATION ); + DALI_TEST_EQUALS(textLabel.GetProperty(DevelTextLabel::Property::ELLIPSIS), true, TEST_LOCATION); DALI_TEST_CHECK(textModel->IsTextElideEnabled()); tet_infoline(" UtcDaliToolkitTextlabelEllipsisInternalAPIs - GetStartIndexOfElidedGlyphs Default"); - DALI_TEST_EQUALS( textModel->GetStartIndexOfElidedGlyphs(), 0u, TEST_LOCATION ); + DALI_TEST_EQUALS(textModel->GetStartIndexOfElidedGlyphs(), 0u, TEST_LOCATION); tet_infoline(" UtcDaliToolkitTextlabelEllipsisInternalAPIs - GetEndIndexOfElidedGlyphs Default"); - DALI_TEST_EQUALS( textModel->GetEndIndexOfElidedGlyphs(), 0u, TEST_LOCATION ); + DALI_TEST_EQUALS(textModel->GetEndIndexOfElidedGlyphs(), 0u, TEST_LOCATION); tet_infoline(" UtcDaliToolkitTextlabelEllipsisInternalAPIs - GetFirstMiddleIndexOfElidedGlyphs Default"); - DALI_TEST_EQUALS( textModel->GetFirstMiddleIndexOfElidedGlyphs(), 0u, TEST_LOCATION ); + DALI_TEST_EQUALS(textModel->GetFirstMiddleIndexOfElidedGlyphs(), 0u, TEST_LOCATION); tet_infoline(" UtcDaliToolkitTextlabelEllipsisInternalAPIs - GetSecondMiddleIndexOfElidedGlyphs Default"); - DALI_TEST_EQUALS( textModel->GetSecondMiddleIndexOfElidedGlyphs(), 0u, TEST_LOCATION ); + DALI_TEST_EQUALS(textModel->GetSecondMiddleIndexOfElidedGlyphs(), 0u, TEST_LOCATION); // Tests the rendering controller has been created. - TypesetterPtr typesetter = Typesetter::New( textModel ); + TypesetterPtr typesetter = Typesetter::New(textModel); DALI_TEST_CHECK(typesetter); // Tests the view model has been created. @@ -144,16 +142,16 @@ int UtcDaliToolkitTextlabelEllipsisInternalAPIs(void) DALI_TEST_CHECK(model->IsTextElideEnabled()); tet_infoline(" UtcDaliToolkitTextlabelEllipsisInternalAPIs - GetStartIndexOfElidedGlyphs ViewModel"); - DALI_TEST_EQUALS( model->GetStartIndexOfElidedGlyphs(), 0u, TEST_LOCATION ); + DALI_TEST_EQUALS(model->GetStartIndexOfElidedGlyphs(), 0u, TEST_LOCATION); tet_infoline(" UtcDaliToolkitTextlabelEllipsisInternalAPIs - GetEndIndexOfElidedGlyphs ViewModel"); - DALI_TEST_EQUALS( model->GetEndIndexOfElidedGlyphs(), 0u, TEST_LOCATION ); + DALI_TEST_EQUALS(model->GetEndIndexOfElidedGlyphs(), 0u, TEST_LOCATION); tet_infoline(" UtcDaliToolkitTextlabelEllipsisInternalAPIs - GetFirstMiddleIndexOfElidedGlyphs ViewModel"); - DALI_TEST_EQUALS( model->GetFirstMiddleIndexOfElidedGlyphs(), 0u, TEST_LOCATION ); + DALI_TEST_EQUALS(model->GetFirstMiddleIndexOfElidedGlyphs(), 0u, TEST_LOCATION); tet_infoline(" UtcDaliToolkitTextlabelEllipsisInternalAPIs - GetSecondMiddleIndexOfElidedGlyphs ViewModel"); - DALI_TEST_EQUALS( model->GetSecondMiddleIndexOfElidedGlyphs(), 0u, TEST_LOCATION ); + DALI_TEST_EQUALS(model->GetSecondMiddleIndexOfElidedGlyphs(), 0u, TEST_LOCATION); END_TEST; } @@ -163,17 +161,17 @@ int UtcDaliTextLabelTextWithSpan(void) tet_infoline("UtcDaliTextLabelTextWithSpan\n"); TextLabel label = TextLabel::New(); - DALI_TEST_CHECK( label ); + DALI_TEST_CHECK(label); - label.SetProperty( TextLabel ::Property::ENABLE_MARKUP, true ); - label.SetProperty( TextLabel::Property::TEXT, "Hello Span" ); - application.GetScene().Add( label ); + label.SetProperty(TextLabel ::Property::ENABLE_MARKUP, true); + label.SetProperty(TextLabel::Property::TEXT, "Hello Span"); + application.GetScene().Add(label); application.SendNotification(); application.Render(); Vector3 originalSize = label.GetNaturalSize(); - label.SetProperty( TextLabel::Property::TEXT, "Hello Span" ); + label.SetProperty(TextLabel::Property::TEXT, "Hello Span"); application.SendNotification(); application.Render(); @@ -182,41 +180,79 @@ int UtcDaliTextLabelTextWithSpan(void) DALI_TEST_GREATER(spanSize.width, originalSize.width, TEST_LOCATION); - Toolkit::Internal::TextLabel& labelImpl = GetImpl( label ); - const ColorIndex* const colorIndicesBuffer1 = labelImpl.GetTextController()->GetTextModel()->GetColorIndices(); + Toolkit::Internal::TextLabel& labelImpl = GetImpl(label); + const ColorIndex* const colorIndicesBuffer1 = labelImpl.GetTextController()->GetTextModel()->GetColorIndices(); - DALI_TEST_CHECK( colorIndicesBuffer1 ); + DALI_TEST_CHECK(colorIndicesBuffer1); //default color - DALI_TEST_EQUALS( colorIndicesBuffer1[0], 0u, TEST_LOCATION); + DALI_TEST_EQUALS(colorIndicesBuffer1[0], 0u, TEST_LOCATION); //span color - DALI_TEST_EQUALS( colorIndicesBuffer1[1], 1u, TEST_LOCATION); + DALI_TEST_EQUALS(colorIndicesBuffer1[1], 1u, TEST_LOCATION); //default color - DALI_TEST_EQUALS( colorIndicesBuffer1[6], 0u, TEST_LOCATION); - + DALI_TEST_EQUALS(colorIndicesBuffer1[6], 0u, TEST_LOCATION); - label.SetProperty( TextLabel::Property::TEXT, "Hello Span" ); + label.SetProperty(TextLabel::Property::TEXT, "Hello Span"); application.SendNotification(); application.Render(); const ColorIndex* const colorIndicesBuffer2 = labelImpl.GetTextController()->GetTextModel()->GetColorIndices(); - DALI_TEST_CHECK( colorIndicesBuffer2 ); + DALI_TEST_CHECK(colorIndicesBuffer2); //default color - DALI_TEST_EQUALS( colorIndicesBuffer2[0], 0u, TEST_LOCATION); + DALI_TEST_EQUALS(colorIndicesBuffer2[0], 0u, TEST_LOCATION); //default color - DALI_TEST_EQUALS( colorIndicesBuffer2[1], 0u, TEST_LOCATION); + DALI_TEST_EQUALS(colorIndicesBuffer2[1], 0u, TEST_LOCATION); //span color - DALI_TEST_EQUALS( colorIndicesBuffer2[6], 1u, TEST_LOCATION); + DALI_TEST_EQUALS(colorIndicesBuffer2[6], 1u, TEST_LOCATION); //default color - DALI_TEST_EQUALS( colorIndicesBuffer2[7], 0u, TEST_LOCATION); + DALI_TEST_EQUALS(colorIndicesBuffer2[7], 0u, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliTextLabelMarkupStrikethrough(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliTextLabelMarkupStrikethrough "); + + 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 expectedNumberOfStrikethroughGlyphs = 2u; + + Toolkit::Internal::TextLabel& textLabelImpl = GetImpl(textLabel); + const Text::Length numberOfStrikethroughRuns = textLabelImpl.GetTextController()->GetTextModel()->GetNumberOfStrikethroughRuns(); + + DALI_TEST_EQUALS(numberOfStrikethroughRuns, expectedNumberOfStrikethroughGlyphs, TEST_LOCATION); + + Vector strikethroughRuns; + strikethroughRuns.Resize(numberOfStrikethroughRuns); + textLabelImpl.GetTextController()->GetTextModel()->GetStrikethroughRuns(strikethroughRuns.Begin(), 0u, numberOfStrikethroughRuns); + + //ABC have strikethrough + DALI_TEST_EQUALS(strikethroughRuns[0u].glyphRun.glyphIndex, 0u, TEST_LOCATION); + DALI_TEST_EQUALS(strikethroughRuns[0u].glyphRun.numberOfGlyphs, 3u, TEST_LOCATION); + DALI_TEST_CHECK(!strikethroughRuns[0u].isColorSet); + + //GH have strikethrough + DALI_TEST_EQUALS(strikethroughRuns[1u].glyphRun.glyphIndex, 5u, TEST_LOCATION); + DALI_TEST_EQUALS(strikethroughRuns[1u].glyphRun.numberOfGlyphs, 2u, TEST_LOCATION); + DALI_TEST_CHECK(strikethroughRuns[1u].isColorSet); END_TEST; } diff --git a/dali-toolkit/devel-api/text/text-utils-devel.cpp b/dali-toolkit/devel-api/text/text-utils-devel.cpp index e4733c1..b4abff2 100644 --- a/dali-toolkit/devel-api/text/text-utils-devel.cpp +++ b/dali-toolkit/devel-api/text/text-utils-devel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -175,7 +175,8 @@ void ShapeTextPreprocess(const RendererParameters& textParameters, TextAbstracti textModel->mLogicalModel->mEmbeddedItems, textModel->mLogicalModel->mAnchors, textModel->mLogicalModel->mUnderlinedCharacterRuns, - textModel->mLogicalModel->mBackgroundColorRuns); + textModel->mLogicalModel->mBackgroundColorRuns, + textModel->mLogicalModel->mStrikethroughCharacterRuns); if(textParameters.markupEnabled) { diff --git a/dali-toolkit/internal/file.list b/dali-toolkit/internal/file.list index 0ad41cd..ddddf9a 100644 --- a/dali-toolkit/internal/file.list +++ b/dali-toolkit/internal/file.list @@ -148,6 +148,7 @@ SET( toolkit_src_files ${toolkit_src_dir}/text/markup-processor-font.cpp ${toolkit_src_dir}/text/markup-processor-background.cpp ${toolkit_src_dir}/text/markup-processor-span.cpp + ${toolkit_src_dir}/text/markup-processor-strikethrough.cpp ${toolkit_src_dir}/text/markup-processor-helper-functions.cpp ${toolkit_src_dir}/text/multi-language-support.cpp ${toolkit_src_dir}/text/hidden-text.cpp diff --git a/dali-toolkit/internal/text/logical-model-impl.cpp b/dali-toolkit/internal/text/logical-model-impl.cpp index 0de63d5..f1fd1f5 100644 --- a/dali-toolkit/internal/text/logical-model-impl.cpp +++ b/dali-toolkit/internal/text/logical-model-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -300,10 +300,18 @@ void LogicalModel::UpdateTextStyleRuns(CharacterIndex index, int numberOfCharact // Process the underlined runs. Vector removedUnderlinedCharacterRuns; UpdateCharacterRuns(index, - numberOfCharacters, - totalNumberOfCharacters, - mUnderlinedCharacterRuns, - removedUnderlinedCharacterRuns); + numberOfCharacters, + totalNumberOfCharacters, + mUnderlinedCharacterRuns, + removedUnderlinedCharacterRuns); + + // Process the strikethrough runs. + Vector removedStrikethroughCharacterRuns; + UpdateCharacterRuns(index, + numberOfCharacters, + totalNumberOfCharacters, + mStrikethroughCharacterRuns, + removedStrikethroughCharacterRuns); // Process the background color runs. Vector removedBackgroundColorRuns; diff --git a/dali-toolkit/internal/text/logical-model-impl.h b/dali-toolkit/internal/text/logical-model-impl.h index 80a1285..1bed342 100644 --- a/dali-toolkit/internal/text/logical-model-impl.h +++ b/dali-toolkit/internal/text/logical-model-impl.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_TEXT_LOGICAL_MODEL_IMPL_H /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -33,6 +33,7 @@ #include #include #include +#include #include namespace Dali @@ -220,7 +221,8 @@ public: Vector mBidirectionalLineInfo; Vector mEmbeddedItems; Vector mAnchors; - Vector mUnderlinedCharacterRuns; ///< The underlined character run from markup-processor + Vector mUnderlinedCharacterRuns; ///< The underlined character run from markup-processor + Vector mStrikethroughCharacterRuns; ///< The strikethrough character run from markup-processor BidirectionalLineRunIndex mBidirectionalLineIndex; ///< The last fetched bidirectional line info. }; diff --git a/dali-toolkit/internal/text/markup-processor-strikethrough.cpp b/dali-toolkit/internal/text/markup-processor-strikethrough.cpp new file mode 100644 index 0000000..9282121 --- /dev/null +++ b/dali-toolkit/internal/text/markup-processor-strikethrough.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2015 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. + * + */ + +// FILE HEADER +#include + +// EXTERNAL INCLUDES +#include + +// INTERNAL INCLUDES +#include +#include + +namespace Dali +{ +namespace Toolkit +{ +namespace Text +{ +namespace +{ +const std::string XHTML_COLOR_ATTRIBUTE("color"); +} + +void ProcessStrikethroughTag(const Tag& tag, StrikethroughCharacterRun& strikethroughRun) +{ + for(Vector::ConstIterator it = tag.attributes.Begin(), + endIt = tag.attributes.End(); + it != endIt; + ++it) + { + const Attribute& attribute(*it); + if(TokenComparison(XHTML_COLOR_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength)) + { + strikethroughRun.isColorSet = true; + ColorStringToVector4(attribute.valueBuffer, attribute.valueLength, strikethroughRun.color); + } + } +} + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/internal/text/markup-processor-strikethrough.h b/dali-toolkit/internal/text/markup-processor-strikethrough.h new file mode 100644 index 0000000..6c0a520 --- /dev/null +++ b/dali-toolkit/internal/text/markup-processor-strikethrough.h @@ -0,0 +1,44 @@ +#ifndef DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_STRIKETHROUGH_H +#define DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_STRIKETHROUGH_H + +/* + * Copyright (c) 2022 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. + * + */ + +namespace Dali +{ +namespace Toolkit +{ +namespace Text +{ +struct Tag; +struct StrikethroughCharacterRun; + +/** + * @brief Retrieves the strikethrough run info from the tag and sets it to the strikethrough run. + * + * @param[in] tag The strikethrough tag and its attributes. + * @param[in,out] strikethroughRun The strikethrough run. + */ +void ProcessStrikethroughTag(const Tag& tag, StrikethroughCharacterRun& strikethroughRun); + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali + +#endif // DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_STRIKETHROUGH_H diff --git a/dali-toolkit/internal/text/markup-processor.cpp b/dali-toolkit/internal/text/markup-processor.cpp index b656aa4..7ed1f61 100644 --- a/dali-toolkit/internal/text/markup-processor.cpp +++ b/dali-toolkit/internal/text/markup-processor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -32,6 +32,7 @@ #include #include #include +#include #include namespace Dali @@ -57,6 +58,7 @@ const std::string XHTML_ITEM_TAG("item"); const std::string XHTML_ANCHOR_TAG("a"); const std::string XHTML_BACKGROUND_TAG("background"); const std::string XHTML_SPAN_TAG("span"); +const std::string XHTML_STRIKETHROUGH_TAG("s"); const char LESS_THAN = '<'; const char GREATER_THAN = '>'; @@ -196,6 +198,18 @@ void Initialize(Span& span) } /** + * @brief Initializes a strikethrough character run to its defaults. + * + * @param[in,out] strikethroughCharacterRun The strikethrough character run to initialize. + */ +void Initialize(StrikethroughCharacterRun& strikethroughCharacterRun) +{ + strikethroughCharacterRun.characterRun.characterIndex = 0u; + strikethroughCharacterRun.characterRun.numberOfCharacters = 0u; + strikethroughCharacterRun.isColorSet = false; +} + +/** * @brief Splits the tag string into the tag name and its attributes. * * The attributes are stored in a vector in the tag. @@ -875,10 +889,11 @@ void ProcessMarkupString(const std::string& markupString, MarkupProcessData& mar StyleStack spanStack; // Points the next free position in the vector of runs. - RunIndex colorRunIndex = 0u; - RunIndex fontRunIndex = 0u; - RunIndex underlinedCharacterRunIndex = 0u; - RunIndex backgroundRunIndex = 0u; + RunIndex colorRunIndex = 0u; + RunIndex fontRunIndex = 0u; + RunIndex underlinedCharacterRunIndex = 0u; + RunIndex backgroundRunIndex = 0u; + RunIndex strikethroughCharacterRunIndex = 0u; // check tag reference int colorTagReference = 0u; @@ -888,6 +903,7 @@ void ProcessMarkupString(const std::string& markupString, MarkupProcessData& mar int uTagReference = 0u; int backgroundTagReference = 0u; int spanTagReference = 0u; + int sTagReference = 0u; // Give an initial default value to the model's vectors. markupProcessData.colorRuns.Reserve(DEFAULT_VECTOR_SIZE); @@ -979,7 +995,12 @@ void ProcessMarkupString(const std::string& markupString, MarkupProcessData& mar { ProcessSpanForRun(tag, spanStack, markupProcessData.colorRuns, markupProcessData.fontRuns, colorRunIndex, fontRunIndex, characterIndex, spanTagReference); } - } // end if( IsTag() ) + else if(TokenComparison(XHTML_STRIKETHROUGH_TAG, tag.buffer, tag.length)) + { + ProcessTagForRun( + markupProcessData.strikethroughCharacterRuns, styleStack, tag, characterIndex, strikethroughCharacterRunIndex, sTagReference, [](const Tag& tag, StrikethroughCharacterRun& run) { ProcessStrikethroughTag(tag, run); }); + } // + } // end if( IsTag() ) else if(markupStringBuffer < markupStringEndBuffer) { ProcessMarkupStringBuffer(markupProcessData, markupStringBuffer, markupStringEndBuffer, characterIndex); diff --git a/dali-toolkit/internal/text/markup-processor.h b/dali-toolkit/internal/text/markup-processor.h index e84b892..bb1b6ba 100644 --- a/dali-toolkit/internal/text/markup-processor.h +++ b/dali-toolkit/internal/text/markup-processor.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_H /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -27,6 +27,7 @@ #include #include #include +#include #include namespace Dali @@ -40,29 +41,32 @@ namespace Text */ struct MarkupProcessData { - MarkupProcessData(Vector& colorRuns, - Vector& fontRuns, - Vector& items, - Vector& anchors, - Vector& underlinedCharacterRuns, - Vector& backgroundColorRuns) + MarkupProcessData(Vector& colorRuns, + Vector& fontRuns, + Vector& items, + Vector& anchors, + Vector& underlinedCharacterRuns, + Vector& backgroundColorRuns, + Vector& strikethroughCharacterRuns) : colorRuns(colorRuns), fontRuns(fontRuns), items(items), anchors(anchors), underlinedCharacterRuns(underlinedCharacterRuns), backgroundColorRuns(backgroundColorRuns), + strikethroughCharacterRuns(strikethroughCharacterRuns), markupProcessedText() { } - 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. - Vector& backgroundColorRuns; ///< The background color runs. - 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. + Vector& backgroundColorRuns; ///< The background color runs. + Vector& strikethroughCharacterRuns; ///< The strikethrough 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 a210785..206d7f6 100644 --- a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp +++ b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -84,7 +84,8 @@ struct AtlasRenderer::Impl mLineThickness(0.0f), mMeshRecordIndex(0u), mUnderlineChunkId(0u), - mStrikethroughPosition(0.0f) + mStrikethroughPosition(0.0f), + mStrikethroughChunkId(0u) { } @@ -96,6 +97,7 @@ struct AtlasRenderer::Impl uint32_t mMeshRecordIndex; uint32_t mUnderlineChunkId; float mStrikethroughPosition; + uint32_t mStrikethroughChunkId; }; struct MaxBlockSize @@ -174,6 +176,30 @@ struct AtlasRenderer::Impl return false; } + bool doGlyphHaveStrikethrough(GlyphIndex index, + const Vector& strikethroughRuns, + Vector4& strikethroughColor) + { + for(Vector::ConstIterator it = strikethroughRuns.Begin(), + endIt = strikethroughRuns.End(); + it != endIt; + ++it) + { + const StrikethroughGlyphRun& run = *it; + + if((run.glyphRun.glyphIndex <= index) && (index < run.glyphRun.glyphIndex + run.glyphRun.numberOfGlyphs)) + { + if(run.isColorSet) + { + strikethroughColor = run.color; + } + + return true; + } + } + + return false; + } void CacheGlyph(const GlyphInfo& glyph, FontId lastFontId, const AtlasGlyphManager::GlyphStyle& style, AtlasManager::AtlasSlot& slot) { const Size& defaultTextAtlasSize = mFontClient.GetDefaultTextAtlasSize(); //Retrieve default size of text-atlas-block from font-client. @@ -293,7 +319,8 @@ struct AtlasRenderer::Impl Vector& newTextCache, Vector& extents, uint32_t underlineChunkId, - bool isGlyphCached) + bool isGlyphCached, + uint32_t strikethroughChunkId) { // Generate mesh data for this quad, plugging in our supplied position AtlasManager::Mesh2D newMesh; @@ -334,7 +361,8 @@ struct AtlasRenderer::Impl currentlineThickness, slot, underlineChunkId, - position.y + (glyph.height * HALF)); + position.y + (glyph.height * HALF), + strikethroughChunkId); } void CreateActors(const std::vector& meshContainer, @@ -446,6 +474,7 @@ struct AtlasRenderer::Impl const bool strikethroughEnabled = view.IsStrikethroughEnabled(); const Vector4& strikethroughColor(view.GetStrikethroughColor()); const float strikethroughHeight = view.GetStrikethroughHeight(); + Vector4 currentStrikethroughColor; // Elided text info. Indices according to elided text. const auto startIndexOfGlyphs = view.GetStartIndexOfElidedGlyphs(); @@ -462,6 +491,12 @@ struct AtlasRenderer::Impl 0u, numberOfUnderlineRuns); + // Get the strikethrough runs. + const Length numberOfStrikethroughRuns = view.GetNumberOfStrikethroughRuns(); + Vector strikethroughRuns; + strikethroughRuns.Resize(numberOfStrikethroughRuns); + view.GetStrikethroughRuns(strikethroughRuns.Begin(), 0u, numberOfStrikethroughRuns); + bool thereAreUnderlinedGlyphs = false; bool strikethroughGlyphsExist = false; @@ -490,6 +525,9 @@ struct AtlasRenderer::Impl uint32_t underlineChunkId = 0u; // give id for each chunk. bool isPreUnderlined = false; // status of underlined for previous glyph. + uint32_t strikethroughChunkId = 0u; // give id for each chunk. + bool isPrevGlyphStrikethrough = false; // status of strikethrough for previous glyph. + //Skip hyphenIndices less than startIndexOfGlyphs or between two middle of elided text if(hyphenIndices) { @@ -516,13 +554,16 @@ struct AtlasRenderer::Impl const bool isGlyphUnderlined = underlineEnabled || IsGlyphUnderlined(i, underlineRuns); thereAreUnderlinedGlyphs = thereAreUnderlinedGlyphs || isGlyphUnderlined; - strikethroughGlyphsExist = strikethroughGlyphsExist || strikethroughEnabled; + + currentStrikethroughColor = strikethroughColor; + const bool isStrikethroughGlyph = strikethroughEnabled || doGlyphHaveStrikethrough(i, strikethroughRuns, currentStrikethroughColor); + strikethroughGlyphsExist = strikethroughGlyphsExist || isStrikethroughGlyph; // No operation for white space if(glyph.width && glyph.height) { // Are we still using the same fontId as previous - if((isGlyphUnderlined || strikethroughGlyphsExist) && (glyph.fontId != lastUnderlinedFontId)) + if((isGlyphUnderlined || isStrikethroughGlyph) && (glyph.fontId != lastUnderlinedFontId)) { // We need to fetch fresh font underline metrics FontMetrics fontMetrics; @@ -626,9 +667,10 @@ struct AtlasRenderer::Impl newTextCache, extents, underlineChunkId, - false); + false, + 0u); - if(strikethroughGlyphsExist) + if(isStrikethroughGlyph) { GenerateMesh(glyph, positionPlusOutlineOffset, @@ -642,7 +684,8 @@ struct AtlasRenderer::Impl newTextCache, strikethroughExtents, 0u, - true); + true, + strikethroughChunkId); } lastFontId = glyph.fontId; // Prevents searching for existing blocksizes when string of the same fontId. @@ -662,7 +705,8 @@ struct AtlasRenderer::Impl newTextCache, extents, 0u, - false); + false, + 0u); } //The new underlined chunk. Add new id if they are not consecutive indices (this is for Markup case) @@ -673,6 +717,13 @@ struct AtlasRenderer::Impl } //Keep status of underlined for previous glyph to check consecutive indices isPreUnderlined = isGlyphUnderlined; + + if(isPrevGlyphStrikethrough && !isStrikethroughGlyph) + { + strikethroughChunkId++; + } + + isPrevGlyphStrikethrough = isStrikethroughGlyph; } if(addHyphen) @@ -694,7 +745,7 @@ struct AtlasRenderer::Impl if(strikethroughGlyphsExist) { // Check to see if any of the text needs a strikethrough - GenerateStrikethrough(meshContainer, strikethroughExtents, strikethroughColor); + GenerateStrikethrough(meshContainer, strikethroughExtents, currentStrikethroughColor); } // For each MeshData object, create a mesh actor and add to the renderable actor @@ -836,7 +887,8 @@ struct AtlasRenderer::Impl float lineThickness, AtlasManager::AtlasSlot& slot, uint32_t underlineChunkId, - float strikethroughPosition) + float strikethroughPosition, + uint32_t strikethroughChunkId) { if(slot.mImageId) { @@ -866,7 +918,8 @@ struct AtlasRenderer::Impl underlinePosition, lineThickness, underlineChunkId, - strikethroughPosition); + strikethroughPosition, + strikethroughChunkId); } return; @@ -891,7 +944,8 @@ struct AtlasRenderer::Impl underlinePosition, lineThickness, underlineChunkId, - strikethroughPosition); + strikethroughPosition, + strikethroughChunkId); } } } @@ -905,7 +959,8 @@ struct AtlasRenderer::Impl float underlinePosition, float lineThickness, uint32_t underlineChunkId, - float strikethroughPosition) + float strikethroughPosition, + uint32_t strikethroughChunkId) { bool foundExtent = false; for(Vector::Iterator eIt = extents.Begin(), @@ -913,7 +968,7 @@ struct AtlasRenderer::Impl eIt != eEndIt; ++eIt) { - if(Equals(baseLine, eIt->mBaseLine) && underlineChunkId == eIt->mUnderlineChunkId) + if(Equals(baseLine, eIt->mBaseLine) && underlineChunkId == eIt->mUnderlineChunkId && strikethroughChunkId == eIt->mStrikethroughChunkId) { foundExtent = true; if(left < eIt->mLeft) @@ -946,6 +1001,7 @@ struct AtlasRenderer::Impl extent.mUnderlineChunkId = underlineChunkId; extent.mLineThickness = lineThickness; extent.mStrikethroughPosition = strikethroughPosition; + extent.mStrikethroughChunkId = strikethroughChunkId; extents.PushBack(extent); } } diff --git a/dali-toolkit/internal/text/rendering/text-typesetter.cpp b/dali-toolkit/internal/text/rendering/text-typesetter.cpp index e6f346c..f7a1123 100644 --- a/dali-toolkit/internal/text/rendering/text-typesetter.cpp +++ b/dali-toolkit/internal/text/rendering/text-typesetter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -275,6 +275,31 @@ bool IsGlyphUnderlined(GlyphIndex index, return false; } +bool doGlyphHaveStrikethrough(GlyphIndex index, + const Vector& strikethroughRuns, + Vector4& strikethroughColor) +{ + for(Vector::ConstIterator it = strikethroughRuns.Begin(), + endIt = strikethroughRuns.End(); + it != endIt; + ++it) + { + const StrikethroughGlyphRun& run = *it; + + if((run.glyphRun.glyphIndex <= index) && (index < run.glyphRun.glyphIndex + run.glyphRun.numberOfGlyphs)) + { + if(run.isColorSet) + { + strikethroughColor = run.color; + } + + return true; + } + } + + return false; +} + /// Helper method to fetch the underline metrics for the specified font glyph void FetchFontDecorationlinesMetrics( TextAbstraction::FontClient& fontClient, @@ -900,6 +925,7 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const unsigned int bufferWidth, // Whether to use the default color. const bool useDefaultColor = (NULL == colorsBuffer); const Vector4& defaultColor = mModel->GetDefaultColor(); + Vector4 currentStrikethroughColor; // Create and initialize the pixel buffer. GlyphData glyphData; @@ -972,6 +998,12 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const unsigned int bufferWidth, underlineRuns.Resize(numberOfUnderlineRuns); mModel->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns); + // Get the strikethrough runs. + const Length numberOfStrikethroughRuns = mModel->GetNumberOfStrikethroughRuns(); + Vector strikethroughRuns; + strikethroughRuns.Resize(numberOfStrikethroughRuns); + mModel->GetStrikethroughRuns(strikethroughRuns.Begin(), 0u, numberOfStrikethroughRuns); + bool thereAreUnderlinedGlyphs = false; bool strikethroughGlyphsExist = false; @@ -1044,10 +1076,12 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const unsigned int bufferWidth, const bool underlineGlyph = underlineEnabled || IsGlyphUnderlined(glyphIndex, underlineRuns); thereAreUnderlinedGlyphs = thereAreUnderlinedGlyphs || underlineGlyph; - strikethroughGlyphsExist = strikethroughGlyphsExist || strikethroughEnabled; + currentStrikethroughColor = strikethroughColor; + const bool strikethroughGlyph = strikethroughEnabled || doGlyphHaveStrikethrough(glyphIndex, strikethroughRuns, currentStrikethroughColor); + strikethroughGlyphsExist = strikethroughGlyphsExist || strikethroughGlyph; // Are we still using the same fontId as previous - if((strikethroughEnabled || underlineGlyph) && (glyphInfo->fontId != lastUnderlinedFontId)) + if((strikethroughGlyph || underlineGlyph) && (glyphInfo->fontId != lastUnderlinedFontId)) { // We need to fetch fresh font underline metrics FetchFontDecorationlinesMetrics(fontClient, glyphInfo, currentUnderlinePosition, underlineHeight, currentUnderlineThickness, maxUnderlineThickness, lastUnderlinedFontId, strikethroughHeight, currentStrikethroughThickness, maxStrikethroughThickness); @@ -1255,43 +1289,83 @@ Devel::PixelBuffer Typesetter::CombineImageBuffer(Devel::PixelBuffer topPixelBuf return combinedPixelBuffer; } +Devel::PixelBuffer Typesetter::ApplyUnderlineMarkupImageBuffer(Devel::PixelBuffer topPixelBuffer, const unsigned int bufferWidth, const unsigned int bufferHeight, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat, int horizontalOffset, int verticalOffset) +{ + // 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; +} + +Devel::PixelBuffer Typesetter::ApplyStrikethroughMarkupImageBuffer(Devel::PixelBuffer topPixelBuffer, const unsigned int bufferWidth, const unsigned int bufferHeight, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat, int horizontalOffset, int verticalOffset) +{ + // strikethrough-tags (this is for Markup case) + // Get the strikethrough runs. + const Length numberOfStrikethroughRuns = mModel->GetNumberOfStrikethroughRuns(); + Vector strikethroughRuns; + strikethroughRuns.Resize(numberOfStrikethroughRuns); + mModel->GetStrikethroughRuns(strikethroughRuns.Begin(), 0u, numberOfStrikethroughRuns); + + // Iterate on the consecutive strikethrough glyph run and connect them into one chunk of strikethrough characters. + Vector::ConstIterator itGlyphRun = strikethroughRuns.Begin(); + Vector::ConstIterator endItGlyphRun = strikethroughRuns.End(); + GlyphIndex startGlyphIndex, endGlyphIndex; + + //The outer loop to iterate on the separated chunks of strikethrough glyph runs + while(itGlyphRun != endItGlyphRun) + { + startGlyphIndex = itGlyphRun->glyphRun.glyphIndex; + endGlyphIndex = startGlyphIndex + itGlyphRun->glyphRun.numberOfGlyphs - 1; + + // Create the image buffer for strikethrough + Devel::PixelBuffer strikethroughImageBuffer = CreateImageBuffer(bufferWidth, bufferHeight, Typesetter::STYLE_STRIKETHROUGH, ignoreHorizontalAlignment, pixelFormat, horizontalOffset, verticalOffset, startGlyphIndex, endGlyphIndex); + // Combine the two buffers + topPixelBuffer = CombineImageBuffer(strikethroughImageBuffer, topPixelBuffer, bufferWidth, bufferHeight); + + itGlyphRun++; + } + + return topPixelBuffer; +} + 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--; + topPixelBuffer = ApplyUnderlineMarkupImageBuffer(topPixelBuffer, bufferWidth, bufferHeight, ignoreHorizontalAlignment, pixelFormat, horizontalOffset, verticalOffset); - // 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); - } + topPixelBuffer = ApplyStrikethroughMarkupImageBuffer(topPixelBuffer, bufferWidth, bufferHeight, ignoreHorizontalAlignment, pixelFormat, horizontalOffset, verticalOffset); } return topPixelBuffer; diff --git a/dali-toolkit/internal/text/rendering/text-typesetter.h b/dali-toolkit/internal/text/rendering/text-typesetter.h index 51ac259..bf46b90 100644 --- a/dali-toolkit/internal/text/rendering/text-typesetter.h +++ b/dali-toolkit/internal/text/rendering/text-typesetter.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_TEXT_TYPESETTER_H /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -181,6 +181,21 @@ private: /** * @brief Apply behaviour of tags if the markup-processor is enabled. * + * @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); + + /** + * @brief Apply markup underline tags. + * * 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. @@ -197,7 +212,28 @@ private: * * @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); + Devel::PixelBuffer ApplyUnderlineMarkupImageBuffer(Devel::PixelBuffer topPixelBuffer, const unsigned int bufferWidth, const unsigned int bufferHeight, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat, int horizontalOffset, int verticalOffset); + + /** + * @brief Apply markup strikethrough tags. + * + * The properties on TextLabel override the behavior of Markup. + * Because the markup will be the bottom layer buffer + * - i.e: If you set property STRIKETHROUGH to enabled and blue. + * And the TEXT is "Hello World Hello World". + * Then the whole text will have a blue line strikethrough. + * + * @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 ApplyStrikethroughMarkupImageBuffer(Devel::PixelBuffer topPixelBuffer, const unsigned int bufferWidth, const unsigned int bufferHeight, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat, int horizontalOffset, int verticalOffset); protected: /** diff --git a/dali-toolkit/internal/text/rendering/view-model.cpp b/dali-toolkit/internal/text/rendering/view-model.cpp index 8f2c864..e446294 100644 --- a/dali-toolkit/internal/text/rendering/view-model.cpp +++ b/dali-toolkit/internal/text/rendering/view-model.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -613,6 +613,16 @@ bool ViewModel::IsStrikethroughEnabled() const return mModel->IsStrikethroughEnabled(); } +Length ViewModel::GetNumberOfStrikethroughRuns() const +{ + return mModel->GetNumberOfStrikethroughRuns(); +} + +void ViewModel::GetStrikethroughRuns(StrikethroughGlyphRun* strikethroughRuns, StrikethroughRunIndex index, Length numberOfRuns) const +{ + mModel->GetStrikethroughRuns(strikethroughRuns, index, numberOfRuns); +} + } // namespace Text } // namespace Toolkit diff --git a/dali-toolkit/internal/text/rendering/view-model.h b/dali-toolkit/internal/text/rendering/view-model.h index e30a859..e877baa 100644 --- a/dali-toolkit/internal/text/rendering/view-model.h +++ b/dali-toolkit/internal/text/rendering/view-model.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_TEXT_VIEW_MODEL_H /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -293,6 +293,16 @@ public: bool IsStrikethroughEnabled() const override; + /** + * @copydoc ModelInterface::GetNumberOfStrikethroughRuns() + */ + Length GetNumberOfStrikethroughRuns() const override; + + /** + * @copydoc ModelInterface::GetStrikethroughRuns() + */ + void GetStrikethroughRuns(StrikethroughGlyphRun* strikethroughRuns, StrikethroughRunIndex index, Length numberOfRuns) const override; + private: const ModelInterface* const mModel; ///< Pointer to the text's model. Vector mElidedGlyphs; ///< Stores the glyphs of the elided text. diff --git a/dali-toolkit/internal/text/strikethrough-character-run.h b/dali-toolkit/internal/text/strikethrough-character-run.h new file mode 100644 index 0000000..3f0e1f4 --- /dev/null +++ b/dali-toolkit/internal/text/strikethrough-character-run.h @@ -0,0 +1,49 @@ +#ifndef DALI_TOOLKIT_TEXT_STRIKETHROUGH_CHARACTER_RUN_H +#define DALI_TOOLKIT_TEXT_STRIKETHROUGH_CHARACTER_RUN_H + +/* + * Copyright (c) 2022 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 + +namespace Dali +{ +namespace Toolkit +{ +namespace Text +{ +/** + * @brief Run of strikethrough characters with same properties. + */ +struct StrikethroughCharacterRun +{ + CharacterRun characterRun; ///< The initial character index and the number of characters of the run. + Vector4 color; ///< The color of strikethrough. + bool isColorSet; ///< If the color of strikethrough is set. +}; + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali + +#endif // DALI_TOOLKIT_TEXT_STRIKETHROUGH_CHARACTER_RUN_H diff --git a/dali-toolkit/internal/text/strikethrough-glyph-run.h b/dali-toolkit/internal/text/strikethrough-glyph-run.h new file mode 100644 index 0000000..34be0af --- /dev/null +++ b/dali-toolkit/internal/text/strikethrough-glyph-run.h @@ -0,0 +1,49 @@ +#ifndef DALI_TOOLKIT_TEXT_STRIKETHROUGH_GLYPH_RUN_H +#define DALI_TOOLKIT_TEXT_STRIKETHROUGH_GLYPH_RUN_H + +/* + * Copyright (c) 2022 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 + +namespace Dali +{ +namespace Toolkit +{ +namespace Text +{ +/** + * @brief Run of strikethrough glyphs with same properties. + */ +struct StrikethroughGlyphRun +{ + GlyphRun glyphRun; ///< The initial glyph index and the number of glyphs in the run. + Vector4 color; ///< The color of strikethrough. + bool isColorSet; ///< If the color of strikethrough is set. +}; + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali + +#endif // DALI_TOOLKIT_TEXT_STRIKETHROUGH_GLYPH_RUN_H diff --git a/dali-toolkit/internal/text/text-controller-impl-model-updater.cpp b/dali-toolkit/internal/text/text-controller-impl-model-updater.cpp index bd93e68..2d1e28d 100644 --- a/dali-toolkit/internal/text/text-controller-impl-model-updater.cpp +++ b/dali-toolkit/internal/text/text-controller-impl-model-updater.cpp @@ -571,6 +571,7 @@ bool ControllerImplModelUpdater::Update(Controller::Impl& impl, OperationsMask o if(impl.mModel->mVisualModel->IsMarkupProcessorEnabled()) { impl.CopyUnderlinedFromLogicalToVisualModels(true); + impl.CopyStrikethroughFromLogicalToVisualModels(); } updated = true; diff --git a/dali-toolkit/internal/text/text-controller-impl.cpp b/dali-toolkit/internal/text/text-controller-impl.cpp index 6ffa715..5ee189b 100644 --- a/dali-toolkit/internal/text/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/text-controller-impl.cpp @@ -1626,6 +1626,34 @@ void Controller::Impl::CopyUnderlinedFromLogicalToVisualModels(bool shouldClearP } } +void Controller::Impl::CopyStrikethroughFromLogicalToVisualModels() +{ + //Strikethrough character runs from markup-processor + const Vector& strikethroughCharacterRuns = mModel->mLogicalModel->mStrikethroughCharacterRuns; + const Vector& charactersToGlyph = mModel->mVisualModel->mCharactersToGlyph; + const Vector& glyphsPerCharacter = mModel->mVisualModel->mGlyphsPerCharacter; + + mModel->mVisualModel->mStrikethroughRuns.Clear(); + + for(Vector::ConstIterator it = strikethroughCharacterRuns.Begin(), endIt = strikethroughCharacterRuns.End(); it != endIt; ++it) + { + CharacterIndex characterIndex = it->characterRun.characterIndex; + Length numberOfCharacters = it->characterRun.numberOfCharacters; + StrikethroughGlyphRun strikethroughGlyphRun; + strikethroughGlyphRun.color = it->color; + strikethroughGlyphRun.isColorSet = it->isColorSet; + strikethroughGlyphRun.glyphRun.glyphIndex = charactersToGlyph[characterIndex]; + strikethroughGlyphRun.glyphRun.numberOfGlyphs = glyphsPerCharacter[characterIndex]; + + for(Length index = 1u; index < numberOfCharacters; index++) + { + strikethroughGlyphRun.glyphRun.numberOfGlyphs += glyphsPerCharacter[characterIndex + index]; + } + + mModel->mVisualModel->mStrikethroughRuns.PushBack(strikethroughGlyphRun); + } +} + void Controller::Impl::SetAutoScrollEnabled(bool enable) { if(mLayoutEngine.GetLayout() == Layout::Engine::SINGLE_LINE_BOX) diff --git a/dali-toolkit/internal/text/text-controller-impl.h b/dali-toolkit/internal/text/text-controller-impl.h index e697d81..12faee1 100644 --- a/dali-toolkit/internal/text/text-controller-impl.h +++ b/dali-toolkit/internal/text/text-controller-impl.h @@ -936,6 +936,12 @@ private: */ void CopyUnderlinedFromLogicalToVisualModels(bool shouldClearPreUnderlineRuns); + /** + * @brief Copy strikethrough-Character-Runs from Logical-Model to strikethrough-Glyph-Runs in Visual-Model + * + */ + void CopyStrikethroughFromLogicalToVisualModels(); + 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 ab90270..caf44f7 100644 --- a/dali-toolkit/internal/text/text-controller-text-updater.cpp +++ b/dali-toolkit/internal/text/text-controller-text-updater.cpp @@ -90,7 +90,8 @@ void Controller::TextUpdater::SetText(Controller& controller, const std::string& logicalModel->mEmbeddedItems, logicalModel->mAnchors, logicalModel->mUnderlinedCharacterRuns, - logicalModel->mBackgroundColorRuns); + logicalModel->mBackgroundColorRuns, + logicalModel->mStrikethroughCharacterRuns); Length textSize = 0u; const uint8_t* utf8 = NULL; diff --git a/dali-toolkit/internal/text/text-definitions.h b/dali-toolkit/internal/text/text-definitions.h index 7cbc279..d5ce520 100644 --- a/dali-toolkit/internal/text/text-definitions.h +++ b/dali-toolkit/internal/text/text-definitions.h @@ -2,7 +2,7 @@ #define DALI_TEXT_ABSTRACTION_TEXT_TYPE_DEFINITIONS_H /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -55,6 +55,7 @@ typedef uint32_t GlyphIndex; ///< An index into an array of glyph typedef uint32_t ScriptRunIndex; ///< An index into an array of script runs. typedef uint32_t FontRunIndex; ///< An index into an array of font runs. typedef uint32_t UnderlineRunIndex; ///< An index into an array of underline runs. +typedef uint32_t StrikethroughRunIndex; ///< An index into an array of underline runs. typedef uint32_t BidirectionalRunIndex; ///< An index into an array of bidirectional info. typedef uint32_t BidirectionalLineRunIndex; ///< An index into an array of bidirectional line info. typedef uint32_t LineIndex; ///< An index into an array of lines. diff --git a/dali-toolkit/internal/text/text-model-interface.h b/dali-toolkit/internal/text/text-model-interface.h index f36c527..128f587 100644 --- a/dali-toolkit/internal/text/text-model-interface.h +++ b/dali-toolkit/internal/text/text-model-interface.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_TEXT_MODEL_INTERFACE_H /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -377,6 +378,22 @@ public: * @return Returns the override height for a strikethrough, 0 indicates that adaptor will determine the height */ virtual float GetStrikethroughHeight() const = 0; + + /** + * @brief Retrieves the number of strikethrough runs. + * + * @return The number of strikethrough runs. + */ + virtual Length GetNumberOfStrikethroughRuns() const = 0; + + /** + * @brief Retrieves the strikethrough runs. + * + * @param[out] strikethroughRuns Pointer to a buffer where the strikethrough runs are copied. + * @param[in] index Index of the first strikethrough run to be copied. + * @param[in] numberOfRuns Number of strikethrough runs to be copied. + */ + virtual void GetStrikethroughRuns(StrikethroughGlyphRun* strikethroughRuns, StrikethroughRunIndex index, Length numberOfRuns) const = 0; }; } // namespace Text diff --git a/dali-toolkit/internal/text/text-model.cpp b/dali-toolkit/internal/text/text-model.cpp index 6001a6e..baa6b91 100644 --- a/dali-toolkit/internal/text/text-model.cpp +++ b/dali-toolkit/internal/text/text-model.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -271,6 +271,16 @@ float Model::GetStrikethroughHeight() const return mVisualModel->GetStrikethroughHeight(); } +Length Model::GetNumberOfStrikethroughRuns() const +{ + return mVisualModel->GetNumberOfStrikethroughRuns(); +} + +void Model::GetStrikethroughRuns(StrikethroughGlyphRun* strikethroughRuns, StrikethroughRunIndex index, Length numberOfRuns) const +{ + mVisualModel->GetStrikethroughRuns(strikethroughRuns, index, numberOfRuns); +} + Model::Model() : mLogicalModel(), mVisualModel(), diff --git a/dali-toolkit/internal/text/text-model.h b/dali-toolkit/internal/text/text-model.h index 4d8149b..443f9ab 100644 --- a/dali-toolkit/internal/text/text-model.h +++ b/dali-toolkit/internal/text/text-model.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_TEXT_MODEL_H /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -278,6 +278,16 @@ public: bool IsStrikethroughEnabled() const override; + /** + * @copydoc ModelInterface::GetNumberOfStrikethroughRuns() + */ + Length GetNumberOfStrikethroughRuns() const override; + + /** + * @copydoc ModelInterface::GetStrikethroughRuns() + */ + void GetStrikethroughRuns(StrikethroughGlyphRun* strikethroughRuns, StrikethroughRunIndex index, Length numberOfRuns) const override; + private: // Private contructors & copy operator. /** * @brief Private constructor. diff --git a/dali-toolkit/internal/text/text-view-interface.h b/dali-toolkit/internal/text/text-view-interface.h index c6f76a4..67875b8 100644 --- a/dali-toolkit/internal/text/text-view-interface.h +++ b/dali-toolkit/internal/text/text-view-interface.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_TEXT_VIEW_INTERFACE_H /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -33,6 +33,7 @@ namespace Toolkit namespace Text { struct GlyphRun; +struct StrikethroughGlyphRun; /** * @brief Abstract interface to provide the information necessary to display text. @@ -309,6 +310,24 @@ public: * @return Returns the override height for a strikethrough, 0 indicates that adaptor will determine the height */ virtual float GetStrikethroughHeight() const = 0; + + /** + * @brief Retrieves the number of strikethrough runs. + * + * @return The number of strikethrough runs. + */ + virtual Length GetNumberOfStrikethroughRuns() const = 0; + + /** + * @brief Retrieves the strikethrough runs. + * + * @param[out] strikethroughRuns Pointer to a buffer where the strikethrough runs are copied. + * @param[in] index Index of the first strikethrough run to be copied. + * @param[in] numberOfRuns Number of strikethrough runs to be copied. + */ + virtual void GetStrikethroughRuns(StrikethroughGlyphRun* strikethroughRuns, + StrikethroughRunIndex index, + Length numberOfRuns) const = 0; }; } // namespace Text diff --git a/dali-toolkit/internal/text/text-view.cpp b/dali-toolkit/internal/text/text-view.cpp index 93c420e..9b34dd4 100644 --- a/dali-toolkit/internal/text/text-view.cpp +++ b/dali-toolkit/internal/text/text-view.cpp @@ -787,6 +787,28 @@ float View::GetStrikethroughHeight() const return (mImpl->mVisualModel) ? mImpl->mVisualModel->GetStrikethroughHeight() : 0.0f; } +Length View::GetNumberOfStrikethroughRuns() const +{ + if(mImpl->mVisualModel) + { + return mImpl->mVisualModel->GetNumberOfStrikethroughRuns(); + } + + return 0u; +} + +void View::GetStrikethroughRuns(StrikethroughGlyphRun* strikethroughRuns, + StrikethroughRunIndex index, + Length numberOfRuns) const +{ + if(mImpl->mVisualModel) + { + mImpl->mVisualModel->GetStrikethroughRuns(strikethroughRuns, + index, + numberOfRuns); + } +} + } // namespace Text } // namespace Toolkit diff --git a/dali-toolkit/internal/text/text-view.h b/dali-toolkit/internal/text/text-view.h index 7b14c8c..37d6e0f 100644 --- a/dali-toolkit/internal/text/text-view.h +++ b/dali-toolkit/internal/text/text-view.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_TEXT_VIEW_H /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -227,6 +227,18 @@ public: */ float GetStrikethroughHeight() const override; + /** + * @copydoc Dali::Toolkit::Text::ViewInterface::GetNumberOfStrikethroughRuns() + */ + Length GetNumberOfStrikethroughRuns() const; + + /** + * @copydoc Dali::Toolkit::Text::ViewInterface::GetStrikethroughRuns() + */ + void GetStrikethroughRuns(StrikethroughGlyphRun* strikethroughRuns, + StrikethroughRunIndex index, + Length numberOfRuns) const; + private: // Undefined View(const View& handle); diff --git a/dali-toolkit/internal/text/visual-model-impl.cpp b/dali-toolkit/internal/text/visual-model-impl.cpp index 6ac00cd..6c4ff9b 100644 --- a/dali-toolkit/internal/text/visual-model-impl.cpp +++ b/dali-toolkit/internal/text/visual-model-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -585,6 +585,20 @@ float VisualModel::GetStrikethroughHeight() const return mStrikethroughHeight; } +void VisualModel::GetStrikethroughRuns(StrikethroughGlyphRun* strikethroughRuns, + StrikethroughRunIndex index, + Length numberOfRuns) const +{ + memcpy(strikethroughRuns, + mStrikethroughRuns.Begin() + index, + numberOfRuns * sizeof(StrikethroughGlyphRun)); +} + +Length VisualModel::GetNumberOfStrikethroughRuns() const +{ + return mStrikethroughRuns.Count(); +} + void VisualModel::ClearCaches() { mCachedLineIndex = 0u; diff --git a/dali-toolkit/internal/text/visual-model-impl.h b/dali-toolkit/internal/text/visual-model-impl.h index 710f0ab..673156b 100644 --- a/dali-toolkit/internal/text/visual-model-impl.h +++ b/dali-toolkit/internal/text/visual-model-impl.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_TEXT_VISUAL_MODEL_IMPL_H /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -28,6 +28,7 @@ // INTERNAL INCLUDES #include #include +#include #include // DEVEL INCLUDES @@ -552,6 +553,24 @@ public: */ float GetStrikethroughHeight() const; + /** + * @brief Retrieves the strikethrough runs. + * + * @param[out] strikethroughRuns Pointer to a buffer where the strikethrough runs are copied. + * @param[in] index Index of the first strikethrough run to be copied. + * @param[in] numberOfRuns Number of strikethrough runs to be copied. + */ + void GetStrikethroughRuns(StrikethroughGlyphRun* strikethroughRuns, + StrikethroughRunIndex index, + Length numberOfRuns) const; + + /** + * @brief Retrieves the number of strikethrough runs. + * + * @return The number of strikethrough runs. + */ + Length GetNumberOfStrikethroughRuns() const; + protected: /** * @brief A reference counted object may only be deleted by calling Unreference(). @@ -571,33 +590,34 @@ private: VisualModel& operator=(const VisualModel& handle); public: - Vector mGlyphs; ///< For each glyph, the font's id, glyph's index within the font and glyph's metrics. - Vector mGlyphsToCharacters; ///< For each glyph, the index of the first character. - Vector mCharactersToGlyph; ///< For each character, the index of the first glyph. - Vector mCharactersPerGlyph; ///< For each glyph, the number of characters that form the glyph. - Vector mGlyphsPerCharacter; ///< For each character, the number of glyphs that are shaped. - Vector mGlyphPositions; ///< For each glyph, the position. - Vector mLines; ///< The laid out lines. - Vector mUnderlineRuns; ///< Runs of glyphs that are underlined. - Vector mColors; ///< Colors of the glyphs. - Vector mColorIndices; ///< Indices to the vector of colors for each glyphs. - Vector mBackgroundColors; ///< Background colors of the glyphs. - Vector mBackgroundColorIndices; ///< Indices to the vector of background colors for each glyphs. - Vector4 mTextColor; ///< The text color - Vector4 mShadowColor; ///< Color of drop shadow - Vector4 mUnderlineColor; ///< Color of underline - Vector4 mOutlineColor; ///< Color of outline - Vector4 mBackgroundColor; ///< Color of text background - Vector4 mStrikethroughColor; ///< Color of text background - Size mControlSize; ///< The size of the UI control. - Vector2 mShadowOffset; ///< Offset for drop shadow, 0 indicates no shadow - float mUnderlineHeight; ///< Fixed height for underline to override font metrics. - float mStrikethroughHeight; ///< Fixed height for strikethrough to override font metrics. - Text::Underline::Type mUnderlineType; ///< The type of the underline. - float mDashedUnderlineWidth; ///< The width of the dashes of the dashed underline. - float mDashedUnderlineGap; ///< The gap between the dashes of the dashed underline. - float mShadowBlurRadius; ///< Blur radius of shadow, 0 indicates no blur. - uint16_t mOutlineWidth; ///< Width of outline. + Vector mGlyphs; ///< For each glyph, the font's id, glyph's index within the font and glyph's metrics. + Vector mGlyphsToCharacters; ///< For each glyph, the index of the first character. + Vector mCharactersToGlyph; ///< For each character, the index of the first glyph. + Vector mCharactersPerGlyph; ///< For each glyph, the number of characters that form the glyph. + Vector mGlyphsPerCharacter; ///< For each character, the number of glyphs that are shaped. + Vector mGlyphPositions; ///< For each glyph, the position. + Vector mLines; ///< The laid out lines. + Vector mUnderlineRuns; ///< Runs of glyphs that are underlined. + Vector mColors; ///< Colors of the glyphs. + Vector mColorIndices; ///< Indices to the vector of colors for each glyphs. + Vector mBackgroundColors; ///< Background colors of the glyphs. + Vector mBackgroundColorIndices; ///< Indices to the vector of background colors for each glyphs. + Vector4 mTextColor; ///< The text color + Vector4 mShadowColor; ///< Color of drop shadow + Vector4 mUnderlineColor; ///< Color of underline + Vector4 mOutlineColor; ///< Color of outline + Vector4 mBackgroundColor; ///< Color of text background + Vector4 mStrikethroughColor; ///< Color of text background + Size mControlSize; ///< The size of the UI control. + Vector2 mShadowOffset; ///< Offset for drop shadow, 0 indicates no shadow + float mUnderlineHeight; ///< Fixed height for underline to override font metrics. + float mStrikethroughHeight; ///< Fixed height for strikethrough to override font metrics. + Text::Underline::Type mUnderlineType; ///< The type of the underline. + float mDashedUnderlineWidth; ///< The width of the dashes of the dashed underline. + float mDashedUnderlineGap; ///< The gap between the dashes of the dashed underline. + float mShadowBlurRadius; ///< Blur radius of shadow, 0 indicates no blur. + uint16_t mOutlineWidth; ///< Width of outline. + Vector mStrikethroughRuns; ///< Runs of glyphs that have strikethrough. private: Size mNaturalSize; ///< Size of the text with no line wrapping. -- 2.7.4