Merge "support strikethrough markup tag" into devel/master
authorBowon Ryu <bowon.ryu@samsung.com>
Wed, 19 Jan 2022 11:42:23 +0000 (11:42 +0000)
committerGerrit Code Review <gerrit@review>
Wed, 19 Jan 2022 11:42:23 +0000 (11:42 +0000)
33 files changed:
automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/toolkit-text-utils.cpp [changed mode: 0755->0644]
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Markup.cpp [changed mode: 0755->0644]
automated-tests/src/dali-toolkit-internal/utc-Dali-TextEditor-internal.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-TextField-internal.cpp [changed mode: 0755->0644]
automated-tests/src/dali-toolkit-internal/utc-Dali-TextLabel-internal.cpp [changed mode: 0755->0644]
dali-toolkit/devel-api/text/text-utils-devel.cpp
dali-toolkit/internal/file.list
dali-toolkit/internal/text/logical-model-impl.cpp
dali-toolkit/internal/text/logical-model-impl.h
dali-toolkit/internal/text/markup-processor-strikethrough.cpp [new file with mode: 0644]
dali-toolkit/internal/text/markup-processor-strikethrough.h [new file with mode: 0644]
dali-toolkit/internal/text/markup-processor.cpp
dali-toolkit/internal/text/markup-processor.h
dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp
dali-toolkit/internal/text/rendering/text-typesetter.cpp
dali-toolkit/internal/text/rendering/text-typesetter.h
dali-toolkit/internal/text/rendering/view-model.cpp
dali-toolkit/internal/text/rendering/view-model.h
dali-toolkit/internal/text/strikethrough-character-run.h [new file with mode: 0644]
dali-toolkit/internal/text/strikethrough-glyph-run.h [new file with mode: 0644]
dali-toolkit/internal/text/text-controller-impl-model-updater.cpp
dali-toolkit/internal/text/text-controller-impl.cpp
dali-toolkit/internal/text/text-controller-impl.h
dali-toolkit/internal/text/text-controller-text-updater.cpp
dali-toolkit/internal/text/text-definitions.h
dali-toolkit/internal/text/text-model-interface.h
dali-toolkit/internal/text/text-model.cpp
dali-toolkit/internal/text/text-model.h
dali-toolkit/internal/text/text-view-interface.h
dali-toolkit/internal/text/text-view.cpp
dali-toolkit/internal/text/text-view.h
dali-toolkit/internal/text/visual-model-impl.cpp
dali-toolkit/internal/text/visual-model-impl.h

old mode 100755 (executable)
new mode 100644 (file)
index cc0288c..e9d0ef0
@@ -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.
 #include "toolkit-text-utils.h"
 
 // EXTERNAL INCLUDES
-#include <limits>
 #include <dali/devel-api/text-abstraction/font-client.h>
+#include <limits>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/bidirectional-support.h>
 #include <dali-toolkit/internal/text/character-set-conversion.h>
+#include <dali-toolkit/internal/text/hyphenator.h>
 #include <dali-toolkit/internal/text/layouts/layout-engine.h>
 #include <dali-toolkit/internal/text/layouts/layout-parameters.h>
+#include <dali-toolkit/internal/text/markup-processor.h>
 #include <dali-toolkit/internal/text/multi-language-support.h>
 #include <dali-toolkit/internal/text/segmentation.h>
 #include <dali-toolkit/internal/text/shaper.h>
 #include <dali-toolkit/internal/text/text-controller-impl.h>
-#include <dali-toolkit/internal/text/markup-processor.h>
-#include <dali-toolkit/internal/text/hyphenator.h>
 
 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<BidirectionalLineInfoRun> bidirectionalLineInfo,
