[dali_2.3.42] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / devel-api / text / text-utils-devel.cpp
index 7242687..483fc3f 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
  *
  * 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/internal/text/bidirectional-support.h>
 #include <dali-toolkit/internal/text/character-set-conversion.h>
 #include <dali-toolkit/internal/text/color-segmentation.h>
 #include <dali-toolkit/internal/text/bidirectional-support.h>
 #include <dali-toolkit/internal/text/character-set-conversion.h>
 #include <dali-toolkit/internal/text/color-segmentation.h>
+#include <dali-toolkit/internal/text/glyph-metrics-helper.h>
 #include <dali-toolkit/internal/text/layouts/layout-engine.h>
 #include <dali-toolkit/internal/text/layouts/layout-parameters.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/markup-processor/markup-processor.h>
 #include <dali-toolkit/internal/text/multi-language-support.h>
 #include <dali-toolkit/internal/text/multi-language-support.h>
+#include <dali-toolkit/internal/text/rendering/styles/character-spacing-helper-functions.h>
 #include <dali-toolkit/internal/text/segmentation.h>
 #include <dali-toolkit/internal/text/shaper.h>
 #include <dali-toolkit/internal/text/text-enumerations-impl.h>
 #include <dali-toolkit/internal/text/text-font-style.h>
 #include <dali-toolkit/internal/text/text-model.h>
 #include <dali-toolkit/internal/text/segmentation.h>
 #include <dali-toolkit/internal/text/shaper.h>
 #include <dali-toolkit/internal/text/text-enumerations-impl.h>
 #include <dali-toolkit/internal/text/text-font-style.h>
 #include <dali-toolkit/internal/text/text-model.h>
