[Tizen] Fixing issue: On Text, reducing font-point-size when the Glyph-block-size... 67/258867/1
authorShrouq Sabah <s.sabah@samsung.com>
Wed, 10 Mar 2021 13:03:20 +0000 (15:03 +0200)
committerBowon Ryu <bowon.ryu@samsung.com>
Thu, 27 May 2021 04:20:59 +0000 (13:20 +0900)
Issue: On TextEditor or TextField when use font size (Point-Size) which creating Glyphs its size larger than Atlas-block size then logging error says that can’t create block and nothing appear in Text-Controller.

Solution: At Adaptor level, checking block size according to point-size if the block will be larger than Atlas size then keep decreasing point-size until achieve block that fit into Atlas size.
Toolkit calls API named “EnableAtlasLimitation” on Font-Client object to activate this validation on Adaptor level. Since the Atlas size information added as constants in Font-Client class.
Log warning that the point-size is reduced.
Automated test-cases added to Adaptor and Toolkit

Added APIs into font-client/Adaptor for Point-size & Atlas information instead of constants/literal values in toolkit.

Reproduce by:
Creating TextEditor or TextFiled then set properties:
mEditor.SetProperty( TextEditor::Property::POINT_SIZE, 330) ;
mEditor.SetProperty( TextEditor::Property::FONT_FAMILY, " DejaVu Sans ") ;

Logged error appears:
Logged ERROR: “ERROR: DALI: CreateAtlas Atlas 512 x 512 too small. Dimensions need to be at least 517x517”
Logged ERROR: “ERROR: DALI: Add Failed to create an atlas of 512 x 512 blocksize: 514 x 514.”

Change-Id: Ib4c57e80c21ca5efe905681fe050d3a65873c6f5

automated-tests/src/dali-toolkit-internal/utc-Dali-TextEditor-internal.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-TextField-internal.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp
dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp
dali-toolkit/internal/text/text-controller-impl.cpp

index ca724ff..bef3f33 100755 (executable)
@@ -21,6 +21,7 @@
 #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-editor-impl.h>
 #include <dali-toolkit/internal/text/text-controller.h>
 #include <dali-toolkit/internal/text/text-controller-impl.h>
@@ -108,4 +109,61 @@ int UtcDaliTextEditorMarkupUnderline(void)
 
   END_TEST;
 
+int UtcDaliTextEditorFontPointSizeLargerThanAtlas(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextEditorFontPointSizeLargerThanAtlas ");
+
+  // Create a text editor
+  TextEditor textEditor = TextEditor::New();
+  //Set size to avoid automatic eliding
+  textEditor.SetProperty( Actor::Property::SIZE, Vector2(1025, 1025));
+  //Set very large font-size using point-size
+  textEditor.SetProperty( TextEditor::Property::POINT_SIZE, 1000);
+  //Specify font-family
+  textEditor.SetProperty( TextEditor::Property::FONT_FAMILY, "DejaVu Sans");
+  //Set text to check if appear or not
+  textEditor.SetProperty(TextEditor::Property::TEXT, "A");
+
+  application.GetScene().Add( textEditor );
+
+  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 );
+
+  END_TEST;
+}
+
+
+int UtcDaliTextEditorFontPointSizeLargerThanAtlasPlaceholderCase(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextEditorFontPointSizeLargerThanAtlasPlaceholderCase ");
+
+  //Set Map of placeholder: text, font-family and point-size
+  Property::Map placeholderMapSet;
+  placeholderMapSet["text"] = "A";
+  placeholderMapSet["fontFamily"] = "DejaVu Sans";
+  placeholderMapSet["pixelSize"] = 1000.0f;
+
+  // Create a text editor
+  TextEditor textEditor = TextEditor::New();
+  //Set size to avoid automatic eliding
+  textEditor.SetProperty( Actor::Property::SIZE, Vector2(1025, 1025));
+  //Set placeholder
+  textEditor.SetProperty( TextEditor::Property::PLACEHOLDER, placeholderMapSet) ;
+
+  application.GetScene().Add( textEditor );
+
+  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 );
+
+  END_TEST;
 }
\ No newline at end of file
index 1d899d9..aa27455 100755 (executable)
@@ -21,6 +21,7 @@
 #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/text-controller-impl.h>