-                                         uint32_t index )
+void FreeBidirectionalLineInfoResources(Vector<BidirectionalLineInfoRun> bidirectionalLineInfo,
+                                        uint32_t                         index)
 {
   // Free the allocated memory used to store the conversion table in the bidirectional line info run.
-  for( Vector<BidirectionalLineInfoRun>::Iterator it = bidirectionalLineInfo.Begin() + index,
-         endIt = bidirectionalLineInfo.End();
-       it != endIt;
-       ++it )
+  for(Vector<BidirectionalLineInfoRun>::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<BidirectionalLineInfoRun> 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<FontDescriptionRun>& 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<FontDescriptionRun>& 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<const uint8_t*>( markupProcessData.markupProcessedText.c_str() );
+    utf8 = reinterpret_cast<const uint8_t*>(markupProcessData.markupProcessedText.c_str());
   }
   else
   {
     textSize = text.size();
 
     // This is a bit horrible but std::string returns a (signed) char*
-    utf8 = reinterpret_cast<const uint8_t*>( text.c_str() );
+    utf8 = reinterpret_cast<const uint8_t*>(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<Character>& 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>& 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<ScriptRun>& scripts = logicalModel->mScriptRuns;
-  multilanguageSupport.SetScripts( utf32Characters,
-                                   0u,
-                                   characterCount,
-                                   scripts );
+  multilanguageSupport.SetScripts(utf32Characters,
+                                  0u,
+                                  characterCount,
+                                  scripts);
 
   // 4) Set the font info
   Vector<FontDescriptionRun>& fontDescriptionRuns = logicalModel->mFontDescriptionRuns;
-  fontDescriptionRuns = fontDescriptions;
-  Vector<FontRun>& validFonts = logicalModel->mFontRuns;
+  fontDescriptionRuns                             = fontDescriptions;
+  Vector<FontRun>& 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<Character> mirroredUtf32Characters;
-  bool textMirrored = false;
+  bool              textMirrored = false;
 
   // Reserve some space for the vector of paragraph's bidirectional info.
   Vector<BidirectionalParagraphInfoRun>& 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<CharacterDirection>& 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<GlyphInfo>& glyphs = visualModel->mGlyphs;
+  Vector<GlyphInfo>&      glyphs                = visualModel->mGlyphs;
   Vector<CharacterIndex>& glyphsToCharactersMap = visualModel->mGlyphsToCharacters;
-  Vector<Length>& charactersPerGlyph = visualModel->mCharactersPerGlyph;
-  Vector<GlyphIndex> newParagraphGlyphs;
+  Vector<Length>&         charactersPerGlyph    = visualModel->mCharactersPerGlyph;
+  Vector<GlyphIndex>      newParagraphGlyphs;
 
   const Vector<Character>& 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<GlyphIndex>::ConstIterator it = newParagraphGlyphs.Begin(),
-         endIt = newParagraphGlyphs.End();
-       it != endIt;
-       ++it )
+  for(Vector<GlyphIndex>::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<LineRun>& lines = visualModel->mLines;
 
   Vector<Vector2>& 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<Length>::max() );
+  controller->SetMaximumNumberOfCharacters(std::numeric_limits<Length>::max());
 
   // Disable the text elide.
-  controller->SetTextElideEnabled( false );
+  controller->SetTextElideEnabled(false);
 
   // Disable match system language direction
   controller->SetMatchLayoutDirection(DevelText::MatchLayoutDirection::CONTENTS);
 }
 
-
 Vector<FontDescriptionRun> 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<FontDescriptionRun> fontDescriptionRuns;
   fontDescriptionRuns.PushBack(fontDescriptionRun);
old mode 100755 (executable)
new mode 100644 (file)
index 1a4b5e1..67299b4
@@ -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.
 
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/dali-toolkit.h>
-#include <toolkit-text-utils.h>
-#include <dali-toolkit/internal/text/markup-processor.h>
-#include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
 #include <dali-toolkit/internal/text/color-run.h>
 #include <dali-toolkit/internal/text/font-description-run.h>
+#include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
+#include <dali-toolkit/internal/text/markup-processor.h>
 #include <dali-toolkit/internal/text/text-definitions.h>
 #include <dali-toolkit/internal/text/text-io.h>
+#include <toolkit-text-utils.h>
 
 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<ColorRun>                  colorRuns;
+  Vector<FontDescriptionRun>        fontRuns;
+  Vector<EmbeddedItem>              items;
+  Vector<Anchor>                    anchors;
+  Vector<UnderlinedCharacterRun>    underlinedCharacterRuns;
+  Vector<ColorRun>                  backgroundColorRuns;
+  Vector<StrikethroughCharacterRun> strikethroughCharacterRuns;
+  MarkupProcessData                 markupProcessData(colorRuns, fontRuns, items, anchors, underlinedCharacterRuns, backgroundColorRuns, strikethroughCharacterRuns);
+  ProcessMarkupString(data.xHTMLEntityString, markupProcessData);
+
+  for(Vector<EmbeddedItem>::Iterator it    = items.Begin(),
+                                     endIt = items.End();
+      it != endIt;
+      ++it)
   {
-    std::cout << "  testing " << data.description << std::endl;
-
-    Vector<ColorRun> colorRuns;
-    Vector<FontDescriptionRun> fontRuns;
-    Vector<EmbeddedItem> items;
-    Vector<Anchor> anchors;
-    Vector<UnderlinedCharacterRun> underlinedCharacterRuns;
-    Vector<ColorRun> backgroundColorRuns;
-    MarkupProcessData markupProcessData( colorRuns, fontRuns, items, anchors, underlinedCharacterRuns, backgroundColorRuns );
-    ProcessMarkupString( data.xHTMLEntityString, markupProcessData );
-
-    for( Vector<EmbeddedItem>::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 &#x26; &#x27; &#x3C; &#x3E; &#xA1; &#xA2; &#xA3; &#xA4; &#xA5; &#xA6; &#xA7; &#xA8; &#xA9; &#xAA; &#xAB; &#xAC; &#xAD; &#xAE; &#xAF; &#xB0; &#xB1; &#xB2; &#xB3; &#xB4; &#xB5; &#xB6; &#xB7; &#xB8; &#xB9; &#xBA; &#xBB; &#xBC; &#xBD; &#xBE; &#xBF; &#xC0; &#xC1; &#xC2; &#xC3; &#xC4; &#xC5; &#xE6; &#xC7; &#xC8; &#xC9; &#xCA; &#xCB; &#xCC; &#xCD; &#xCE; &#xCF; &#xF0; &#xD1; &#xD2; &#xD3; &#xD4; &#xD5; &#xD6; &#xD7; &#xD8; &#xD9; &#xDA; &#xDB; &#xDD; &#xFE; &#xDF; &#xE0; &#xE1; &#xE2; &#xE3; &#xE4; &#xE5; &#xE6; &#xE7; &#xE8; &#xE9; &#xEA; &#xEB; &#xEC; &#xED; &#xEE; &#xEF; &#xF0; &#xF1; &#xF2; &#xF3; &#xF4; &#xF5; &#xF6; &#xF7; &#xF8; &#xF9; &#xFA; &#xFB; &#xFC; &#xFD; &#xFE; &#xFF; &#x3B1; &#x3B2; &#x3B3; &#x3B4; &#x3B5; &#x3B6; &#x3B7; &#x3B8; &#x3B9; &#x3BA; &#x3BB; &#x3BC; &#x3BD; &#x3BE; &#x3BF; &#x3C0; &#x3C1; &#x3C3; &#x3C4; &#x3C5; &#x3C6; &#x3C7; &#x3C8; &#x3C9; &#x2026; &#x20AC; &#x2190; &#x2191; &#x2192; &#x2193; &#x2194; &#x2190; &#x2192; &#x2200; &#x2203; &#x2207; &#x220F; &#x2211; &#x2227; &#x2228; &#x222B; &#x2260; &#x2261; &#x2295; &#x22A5; &#x2020; &#x2021; &#x2022; ",
-      "Checking Numeric Entitities & ' < > ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å æ Ç È É Ê Ë Ì Í Î Ï ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ý þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ σ τ υ φ χ ψ ω … € ← ↑ → ↓ ↔ ← → ∀ ∃ ∇ ∏ ∑ ∧ ∨ ∫ ≠ ≡ ⊕ ⊥ † ‡ • "
-    },
-    {
-      "Text With XHTML Named Entities",
-      "Checking Named Entitities &amp; &apos; &lt; &gt; &iexcl; &cent; &pound; &curren; &yen; &brvbar; &sect; &uml; &copy; &ordf; &laquo; &not; &shy; &reg; &macr; &deg; &plusmn; &sup2; &sup3; &acute; &micro; &para; &middot; &cedil; &sup1; &ordm; &raquo; &frac14; &frac12; &frac34; &iquest; &Agrave; &Aacute; &Acirc; &Atilde; &Auml; &Aring; &aelig; &Ccedil; &Egrave; &Eacute; &Ecirc; &Euml; &Igrave; &Iacute; &Icirc; &Iuml; &eth; &Ntilde; &Ograve; &Oacute; &Ocirc; &Otilde; &Ouml; &times; &Oslash; &Ugrave; &Uacute; &Ucirc; &Yacute; &thorn; &szlig; &agrave; &aacute; &acirc; &atilde; &auml; &aring; &aelig; &ccedil; &egrave; &eacute; &ecirc; &euml; &igrave; &iacute; &icirc; &iuml; &eth; &ntilde; &ograve; &oacute; &ocirc; &otilde; &ouml; &divide; &oslash; &ugrave; &uacute; &ucirc; &uuml; &yacute; &thorn; &yuml; &alpha; &beta; &gamma; &delta; &epsilon; &zeta; &eta; &theta; &iota; &kappa; &lambda; &mu; &nu; &xi; &omicron; &pi; &rho; &sigma; &tau; &upsilon; &phi; &chi; &psi; &omega; &hellip; &euro; &larr; &uarr; &rarr; &darr; &harr; &larr; &rarr; &forall; &exist; &nabla; &prod; &sum; &and; &or; &int; &ne; &equiv; &oplus; &perp; &dagger; &Dagger; &bull; ",
-      "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 &#x26; &#x27; &#x3C; &#x3E; &#xA1; &#xA2; &#xA3; &#xA4; &#xA5; &#xA6; &#xA7; &#xA8; &#xA9; &#xAA; &#xAB; &#xAC; &#xAD; &#xAE; &#xAF; &#xB0; &#xB1; &#xB2; &#xB3; &#xB4; &#xB5; &#xB6; &#xB7; &#xB8; &#xB9; &#xBA; &#xBB; &#xBC; &#xBD; &#xBE; &#xBF; &#xC0; &#xC1; &#xC2; &#xC3; &#xC4; &#xC5; &#xE6; &#xC7; &#xC8; &#xC9; &#xCA; &#xCB; &#xCC; &#xCD; &#xCE; &#xCF; &#xF0; &#xD1; &#xD2; &#xD3; &#xD4; &#xD5; &#xD6; &#xD7; &#xD8; &#xD9; &#xDA; &#xDB; &#xDD; &#xFE; &#xDF; &#xE0; &#xE1; &#xE2; &#xE3; &#xE4; &#xE5; &#xE6; &#xE7; &#xE8; &#xE9; &#xEA; &#xEB; &#xEC; &#xED; &#xEE; &#xEF; &#xF0; &#xF1; &#xF2; &#xF3; &#xF4; &#xF5; &#xF6; &#xF7; &#xF8; &#xF9; &#xFA; &#xFB; &#xFC; &#xFD; &#xFE; &#xFF; &#x3B1; &#x3B2; &#x3B3; &#x3B4; &#x3B5; &#x3B6; &#x3B7; &#x3B8; &#x3B9; &#x3BA; &#x3BB; &#x3BC; &#x3BD; &#x3BE; &#x3BF; &#x3C0; &#x3C1; &#x3C3; &#x3C4; &#x3C5; &#x3C6; &#x3C7; &#x3C8; &#x3C9; &#x2026; &#x20AC; &#x2190; &#x2191; &#x2192; &#x2193; &#x2194; &#x2190; &#x2192; &#x2200; &#x2203; &#x2207; &#x220F; &#x2211; &#x2227; &#x2228; &#x222B; &#x2260; &#x2261; &#x2295; &#x22A5; &#x2020; &#x2021; &#x2022; ",
+       "Checking Numeric Entitities & ' < > ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å æ Ç È É Ê Ë Ì Í Î Ï ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ý þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ σ τ υ φ χ ψ ω … € ← ↑ → ↓ ↔ ← → ∀ ∃ ∇ ∏ ∑ ∧ ∨ ∫ ≠ ≡ ⊕ ⊥ † ‡ • "},
+      {"Text With XHTML Named Entities",
+       "Checking Named Entitities &amp; &apos; &lt; &gt; &iexcl; &cent; &pound; &curren; &yen; &brvbar; &sect; &uml; &copy; &ordf; &laquo; &not; &shy; &reg; &macr; &deg; &plusmn; &sup2; &sup3; &acute; &micro; &para; &middot; &cedil; &sup1; &ordm; &raquo; &frac14; &frac12; &frac34; &iquest; &Agrave; &Aacute; &Acirc; &Atilde; &Auml; &Aring; &aelig; &Ccedil; &Egrave; &Eacute; &Ecirc; &Euml; &Igrave; &Iacute; &Icirc; &Iuml; &eth; &Ntilde; &Ograve; &Oacute; &Ocirc; &Otilde; &Ouml; &times; &Oslash; &Ugrave; &Uacute; &Ucirc; &Yacute; &thorn; &szlig; &agrave; &aacute; &acirc; &atilde; &auml; &aring; &aelig; &ccedil; &egrave; &eacute; &ecirc; &euml; &igrave; &iacute; &icirc; &iuml; &eth; &ntilde; &ograve; &oacute; &ocirc; &otilde; &ouml; &divide; &oslash; &ugrave; &uacute; &ucirc; &uuml; &yacute; &thorn; &yuml; &alpha; &beta; &gamma; &delta; &epsilon; &zeta; &eta; &theta; &iota; &kappa; &lambda; &mu; &nu; &xi; &omicron; &pi; &rho; &sigma; &tau; &upsilon; &phi; &chi; &psi; &omega; &hellip; &euro; &larr; &uarr; &rarr; &darr; &harr; &larr; &rarr; &forall; &exist; &nabla; &prod; &sum; &and; &or; &int; &ne; &equiv; &oplus; &perp; &dagger; &Dagger; &bull; ",
+       "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);
     }
index e588998..0c55d97 100644 (file)
@@ -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, "<s>ABC</s>EF<s color='red'>GH</s>");
+  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<StrikethroughGlyphRun> 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;
+}
old mode 100755 (executable)
new mode 100644 (file)
index 7cf4084..57fb32b
@@ -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.
  *
  */
 