-#include <dali-toolkit/internal/text/glyph-metrics-helper.h>
 
 namespace Dali
 {
 
 namespace Dali
 {
@@ -150,6 +151,7 @@ void ShapeTextPreprocess(const RendererParameters& textParameters, TextAbstracti
   const uint8_t*       utf8                 = NULL; // pointer to the first character of the text (encoded in utf8)
   Length               textSize             = 0u;   // The length of the utf8 string.
 
   const uint8_t*       utf8                 = NULL; // pointer to the first character of the text (encoded in utf8)
   Length               textSize             = 0u;   // The length of the utf8 string.
 
+  FontClient&        fontClient              = internalDataModel.fontClient;
   Length&            numberOfCharacters      = internalDataModel.numberOfCharacters;
   Vector<Character>& mirroredUtf32Characters = internalDataModel.mirroredUtf32Characters;
   Text::ModelPtr&    textModel               = internalDataModel.textModel;
   Length&            numberOfCharacters      = internalDataModel.numberOfCharacters;
   Vector<Character>& mirroredUtf32Characters = internalDataModel.mirroredUtf32Characters;
   Text::ModelPtr&    textModel               = internalDataModel.textModel;
@@ -177,11 +179,15 @@ void ShapeTextPreprocess(const RendererParameters& textParameters, TextAbstracti
                                       textModel->mLogicalModel->mAnchors,
                                       textModel->mLogicalModel->mUnderlinedCharacterRuns,
                                       textModel->mLogicalModel->mBackgroundColorRuns,
                                       textModel->mLogicalModel->mAnchors,
                                       textModel->mLogicalModel->mUnderlinedCharacterRuns,
                                       textModel->mLogicalModel->mBackgroundColorRuns,
-                                      textModel->mLogicalModel->mStrikethroughCharacterRuns);
+                                      textModel->mLogicalModel->mStrikethroughCharacterRuns,
+                                      textModel->mLogicalModel->mBoundedParagraphRuns,
+                                      textModel->mLogicalModel->mCharacterSpacingCharacterRuns);
 
   if(textParameters.markupEnabled)
   {
 
   if(textParameters.markupEnabled)
   {
-    ProcessMarkupString(textParameters.text, markupProcessData);
+    MarkupPropertyData markupPropertyData(Color::MEDIUM_BLUE, Color::DARK_MAGENTA);
+
+    ProcessMarkupString(textParameters.text, markupPropertyData, markupProcessData);
     textSize = markupProcessData.markupProcessedText.size();
 
     // This is a bit horrible but std::string returns a (signed) char*
     textSize = markupProcessData.markupProcessedText.size();
 
     // This is a bit horrible but std::string returns a (signed) char*
@@ -212,10 +218,8 @@ void ShapeTextPreprocess(const RendererParameters& textParameters, TextAbstracti
 
   lineBreakInfo.Resize(numberOfCharacters, LINE_NO_BREAK);
 
 
   lineBreakInfo.Resize(numberOfCharacters, LINE_NO_BREAK);
 
-  SetLineBreakInfo(utf32Characters,
-                   0u,
-                   numberOfCharacters,
-                   lineBreakInfo);
+  TextAbstraction::Segmentation segmentation = TextAbstraction::Segmentation::Get();
+  SetLineBreakInfo(segmentation, utf32Characters, 0u, numberOfCharacters, lineBreakInfo);
 
   ////////////////////////////////////////////////////////////////////////////////
   // Retrieve the script runs.
 
   ////////////////////////////////////////////////////////////////////////////////
   // Retrieve the script runs.
@@ -285,11 +289,13 @@ void ShapeTextPreprocess(const RendererParameters& textParameters, TextAbstracti
 
   // Validates the fonts. If there is a character with no assigned font it sets a default one.
   // After this call, fonts are validated.
 
   // 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,
+  multilanguageSupport.ValidateFonts(fontClient,
+                                     utf32Characters,
                                      scripts,
                                      fontDescriptionRuns,
                                      defaultFontDescription,
                                      defaultPointSize,
                                      scripts,
                                      fontDescriptionRuns,
                                      defaultFontDescription,
                                      defaultPointSize,
+                                     1.0f,
                                      0u,
                                      numberOfCharacters,
                                      validFonts);
                                      0u,
                                      numberOfCharacters,
                                      validFonts);
@@ -300,7 +306,10 @@ void ShapeTextPreprocess(const RendererParameters& textParameters, TextAbstracti
 
   bidirectionalInfo.Reserve(1u);
 
 
   bidirectionalInfo.Reserve(1u);
 
-  SetBidirectionalInfo(utf32Characters,
+  TextAbstraction::BidirectionalSupport bidirectionalSupport = TextAbstraction::BidirectionalSupport::Get();
+
+  SetBidirectionalInfo(bidirectionalSupport,
+                       utf32Characters,
                        scripts,
                        lineBreakInfo,
                        0u,
                        scripts,
                        lineBreakInfo,
                        0u,
@@ -311,7 +320,8 @@ void ShapeTextPreprocess(const RendererParameters& textParameters, TextAbstracti
   if(hasBidirectionalText)
   {
     // Only set the character directions if there is right to left characters.
   if(hasBidirectionalText)
   {
     // Only set the character directions if there is right to left characters.
-    GetCharactersDirection(bidirectionalInfo,
+    GetCharactersDirection(bidirectionalSupport,
+                           bidirectionalInfo,
                            numberOfCharacters,
                            0u,
                            numberOfCharacters,
                            numberOfCharacters,
                            0u,
                            numberOfCharacters,
@@ -320,7 +330,8 @@ void ShapeTextPreprocess(const RendererParameters& textParameters, TextAbstracti
     // This paragraph has right to left text. Some characters may need to be mirrored.
     // TODO: consider if the mirrored string can be stored as well.
 
     // This paragraph has right to left text. Some characters may need to be mirrored.
     // TODO: consider if the mirrored string can be stored as well.
 
-    internalDataModel.isTextMirrored = GetMirroredText(utf32Characters,
+    internalDataModel.isTextMirrored = GetMirroredText(bidirectionalSupport,
+                                                       utf32Characters,
                                                        directions,
                                                        bidirectionalInfo,
                                                        0u,
                                                        directions,
                                                        bidirectionalInfo,
                                                        0u,
@@ -353,8 +364,12 @@ void ShapeText(TextAbstraction::TextRenderer::Parameters& rendererParameters, Ve
 
   newParagraphGlyphs.Reserve(1u);
 
 
   newParagraphGlyphs.Reserve(1u);
 
+  TextAbstraction::Shaping shaping = TextAbstraction::Shaping::Get();
+
   // Shapes the text.
   // Shapes the text.
-  ShapeText(textToShape,
+  ShapeText(shaping,
+            fontClient,
+            textToShape,
             lineBreakInfo,
             scripts,
             validFonts,
             lineBreakInfo,
             scripts,
             validFonts,
@@ -818,10 +833,14 @@ void Ellipsis(const RendererParameters& textParameters, TextAbstraction::TextRen
   Vector<LineRun>&        lines                     = textModel->mVisualModel->mLines; // The laid out lines.
   Vector<bool>&           isEmoji                   = internalDataModel.isEmoji;
   const Size              textLayoutArea            = internalDataModel.textLayoutArea;
   Vector<LineRun>&        lines                     = textModel->mVisualModel->mLines; // The laid out lines.
   Vector<bool>&           isEmoji                   = internalDataModel.isEmoji;
   const Size              textLayoutArea            = internalDataModel.textLayoutArea;
-  const float             characterSpacing          = textModel->mVisualModel->GetCharacterSpacing();
+  const float             modelCharacterSpacing     = textModel->mVisualModel->GetCharacterSpacing();
   float                   calculatedAdvance         = 0.f;
   Vector<CharacterIndex>& glyphToCharacterMap       = textModel->mVisualModel->mGlyphsToCharacters;
   const CharacterIndex*   glyphToCharacterMapBuffer = glyphToCharacterMap.Begin();
   float                   calculatedAdvance         = 0.f;
   Vector<CharacterIndex>& glyphToCharacterMap       = textModel->mVisualModel->mGlyphsToCharacters;
   const CharacterIndex*   glyphToCharacterMapBuffer = glyphToCharacterMap.Begin();
+
+  // Get the character-spacing runs.
+  const Vector<CharacterSpacingGlyphRun>& characterSpacingGlyphRuns = textModel->mVisualModel->GetCharacterSpacingGlyphRuns();
+
   ////////////////////////////////////////////////////////////////////////////////
   // Ellipsis the text.
   ////////////////////////////////////////////////////////////////////////////////
   ////////////////////////////////////////////////////////////////////////////////
   // Ellipsis the text.
   ////////////////////////////////////////////////////////////////////////////////
@@ -834,7 +853,7 @@ void Ellipsis(const RendererParameters& textParameters, TextAbstraction::TextRen
     {
       Length finalNumberOfGlyphs = 0u;
 
     {
       Length finalNumberOfGlyphs = 0u;
 
-      if((GetLineHeight(line)) > textLayoutArea.height)
+      if((GetLineHeight(line, (lines.Size() == 1))) > textLayoutArea.height)
       {
         // The height of the line is bigger than the height of the text area.
         // Show the ellipsis glyph even if it doesn't fit in the text area.
       {
         // The height of the line is bigger than the height of the text area.
         // Show the ellipsis glyph even if it doesn't fit in the text area.
@@ -907,7 +926,8 @@ void Ellipsis(const RendererParameters& textParameters, TextAbstraction::TextRen
                 firstPenSet = true;
               }
 
                 firstPenSet = true;
               }
 
-              calculatedAdvance = GetCalculatedAdvance(*(textModel->mLogicalModel->mText.Begin() + (*(glyphToCharacterMapBuffer + index))), characterSpacing, glyphToRemove.advance);
+              const float characterSpacing = GetGlyphCharacterSpacing(index, characterSpacingGlyphRuns, modelCharacterSpacing);
+              calculatedAdvance            = GetCalculatedAdvance(*(textModel->mLogicalModel->mText.Begin() + (*(glyphToCharacterMapBuffer + index))), characterSpacing, glyphToRemove.advance);
               removedGlypsWidth += std::min(calculatedAdvance, (glyphToRemove.xBearing + glyphToRemove.width));
 
               // Calculate the width of the ellipsis glyph and check if it fits.
               removedGlypsWidth += std::min(calculatedAdvance, (glyphToRemove.xBearing + glyphToRemove.width));
 
               // Calculate the width of the ellipsis glyph and check if it fits.
@@ -1041,8 +1061,12 @@ Size LayoutText(const RendererParameters& textParameters, TextAbstraction::TextR
 
   textModel->mLineWrapMode          = Text::LineWrap::WORD;
   textModel->mIgnoreSpacesAfterText = false;
 
   textModel->mLineWrapMode          = Text::LineWrap::WORD;
   textModel->mIgnoreSpacesAfterText = false;
+
+  TextAbstraction::BidirectionalSupport bidirectionalSupport = TextAbstraction::BidirectionalSupport::Get();
   Text::Layout::Parameters layoutParameters(internalDataModel.textLayoutArea,
   Text::Layout::Parameters layoutParameters(internalDataModel.textLayoutArea,
-                                            textModel);
+                                            textModel,
+                                            fontClient,
+                                            bidirectionalSupport);
 
   // Whether the last character is a new paragraph character.
   const Vector<Character>& textToShape = isTextMirrored ? mirroredUtf32Characters : textModel->mLogicalModel->mText;
 
   // Whether the last character is a new paragraph character.
   const Vector<Character>& textToShape = isTextMirrored ? mirroredUtf32Characters : textModel->mLogicalModel->mText;
@@ -1057,11 +1081,16 @@ Size LayoutText(const RendererParameters& textParameters, TextAbstraction::TextR
 
   // Update the visual model.
   Size newLayoutSize;
 
   // Update the visual model.
   Size newLayoutSize;
-  bool isAutoScrollEnabled = false;
+  bool isAutoScrollEnabled            = false;
+  bool isAutoScrollMaxTextureExceeded = false;
+  bool isHiddenInputEnabled           = false;
+
   layoutEngine.LayoutText(layoutParameters,
                           newLayoutSize,
                           textParameters.ellipsisEnabled,
                           isAutoScrollEnabled,
   layoutEngine.LayoutText(layoutParameters,
                           newLayoutSize,
                           textParameters.ellipsisEnabled,
                           isAutoScrollEnabled,
+                          isAutoScrollMaxTextureExceeded,
+                          isHiddenInputEnabled,
                           ellipsisPosition);
 
   return newLayoutSize;
                           ellipsisPosition);
 
   return newLayoutSize;
@@ -1527,12 +1556,14 @@ Dali::Property::Array RenderForLastIndex(RendererParameters& textParameters)
   float            penY               = 0.f;
   float            lineSize           = internalData.layoutEngine.GetDefaultLineSize();
   float            lineOffset         = 0.f;
   float            penY               = 0.f;
   float            lineSize           = internalData.layoutEngine.GetDefaultLineSize();
   float            lineOffset         = 0.f;
+  bool             isLastLine;
   for(unsigned int index = 0u; index < numberOfLines; ++index)
   {
     const LineRun& line = *(lines.Begin() + index);
     numberOfCharacters += line.characterRun.numberOfCharacters;
   for(unsigned int index = 0u; index < numberOfLines; ++index)
   {
     const LineRun& line = *(lines.Begin() + index);
     numberOfCharacters += line.characterRun.numberOfCharacters;
+    isLastLine = (index == numberOfLines - 1);
 
 
-    lineOffset = lineSize > 0.f ? lineSize : GetLineHeight(line);
+    lineOffset = lineSize > 0.f ? lineSize : GetLineHeight(line, isLastLine);
     penY += lineOffset;
     if((penY + lineOffset) > boundingBox)
     {
     penY += lineOffset;
     if((penY + lineOffset) > boundingBox)
     {