@@ -190,4 +191,62 @@ int UtcDaliTextFieldMarkupUnderline(void)
 
   END_TEST;
 
+int UtcDaliTextFieldFontPointSizeLargerThanAtlas(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextFieldFontPointSizeLargerThanAtlas ");
+
+  // Create a Text field
+  TextField textField = TextField::New();
+  //Set size to avoid automatic eliding
+  textField.SetProperty( Actor::Property::SIZE, Vector2(1025, 1025));
+  //Set very large font-size using point-size
+  textField.SetProperty( TextField::Property::POINT_SIZE, 1000) ;
+  //Specify font-family
+  textField.SetProperty( TextField::Property::FONT_FAMILY, "DejaVu Sans");
+  //Set text to check if appear or not
+  textField.SetProperty( TextField::Property::TEXT, "A");
+
+  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 );
+
+
+  END_TEST;
+}
+
+int UtcDaliTextFieldFontPointSizeLargerThanAtlasPlaceholderCase(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextFieldFontPointSizeLargerThanAtlasPlaceholderCase ");
+
+  //Set Map of placeholder: text, font-family and point-size
+  Property::Map placeholderMapSet;
+  placeholderMapSet["text"] = "A";
+  placeholderMapSet["fontFamily"] = "DejaVu Sans";
+  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));
+  //Set placeholder
+  textField.SetProperty( TextField::Property::PLACEHOLDER, placeholderMapSet) ;
+
+  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 );
+
+
+  END_TEST;
 }
\ No newline at end of file
index 62625ef..3bd9ee6 100644 (file)
@@ -3570,4 +3570,74 @@ int utcDaliTextEditorGetNaturalSizeDoesNotChangeLineCountLineWrapCharCase(void)
   DALI_TEST_EQUALS( lineCountAfter , lineCountBefore, TEST_LOCATION );
 
   END_TEST;