-#include <iostream>
 #include <stdlib.h>
+#include <iostream>
 
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/dali-toolkit.h>
 
-#include <dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h>
 #include <dali-toolkit/internal/controls/text-controls/text-field-impl.h>
-#include <dali-toolkit/internal/text/text-controller.h>
+#include <dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h>
 #include <dali-toolkit/internal/text/text-controller-impl.h>
+#include <dali-toolkit/internal/text/text-controller.h>
 
 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<std::string>(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<std::string>(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, "<u>ABC</u>EF<u>GH</u>" );
-  textField.SetProperty( TextField ::Property::ENABLE_MARKUP,  true );
+  textField.SetProperty(TextField::Property::TEXT, "<u>ABC</u>EF<u>GH</u>");
+  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<GlyphRun> 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, "H<background color='red'>e</background> Worl<background color='yellow'>d</background>" );
-  application.GetScene().Add( field );
+  field.SetProperty(TextField ::Property::ENABLE_MARKUP, true);
+  field.SetProperty(TextField::Property::TEXT, "H<background color='red'>e</background> Worl<background color='yellow'>d</background>");
+  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<bool>(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<bool>(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, "H<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red'>ello</span> Span" );
+  field.SetProperty(TextField::Property::TEXT, "H<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red'>ello</span> 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, "<span font-size='45'>H</span>ello <span text-color='red'>S</span>pan" );
+  field.SetProperty(TextField::Property::TEXT, "<span font-size='45'>H</span>ello <span text-color='red'>S</span>pan");
 
   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, "<s>ABC</s>EF<s color='red'>GH</s>");
+  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<StrikethroughGlyphRun> 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;
+}
old mode 100755 (executable)
new mode 100644 (file)
index b72dcb4..5af84d4
@@ -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.
  *
  */
 
-#include <iostream>
 #include <stdlib.h>
+#include <iostream>
 
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/dali-toolkit.h>
 
 #include <dali-toolkit/internal/controls/text-controls/text-label-impl.h>
-#include <dali-toolkit/internal/text/text-controller.h>
-#include <dali-toolkit/internal/text/text-controller-impl.h>
 #include <dali-toolkit/internal/text/rendering/text-typesetter.h>
 #include <dali-toolkit/internal/text/rendering/view-model.h>
+#include <dali-toolkit/internal/text/text-controller-impl.h>
+#include <dali-toolkit/internal/text/text-controller.h>
 
 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, "<u>ABC</u>EF<u>GH</u>" );
-  textLabel.SetProperty( TextLabel ::Property::ENABLE_MARKUP,  true );
+  textLabel.SetProperty(TextLabel::Property::TEXT, "<u>ABC</u>EF<u>GH</u>");
+  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<GlyphRun> 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, "H<background color='red'>e</background> Worl<background color='yellow'>d</background>" );
-  application.GetScene().Add( label );
+  label.SetProperty(TextLabel ::Property::ENABLE_MARKUP, true);
+  label.SetProperty(TextLabel::Property::TEXT, "H<background color='red'>e</background> Worl<background color='yellow'>d</background>");
+  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<bool>(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<bool>(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, "H<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red'>ello</span> Span" );
+  label.SetProperty(TextLabel::Property::TEXT, "H<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red'>ello</span> 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, "<span font-size='45'>H</span>ello <span text-color='red'>S</span>pan" );
+  label.SetProperty(TextLabel::Property::TEXT, "<span font-size='45'>H</span>ello <span text-color='red'>S</span>pan");
 
   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, "<s>ABC</s>EF<s color='red'>GH</s>");
+  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<StrikethroughGlyphRun> 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;
 }