+}
+
+int UtcDaliTextEditorAtlasLimitationIsEnabledForLargeFontPointSize(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextEditorAtlasLimitationIsEnabledForLargeFontPointSize ");
+
+  // +2: First one to handle the equal case. Second one to handle odd to even case of GetNaturalSize
+  const uint32_t lessThanWidth = TextAbstraction::FontClient::MAX_TEXT_ATLAS_WIDTH - TextAbstraction::FontClient::PADDING_TEXT_ATLAS_BLOCK + 2;
+  const uint32_t lessThanHeight = TextAbstraction::FontClient::MAX_TEXT_ATLAS_HEIGHT - TextAbstraction::FontClient::PADDING_TEXT_ATLAS_BLOCK + 2;
+
+  // Create a text editor
+  TextEditor textEditor = TextEditor::New();
+
+  //Set size to avoid automatic eliding
+  textEditor.SetProperty( Actor::Property::SIZE, Vector2(1025, 1025));
+  //Set very large font-size using point-size
+  textEditor.SetProperty( TextEditor::Property::POINT_SIZE, 1000) ;
+  //Specify font-family
+  textEditor.SetProperty( TextEditor::Property::FONT_FAMILY, "DejaVu Sans");
+  //Set text to check if appear or not
+  textEditor.SetProperty( TextEditor::Property::TEXT, "A");
+
+  application.GetScene().Add( textEditor );
+
+  application.SendNotification();
+  application.Render();
+  //Use GetNaturalSize to verify that size of block does not exceed Atlas size
+  Vector3 naturalSize = textEditor.GetNaturalSize();
+
+  DALI_TEST_GREATER( lessThanWidth, static_cast<uint32_t>(naturalSize.width), TEST_LOCATION );
+  DALI_TEST_GREATER( lessThanHeight, static_cast<uint32_t>(naturalSize.height), TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliTextEditorAtlasLimitationIsEnabledPerformanceCases(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextEditorAtlasLimitationIsEnabledPerformanceCases ");
+
+  // +2: First one to handle the equal case. Second one to handle odd to even case of GetNaturalSize
+  const uint32_t lessThanWidth = TextAbstraction::FontClient::MAX_TEXT_ATLAS_WIDTH - TextAbstraction::FontClient::PADDING_TEXT_ATLAS_BLOCK + 2;
+  const uint32_t lessThanHeight = TextAbstraction::FontClient::MAX_TEXT_ATLAS_HEIGHT - TextAbstraction::FontClient::PADDING_TEXT_ATLAS_BLOCK + 2;
+
+  Vector3 naturalSize; //Use GetNaturalSize to verify that size of block does not exceed Atlas size
+  // Create a text editor
+  TextEditor textEditor = TextEditor::New();
+  //Set size to avoid automatic eliding
+  textEditor.SetProperty( Actor::Property::SIZE, Vector2(1025, 1025));
+  textEditor.SetProperty( TextEditor::Property::FONT_FAMILY, "DejaVu Sans");
+  textEditor.SetProperty( TextEditor::Property::TEXT, "A");
+
+  const int numberOfCases = 6;
+  int arrayCases[numberOfCases] = {323, 326, 330, 600, 1630, 2500};
+
+  for (int index=0; index < numberOfCases; index++)
+  {
+    tet_printf(" UtcDaliTextEditorAtlasLimitationIsEnabledPerformanceCases point-size= %d \n", arrayCases[index]);
+    textEditor.SetProperty( TextEditor::Property::POINT_SIZE, arrayCases[index]) ;
+    application.GetScene().Add( textEditor );
+    application.SendNotification();
+    application.Render();
+    naturalSize = textEditor.GetNaturalSize();
+    DALI_TEST_GREATER( lessThanWidth, static_cast<uint32_t>(naturalSize.width), TEST_LOCATION );
+    DALI_TEST_GREATER( lessThanHeight, static_cast<uint32_t>(naturalSize.height), TEST_LOCATION );
+
+  }
+
+  END_TEST;
 }
\ No newline at end of file
index 05eaeb1..c615774 100644 (file)
@@ -3555,4 +3555,77 @@ int utcDaliTextFieldMaxCharactersReachedAfterSetText(void)
   DALI_TEST_EQUALS( field.GetProperty( TextField::Property::TEXT ).Get<std::string>(), "123456789", TEST_LOCATION );
 
   END_TEST;
+}
+
+
+
+int UtcDaliTextFieldAtlasLimitationIsEnabledForLargeFontPointSize(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextFieldAtlasLimitationIsEnabledForLargeFontPointSize ");
+
+  // +2: First one to handle the equal case. Second one to handle odd to even case of GetNaturalSize
+  const uint32_t lessThanWidth = TextAbstraction::FontClient::MAX_TEXT_ATLAS_WIDTH - TextAbstraction::FontClient::PADDING_TEXT_ATLAS_BLOCK + 2;
+  const uint32_t lessThanHeight = TextAbstraction::FontClient::MAX_TEXT_ATLAS_HEIGHT - TextAbstraction::FontClient::PADDING_TEXT_ATLAS_BLOCK + 2;
+
+  // Create a text field
+  TextField textField = TextField::New();
+
+  //Set size to avoid automatic eliding
+  textField.SetProperty( Actor::Property::SIZE, Vector2(1025, 1025));
+  //Set very large font-size using point-size
+  textField.SetProperty( TextField::Property::POINT_SIZE, 1000) ;
+  //Specify font-family
+  textField.SetProperty( TextField::Property::FONT_FAMILY, "DejaVu Sans");
+  //Set text to check if appear or not
+  textField.SetProperty( TextField::Property::TEXT, "A");
+
+  application.GetScene().Add( textField );
+
+  application.SendNotification();
+  application.Render();
+  //Use GetNaturalSize to verify that size of block does not exceed Atlas size
+  Vector3 naturalSize = textField.GetNaturalSize();
+
+  DALI_TEST_GREATER( lessThanWidth, static_cast<uint32_t>(naturalSize.width), TEST_LOCATION );
+  DALI_TEST_GREATER( lessThanHeight, static_cast<uint32_t>(naturalSize.height), TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliTextFieldAtlasLimitationIsEnabledPerformanceCases(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextFieldAtlasLimitationIsEnabledPerformanceCases ");
+
+  // +2: First one to handle the equal case. Second one to handle odd to even case of GetNaturalSize
+  const uint32_t lessThanWidth = TextAbstraction::FontClient::MAX_TEXT_ATLAS_WIDTH - TextAbstraction::FontClient::PADDING_TEXT_ATLAS_BLOCK + 2;
+  const uint32_t lessThanHeight = TextAbstraction::FontClient::MAX_TEXT_ATLAS_HEIGHT - TextAbstraction::FontClient::PADDING_TEXT_ATLAS_BLOCK + 2;
+
+  Vector3 naturalSize; //Use GetNaturalSize to verify that size of block does not exceed Atlas size
+  // Create a text editor
+  TextField textField = TextField::New();
+
+  //Set size to avoid automatic eliding
+  textField.SetProperty( Actor::Property::SIZE, Vector2(1025, 1025));
+  textField.SetProperty( TextField::Property::FONT_FAMILY, "DejaVu Sans");
+  textField.SetProperty( TextField::Property::TEXT, "A");
+
+  const int numberOfCases = 6;
+  int arrayCases[numberOfCases] = {323, 326, 330, 600, 1630, 2500};
+
+  for (int index=0; index < numberOfCases; index++)
+  {
+    tet_printf(" UtcDaliTextFieldAtlasLimitationIsEnabledPerformanceCases point-size= %d \n", arrayCases[index]);
+    textField.SetProperty( TextField::Property::POINT_SIZE, arrayCases[index]) ;
+    application.GetScene().Add( textField );
+    application.SendNotification();
+    application.Render();
+    naturalSize = textField.GetNaturalSize();
+    DALI_TEST_GREATER( lessThanWidth, static_cast<uint32_t>(naturalSize.width), TEST_LOCATION );
+    DALI_TEST_GREATER( lessThanHeight, static_cast<uint32_t>(naturalSize.height), TEST_LOCATION );
+
+  }
+
+  END_TEST;
 }
\ No newline at end of file
index ecefef7..d8a7c18 100644 (file)
@@ -1802,3 +1802,38 @@ int UtcDaliToolkitTextlabelAnchorClicked(void)
 
   END_TEST;
 }
+
+int UtcDaliTextLabelAtlasLimitationIsEnabledForLargeFontPointSize(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextLabelAtlasLimitationIsEnabledForLargeFontPointSize ");
+
+  //TextLabel is not using Atlas but this is to unify font-size on text-controllers
+
+  // +2: First one to handle the equal case. Second one to handle odd to even case of GetNaturalSize
+  const uint32_t lessThanWidth = TextAbstraction::FontClient::MAX_TEXT_ATLAS_WIDTH - TextAbstraction::FontClient::PADDING_TEXT_ATLAS_BLOCK + 2;
+  const uint32_t lessThanHeight = TextAbstraction::FontClient::MAX_TEXT_ATLAS_HEIGHT - TextAbstraction::FontClient::PADDING_TEXT_ATLAS_BLOCK + 2;
+
+  // Create a text editor
+  TextLabel textLabel = TextLabel::New();
+  //Set size to avoid automatic eliding
+  textLabel.SetProperty( Actor::Property::SIZE, Vector2(1025, 1025));
+  //Set very large font-size using point-size
+  textLabel.SetProperty( TextLabel::Property::POINT_SIZE, 1000);
+  //Specify font-family
+  textLabel.SetProperty( TextLabel::Property::FONT_FAMILY, "DejaVu Sans");
+  //Set text to check if appear or not
+  textLabel.SetProperty( TextLabel::Property::TEXT, "A");
+
+  application.GetScene().Add( textLabel );
+
+  application.SendNotification();
+  application.Render();
+  //Use GetNaturalSize to verify that size of block does not exceed Atlas size
+  Vector3 naturalSize = textLabel.GetNaturalSize();
+
+  DALI_TEST_GREATER( lessThanWidth, static_cast<uint32_t>(naturalSize.width), TEST_LOCATION );
+  DALI_TEST_GREATER( lessThanHeight, static_cast<uint32_t>(naturalSize.height), TEST_LOCATION );
+
+  END_TEST;
+}
\ No newline at end of file
index 7b51d5b..1b1fc35 100644 (file)
@@ -46,10 +46,6 @@ Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT
 const float    ZERO(0.0f);
 const float    HALF(0.5f);
 const float    ONE(1.0f);
-const uint32_t DEFAULT_ATLAS_WIDTH  = 512u;
-const uint32_t DEFAULT_ATLAS_HEIGHT = 512u;
-const uint32_t MAX_ATLAS_WIDTH  = 1024u;
-const uint32_t MAX_ATLAS_HEIGHT = 1024u;
 const uint32_t DOUBLE_PIXEL_PADDING = 4u;//Padding will be added twice to Atlas
 const uint16_t NO_OUTLINE           = 0u;
 } // namespace
@@ -177,6 +173,9 @@ struct AtlasRenderer::Impl
 
   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.
+    const Size& maximumTextAtlasSize = mFontClient.GetMaximumTextAtlasSize(); //Retrieve maximum size of text-atlas-block from font-client.
+
     const bool glyphNotCached = !mGlyphManager.IsCached(glyph.fontId, glyph.index, style, slot); // Check FontGlyphRecord vector for entry with glyph index and fontId
 
     DALI_LOG_INFO(gLogFilter, Debug::Verbose, "AddGlyphs fontID[%u] glyphIndex[%u] [%s]\n", glyph.fontId, glyph.index, (glyphNotCached) ? "not cached" : "cached");
@@ -250,15 +249,15 @@ struct AtlasRenderer::Impl
           // If CheckAtlas in AtlasManager::Add can't fit the bitmap in the current atlas it will create a new atlas
 
           // Setting the block size and size of new atlas does not mean a new one will be created. An existing atlas may still surffice.
-          uint32_t default_width = DEFAULT_ATLAS_WIDTH;
-          uint32_t default_height = DEFAULT_ATLAS_HEIGHT;
+          uint32_t default_width = defaultTextAtlasSize.width;
+          uint32_t default_height = defaultTextAtlasSize.height;
 
           while (
             (blockSize.mNeededBlockWidth >= (default_width - (DOUBLE_PIXEL_PADDING + 1u)) ||
              blockSize.mNeededBlockHeight >= (default_height - (DOUBLE_PIXEL_PADDING + 1u)))
             &&
-            (default_width < MAX_ATLAS_WIDTH &&
-             default_height < MAX_ATLAS_HEIGHT))
+            (default_width < maximumTextAtlasSize.width &&
+             default_height < maximumTextAtlasSize.height))
           {
             default_width <<= 1u;
             default_height <<= 1u;
index 8140c84..2faaee1 100644 (file)
@@ -697,13 +697,16 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired)
       TextAbstraction::FontDescription defaultFontDescription;
       TextAbstraction::PointSize26Dot6 defaultPointSize = TextAbstraction::FontClient::DEFAULT_POINT_SIZE * mFontSizeScale;
 
+      //Get the number of points per one unit of point-size
+      uint32_t numberOfPointsPerOneUnitOfPointSize = mFontClient.GetNumberOfPointsPerOneUnitOfPointSize();
+
       if(IsShowingPlaceholderText() && mEventData && (nullptr != mEventData->mPlaceholderFont))
       {
         // If the placeholder font is set specifically, only placeholder font is changed.
         defaultFontDescription = mEventData->mPlaceholderFont->mFontDescription;
         if(mEventData->mPlaceholderFont->sizeDefined)
         {
-          defaultPointSize = mEventData->mPlaceholderFont->mDefaultPointSize * mFontSizeScale * 64u;
+          defaultPointSize = mEventData->mPlaceholderFont->mDefaultPointSize * mFontSizeScale * numberOfPointsPerOneUnitOfPointSize;
         }
       }
       else if(nullptr != mFontDefaults)
@@ -713,11 +716,11 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired)
 
         if(mTextFitEnabled)
         {
-          defaultPointSize = mFontDefaults->mFitPointSize * 64u;
+          defaultPointSize = mFontDefaults->mFitPointSize * numberOfPointsPerOneUnitOfPointSize;
         }
         else
         {
-          defaultPointSize = mFontDefaults->mDefaultPointSize * mFontSizeScale * 64u;
+          defaultPointSize = mFontDefaults->mDefaultPointSize * mFontSizeScale * numberOfPointsPerOneUnitOfPointSize;
         }
       }