index e4733c1..b4abff2 100644 (file)
@@ -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)
   {
index 0ad41cd..ddddf9a 100644 (file)
@@ -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
index 0de63d5..f1fd1f5 100644 (file)
@@ -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<UnderlinedCharacterRun> removedUnderlinedCharacterRuns;
   UpdateCharacterRuns<UnderlinedCharacterRun>(index,
-                                numberOfCharacters,
-                                totalNumberOfCharacters,
-                                mUnderlinedCharacterRuns,
-                                removedUnderlinedCharacterRuns);
+                                              numberOfCharacters,
+                                              totalNumberOfCharacters,
+                                              mUnderlinedCharacterRuns,
+                                              removedUnderlinedCharacterRuns);
+
+  // Process the strikethrough runs.
+  Vector<StrikethroughCharacterRun> removedStrikethroughCharacterRuns;
+  UpdateCharacterRuns<StrikethroughCharacterRun>(index,
+                                                 numberOfCharacters,
+                                                 totalNumberOfCharacters,
+                                                 mStrikethroughCharacterRuns,
+                                                 removedStrikethroughCharacterRuns);
 
   // Process the background color runs.
   Vector<ColorRun> removedBackgroundColorRuns;
index 80a1285..1bed342 100644 (file)
@@ -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 <dali-toolkit/internal/text/font-run.h>
 #include <dali-toolkit/internal/text/paragraph-run.h>
 #include <dali-toolkit/internal/text/script-run.h>
+#include <dali-toolkit/internal/text/strikethrough-character-run.h>
 #include <dali-toolkit/internal/text/underlined-character-run.h>
 
 namespace Dali
@@ -220,7 +221,8 @@ public:
   Vector<BidirectionalLineInfoRun>      mBidirectionalLineInfo;
   Vector<EmbeddedItem>                  mEmbeddedItems;
   Vector<Anchor>                        mAnchors;
-  Vector<UnderlinedCharacterRun>        mUnderlinedCharacterRuns; ///< The underlined character run from markup-processor
+  Vector<UnderlinedCharacterRun>        mUnderlinedCharacterRuns;    ///< The underlined character run from markup-processor
+  Vector<StrikethroughCharacterRun>     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 (file)
index 0000000..9282121
--- /dev/null
@@ -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 <dali-toolkit/internal/text/markup-processor-strikethrough.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
+#include <dali-toolkit/internal/text/strikethrough-character-run.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace
+{
+const std::string XHTML_COLOR_ATTRIBUTE("color");
+}
+
+void ProcessStrikethroughTag(const Tag& tag, StrikethroughCharacterRun& strikethroughRun)
+{
+  for(Vector<Attribute>::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 (file)
index 0000000..6c0a520
--- /dev/null
@@ -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
index b656aa4..7ed1f61 100644 (file)
@@ -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 <dali-toolkit/internal/text/markup-processor-font.h>
 #include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
 #include <dali-toolkit/internal/text/markup-processor-span.h>
+#include <dali-toolkit/internal/text/markup-processor-strikethrough.h>
 #include <dali-toolkit/internal/text/xhtml-entities.h>
 
 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<Span> 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<StrikethroughCharacterRun>(
+          markupProcessData.strikethroughCharacterRuns, styleStack, tag, characterIndex, strikethroughCharacterRunIndex, sTagReference, [](const Tag& tag, StrikethroughCharacterRun& run) { ProcessStrikethroughTag(tag, run); });
+      } // <s></s>
+    }   // end if( IsTag() )
     else if(markupStringBuffer < markupStringEndBuffer)
     {
       ProcessMarkupStringBuffer(markupProcessData, markupStringBuffer, markupStringEndBuffer, characterIndex);
index e84b892..bb1b6ba 100644 (file)
@@ -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 <dali-toolkit/internal/text/color-run.h>
 #include <dali-toolkit/internal/text/embedded-item.h>
 #include <dali-toolkit/internal/text/font-description-run.h>
+#include <dali-toolkit/internal/text/strikethrough-character-run.h>
 #include <dali-toolkit/internal/text/underlined-character-run.h>
 
 namespace Dali
@@ -40,29 +41,32 @@ namespace Text
  */
 struct MarkupProcessData
 {
-  MarkupProcessData(Vector<ColorRun>&               colorRuns,
-                    Vector<FontDescriptionRun>&     fontRuns,
-                    Vector<EmbeddedItem>&           items,
-                    Vector<Anchor>&                 anchors,
-                    Vector<UnderlinedCharacterRun>& underlinedCharacterRuns,
-                    Vector<ColorRun>&               backgroundColorRuns)
+  MarkupProcessData(Vector<ColorRun>&                  colorRuns,
+                    Vector<FontDescriptionRun>&        fontRuns,
+                    Vector<EmbeddedItem>&              items,
+                    Vector<Anchor>&                    anchors,
+                    Vector<UnderlinedCharacterRun>&    underlinedCharacterRuns,
+                    Vector<ColorRun>&                  backgroundColorRuns,
+                    Vector<StrikethroughCharacterRun>& strikethroughCharacterRuns)
   : colorRuns(colorRuns),
     fontRuns(fontRuns),
     items(items),
     anchors(anchors),
     underlinedCharacterRuns(underlinedCharacterRuns),
     backgroundColorRuns(backgroundColorRuns),
+    strikethroughCharacterRuns(strikethroughCharacterRuns),
     markupProcessedText()
   {
   }
 
-  Vector<ColorRun>&               colorRuns;               ///< The color runs.
-  Vector<FontDescriptionRun>&     fontRuns;                ///< The font description runs.
-  Vector<EmbeddedItem>&           items;                   ///< The embedded items.
-  Vector<Anchor>&                 anchors;                 ///< The anchors.
-  Vector<UnderlinedCharacterRun>& underlinedCharacterRuns; ///< The underlined character runs.
-  Vector<ColorRun>&               backgroundColorRuns;     ///< The background color runs.
-  std::string                     markupProcessedText;     ///< The mark-up string.
+  Vector<ColorRun>&                  colorRuns;                  ///< The color runs.
+  Vector<FontDescriptionRun>&        fontRuns;                   ///< The font description runs.
+  Vector<EmbeddedItem>&              items;                      ///< The embedded items.
+  Vector<Anchor>&                    anchors;                    ///< The anchors.
+  Vector<UnderlinedCharacterRun>&    underlinedCharacterRuns;    ///< The underlined character runs.
+  Vector<ColorRun>&                  backgroundColorRuns;        ///< The background color runs.
+  Vector<StrikethroughCharacterRun>& strikethroughCharacterRuns; ///< The strikethrough character runs.
+  std::string                        markupProcessedText;        ///< The mark-up string.
 };
 
 /**
index a210785..206d7f6 100644 (file)
@@ -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<StrikethroughGlyphRun>& strikethroughRuns,
+                                Vector4&                             strikethroughColor)
+  {
+    for(Vector<StrikethroughGlyphRun>::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<TextCacheEntry>&  newTextCache,
                     Vector<Extent>&          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<MeshRecord>& 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<StrikethroughGlyphRun> 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<Extent>::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);
     }
   }
index e6f346c..f7a1123 100644 (file)
@@ -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<StrikethroughGlyphRun>& strikethroughRuns,
+                              Vector4&                             strikethroughColor)
+{
+  for(Vector<StrikethroughGlyphRun>::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<StrikethroughGlyphRun> 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<GlyphRun> 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<GlyphRun>::ConstIterator itGlyphRun    = underlineRuns.Begin();
+  Vector<GlyphRun>::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<StrikethroughGlyphRun> 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<StrikethroughGlyphRun>::ConstIterator itGlyphRun    = strikethroughRuns.Begin();
+  Vector<StrikethroughGlyphRun>::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<GlyphRun> 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<GlyphRun>::ConstIterator itGlyphRun    = underlineRuns.Begin();
-    Vector<GlyphRun>::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;
index 51ac259..bf46b90 100644 (file)
@@ -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 "<color value='green'>Hello</color> <s>World</s> <i>Hello</i> <b>World</b>".
+   *    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:
   /**
index 8f2c864..e446294 100644 (file)
@@ -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
index e30a859..e877baa 100644 (file)
@@ -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<GlyphInfo>           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 (file)
index 0000000..3f0e1f4
--- /dev/null
@@ -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 <dali/public-api/math/vector4.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/character-run.h>
+
+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 (file)
index 0000000..34be0af
--- /dev/null
@@ -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 <dali/public-api/math/vector4.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/glyph-run.h>
+
+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
index bd93e68..2d1e28d 100644 (file)
@@ -571,6 +571,7 @@ bool ControllerImplModelUpdater::Update(Controller::Impl& impl, OperationsMask o
     if(impl.mModel->mVisualModel->IsMarkupProcessorEnabled())
     {
       impl.CopyUnderlinedFromLogicalToVisualModels(true);
+      impl.CopyStrikethroughFromLogicalToVisualModels();
     }
 
     updated = true;
index 6ffa715..5ee189b 100644 (file)
@@ -1626,6 +1626,34 @@ void Controller::Impl::CopyUnderlinedFromLogicalToVisualModels(bool shouldClearP
   }
 }
 
+void Controller::Impl::CopyStrikethroughFromLogicalToVisualModels()
+{
+  //Strikethrough character runs from markup-processor
+  const Vector<StrikethroughCharacterRun>& strikethroughCharacterRuns = mModel->mLogicalModel->mStrikethroughCharacterRuns;
+  const Vector<GlyphIndex>&                charactersToGlyph          = mModel->mVisualModel->mCharactersToGlyph;
+  const Vector<Length>&                    glyphsPerCharacter         = mModel->mVisualModel->mGlyphsPerCharacter;
+
+  mModel->mVisualModel->mStrikethroughRuns.Clear();
+
+  for(Vector<StrikethroughCharacterRun>::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)
index e697d81..12faee1 100644 (file)
@@ -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.
index ab90270..caf44f7 100644 (file)
@@ -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;
index 7cbc279..d5ce520 100644 (file)
@@ -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.
index f36c527..128f587 100644 (file)
@@ -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 <dali-toolkit/devel-api/text/text-enumerations-devel.h>
 #include <dali-toolkit/internal/text/line-run.h>
 #include <dali-toolkit/internal/text/script-run.h>
+#include <dali-toolkit/internal/text/strikethrough-glyph-run.h>
 #include <dali-toolkit/internal/text/text-definitions.h>
 #include <dali-toolkit/public-api/text/text-enumerations.h>
 
@@ -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
index 6001a6e..baa6b91 100644 (file)
@@ -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(),
index 4d8149b..443f9ab 100644 (file)
@@ -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.
index c6f76a4..67875b8 100644 (file)
@@ -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
index 93c420e..9b34dd4 100644 (file)
@@ -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
index 7b14c8c..37d6e0f 100644 (file)
@@ -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);
index 6ac00cd..6c4ff9b 100644 (file)
@@ -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;
index 710f0ab..673156b 100644 (file)
@@ -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 <dali-toolkit/internal/text/color-run.h>
 #include <dali-toolkit/internal/text/line-run.h>
+#include <dali-toolkit/internal/text/strikethrough-glyph-run.h>
 #include <dali-toolkit/public-api/text/text-enumerations.h>
 
 // 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<GlyphInfo>      mGlyphs;                 ///< For each glyph, the font's id, glyph's index within the font and glyph's metrics.
-  Vector<CharacterIndex> mGlyphsToCharacters;     ///< For each glyph, the index of the first character.
-  Vector<GlyphIndex>     mCharactersToGlyph;      ///< For each character, the index of the first glyph.
-  Vector<Length>         mCharactersPerGlyph;     ///< For each glyph, the number of characters that form the glyph.
-  Vector<Length>         mGlyphsPerCharacter;     ///< For each character, the number of glyphs that are shaped.
-  Vector<Vector2>        mGlyphPositions;         ///< For each glyph, the position.
-  Vector<LineRun>        mLines;                  ///< The laid out lines.
-  Vector<GlyphRun>       mUnderlineRuns;          ///< Runs of glyphs that are underlined.
-  Vector<Vector4>        mColors;                 ///< Colors of the glyphs.
-  Vector<ColorIndex>     mColorIndices;           ///< Indices to the vector of colors for each glyphs.
-  Vector<Vector4>        mBackgroundColors;       ///< Background colors of the glyphs.
-  Vector<ColorIndex>     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<GlyphInfo>             mGlyphs;                 ///< For each glyph, the font's id, glyph's index within the font and glyph's metrics.
+  Vector<CharacterIndex>        mGlyphsToCharacters;     ///< For each glyph, the index of the first character.
+  Vector<GlyphIndex>            mCharactersToGlyph;      ///< For each character, the index of the first glyph.
+  Vector<Length>                mCharactersPerGlyph;     ///< For each glyph, the number of characters that form the glyph.
+  Vector<Length>                mGlyphsPerCharacter;     ///< For each character, the number of glyphs that are shaped.
+  Vector<Vector2>               mGlyphPositions;         ///< For each glyph, the position.
+  Vector<LineRun>               mLines;                  ///< The laid out lines.
+  Vector<GlyphRun>              mUnderlineRuns;          ///< Runs of glyphs that are underlined.
+  Vector<Vector4>               mColors;                 ///< Colors of the glyphs.
+  Vector<ColorIndex>            mColorIndices;           ///< Indices to the vector of colors for each glyphs.
+  Vector<Vector4>               mBackgroundColors;       ///< Background colors of the glyphs.
+  Vector<ColorIndex>            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<StrikethroughGlyphRun> mStrikethroughRuns;      ///< Runs of glyphs that have strikethrough.
 
 private:
   Size mNaturalSize; ///< Size of the text with no line wrapping.