Copyless glyph bitmap creation 32/276732/13
authorEunki, Hong <eunkiki.hong@samsung.com>
Thu, 23 Jun 2022 12:54:44 +0000 (21:54 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Thu, 30 Jun 2022 05:18:38 +0000 (14:18 +0900)
We update glyphBufferData check the buffer's ownership.
So Typesetter now can use the glyph buffer without memcpy.

Change-Id: I2fff8a10f5ed93c2e053825a61350ae5d384f3e8
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Typesetter.cpp
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

index 8ec03d6..462a883 100644 (file)
 #include <iostream>
 
 #include <stdlib.h>
 #include <iostream>
 
 #include <stdlib.h>
-#include <limits>
 #include <unistd.h>
 #include <unistd.h>
+#include <limits>
 
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/dali-toolkit.h>
 
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/dali-toolkit.h>
-#include <toolkit-text-utils.h>
+#include <dali-toolkit/devel-api/text/bitmap-font.h>
+#include <dali-toolkit/devel-api/text/text-enumerations-devel.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.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.h>
-#include <dali-toolkit/devel-api/text/text-enumerations-devel.h>
 #include <dali/devel-api/text-abstraction/bitmap-font.h>
 #include <dali/devel-api/text-abstraction/bitmap-font.h>
-#include <dali-toolkit/devel-api/text/bitmap-font.h>
+#include <toolkit-environment-variable.h>
+#include <toolkit-text-utils.h>
 
 using namespace Dali;
 using namespace Toolkit;
 
 using namespace Dali;
 using namespace Toolkit;
@@ -37,8 +38,10 @@ using namespace Text;
 
 namespace
 {
 
 namespace
 {
-const std::string DEFAULT_FONT_DIR( "/resources/fonts" );
+const std::string     DEFAULT_FONT_DIR("/resources/fonts");
 const PointSize26Dot6 EMOJI_FONT_SIZE = 3840u; // 60 * 64
 const PointSize26Dot6 EMOJI_FONT_SIZE = 3840u; // 60 * 64
+
+constexpr auto DALI_RENDERED_GLYPH_COMPRESS_POLICY = "DALI_RENDERED_GLYPH_COMPRESS_POLICY";
 } // namespace
 
 int UtcDaliTextTypesetter(void)
 } // namespace
 
 int UtcDaliTextTypesetter(void)
@@ -50,8 +53,8 @@ int UtcDaliTextTypesetter(void)
   ControllerPtr controller = Controller::New();
 
   // Tests the rendering controller has been created.
   ControllerPtr controller = Controller::New();
 
   // Tests the rendering controller has been created.
-  TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
-  DALI_TEST_CHECK( typesetter );
+  TypesetterPtr typesetter = Typesetter::New(controller->GetTextModel());
+  DALI_TEST_CHECK(typesetter);
 
   tet_result(TET_PASS);
   END_TEST;
 
   tet_result(TET_PASS);
   END_TEST;
@@ -66,82 +69,293 @@ int UtcDaliTextTypesetterGetViewModel(void)
   ControllerPtr controller = Controller::New();
 
   // Tests the rendering controller has been created.
   ControllerPtr controller = Controller::New();
 
   // Tests the rendering controller has been created.
-  TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
-  DALI_TEST_CHECK( typesetter );
+  TypesetterPtr typesetter = Typesetter::New(controller->GetTextModel());
+  DALI_TEST_CHECK(typesetter);
 
   // Tests the view model has been created.
   ViewModel* model = typesetter->GetViewModel();
 
   // Tests the view model has been created.
   ViewModel* model = typesetter->GetViewModel();
-  DALI_TEST_CHECK( NULL != model );
+  DALI_TEST_CHECK(NULL != model);
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextRenderingControllerRenderRGBA(void)
+{
+  tet_infoline(" UtcDaliTextRenderingControllerRenderRGBA");
+  ToolkitTestApplication application;
+
+  // Load some fonts.
+  TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+
+  char*             pathNamePtr = get_current_dir_name();
+  const std::string pathName(pathNamePtr);
+  free(pathNamePtr);
+
+  fontClient.GetFontId(pathName + DEFAULT_FONT_DIR + "/tizen/BreezeColorEmoji.ttf", EMOJI_FONT_SIZE);
+  fontClient.GetFontId(pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf");
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  // Configures the text controller similarly to the text-label.
+  ConfigureTextLabel(controller);
+
+  // Sets the text.
+  controller->SetMarkupProcessorEnabled(true);
+  controller->SetText("<font family='TizenSansRegular'>Hello world </font><font family='BreezeColorEmoji'>\xF0\x9F\x98\x81</font>");
+
+  // Creates the text's model and relais-out the text.
+  const Size relayoutSize(120.f, 60.f);
+  controller->Relayout(relayoutSize);
+
+  // Tests the rendering controller has been created.
+  TypesetterPtr renderingController = Typesetter::New(controller->GetTextModel());
+  DALI_TEST_CHECK(renderingController);
+
+  // Renders the text and creates the final bitmap.
+  PixelData bitmap = renderingController->Render(relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT);
+  DALI_TEST_CHECK(bitmap);
+
+  DALI_TEST_EQUALS(120u, bitmap.GetWidth(), TEST_LOCATION);
+  DALI_TEST_EQUALS(60u, bitmap.GetHeight(), TEST_LOCATION);
+  DALI_TEST_EQUALS(Pixel::RGBA8888, bitmap.GetPixelFormat(), TEST_LOCATION);
+
+  // Changes vertical alignment.
+  controller->SetVerticalAlignment(Text::VerticalAlignment::CENTER);
+  controller->Relayout(relayoutSize);
+
+  // Renders the text and creates the final bitmap.
+  bitmap = renderingController->Render(relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT);
+  DALI_TEST_CHECK(bitmap);
+
+  DALI_TEST_EQUALS(120u, bitmap.GetWidth(), TEST_LOCATION);
+  DALI_TEST_EQUALS(60u, bitmap.GetHeight(), TEST_LOCATION);
+  DALI_TEST_EQUALS(Pixel::RGBA8888, bitmap.GetPixelFormat(), TEST_LOCATION);
+
+  controller->SetVerticalAlignment(Text::VerticalAlignment::BOTTOM);
+  controller->Relayout(relayoutSize);
+
+  // Renders the text and creates the final bitmap.
+  bitmap = renderingController->Render(relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT);
+  DALI_TEST_CHECK(bitmap);
+
+  DALI_TEST_EQUALS(120u, bitmap.GetWidth(), TEST_LOCATION);
+  DALI_TEST_EQUALS(60u, bitmap.GetHeight(), TEST_LOCATION);
+  DALI_TEST_EQUALS(Pixel::RGBA8888, bitmap.GetPixelFormat(), TEST_LOCATION);
 
   tet_result(TET_PASS);
   END_TEST;
 }
 
 
   tet_result(TET_PASS);
   END_TEST;
 }
 
-int UtcDaliTextRenderingControllerRender(void)
+int UtcDaliTextRenderingControllerRenderLuminance(void)
 {
 {
-  tet_infoline(" UtcDaliTextRenderingControllerRender");
+  tet_infoline(" UtcDaliTextRenderingControllerRenderLuminance");
   ToolkitTestApplication application;
 
   // Load some fonts.
   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
 
   ToolkitTestApplication application;
 
   // Load some fonts.
   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
 
-  char* pathNamePtr = get_current_dir_name();
-  const std::string pathName( pathNamePtr );
-  free( pathNamePtr );
+  char*             pathNamePtr = get_current_dir_name();
+  const std::string pathName(pathNamePtr);
+  free(pathNamePtr);
 
 
-  fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/BreezeColorEmoji.ttf", EMOJI_FONT_SIZE );
-  fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf" );
+  fontClient.GetFontId(pathName + DEFAULT_FONT_DIR + "/tizen/BreezeColorEmoji.ttf", EMOJI_FONT_SIZE);
+  fontClient.GetFontId(pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf");
 
   // Creates a text controller.
   ControllerPtr controller = Controller::New();
 
   // Configures the text controller similarly to the text-label.
 
   // Creates a text controller.
   ControllerPtr controller = Controller::New();
 
   // Configures the text controller similarly to the text-label.
-  ConfigureTextLabel( controller );
+  ConfigureTextLabel(controller);
 
   // Sets the text.
 
   // Sets the text.
-  controller->SetMarkupProcessorEnabled( true );
-  controller->SetText( "<font family='TizenSansRegular'>Hello world </font><font family='BreezeColorEmoji'>\xF0\x9F\x98\x81</font>" );
+  controller->SetMarkupProcessorEnabled(true);
+  controller->SetText("<font family='TizenSansRegular'>Hello world </font><font family='BreezeColorEmoji'>\xF0\x9F\x98\x81</font>");
 
   // Creates the text's model and relais-out the text.
 
   // Creates the text's model and relais-out the text.
-  const Size relayoutSize( 120.f, 60.f );
-  controller->Relayout( relayoutSize );
+  const Size relayoutSize(120.f, 60.f);
+  controller->Relayout(relayoutSize);
 
   // Tests the rendering controller has been created.
 
   // Tests the rendering controller has been created.
-  TypesetterPtr renderingController = Typesetter::New( controller->GetTextModel() );
-  DALI_TEST_CHECK( renderingController );
+  TypesetterPtr renderingController = Typesetter::New(controller->GetTextModel());
+  DALI_TEST_CHECK(renderingController);
 
   // Renders the text and creates the final bitmap.
 
   // Renders the text and creates the final bitmap.
-  PixelData bitmap = renderingController->Render( relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT );
-  DALI_TEST_CHECK( bitmap );
+  PixelData bitmap = renderingController->Render(relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT, Typesetter::RENDER_TEXT_AND_STYLES, false, Pixel::L8);
+  DALI_TEST_CHECK(bitmap);
 
 
-  DALI_TEST_EQUALS( 120u, bitmap.GetWidth(), TEST_LOCATION );
-  DALI_TEST_EQUALS( 60u, bitmap.GetHeight(), TEST_LOCATION );
-  DALI_TEST_EQUALS( Pixel::RGBA8888, bitmap.GetPixelFormat(), TEST_LOCATION );
+  DALI_TEST_EQUALS(120u, bitmap.GetWidth(), TEST_LOCATION);
+  DALI_TEST_EQUALS(60u, bitmap.GetHeight(), TEST_LOCATION);
+  DALI_TEST_EQUALS(Pixel::L8, bitmap.GetPixelFormat(), TEST_LOCATION);
 
   // Changes vertical alignment.
 
   // Changes vertical alignment.
-  controller->SetVerticalAlignment( Text::VerticalAlignment::CENTER );
-  controller->Relayout( relayoutSize );
+  controller->SetVerticalAlignment(Text::VerticalAlignment::CENTER);
+  controller->Relayout(relayoutSize);
 
   // Renders the text and creates the final bitmap.
 
   // Renders the text and creates the final bitmap.
-  bitmap = renderingController->Render( relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT );
-  DALI_TEST_CHECK( bitmap );
+  bitmap = renderingController->Render(relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT, Typesetter::RENDER_TEXT_AND_STYLES, false, Pixel::L8);
+  DALI_TEST_CHECK(bitmap);
 
 
-  DALI_TEST_EQUALS( 120u, bitmap.GetWidth(), TEST_LOCATION );
-  DALI_TEST_EQUALS( 60u, bitmap.GetHeight(), TEST_LOCATION );
-  DALI_TEST_EQUALS( Pixel::RGBA8888, bitmap.GetPixelFormat(), TEST_LOCATION );
+  DALI_TEST_EQUALS(120u, bitmap.GetWidth(), TEST_LOCATION);
+  DALI_TEST_EQUALS(60u, bitmap.GetHeight(), TEST_LOCATION);
+  DALI_TEST_EQUALS(Pixel::L8, bitmap.GetPixelFormat(), TEST_LOCATION);
 
 
-  controller->SetVerticalAlignment( Text::VerticalAlignment::BOTTOM );
-  controller->Relayout( relayoutSize );
+  controller->SetVerticalAlignment(Text::VerticalAlignment::BOTTOM);
+  controller->Relayout(relayoutSize);
 
   // Renders the text and creates the final bitmap.
 
   // Renders the text and creates the final bitmap.
-  bitmap = renderingController->Render( relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT );
-  DALI_TEST_CHECK( bitmap );
+  bitmap = renderingController->Render(relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT, Typesetter::RENDER_TEXT_AND_STYLES, false, Pixel::L8);
+  DALI_TEST_CHECK(bitmap);
 
 
-  DALI_TEST_EQUALS( 120u, bitmap.GetWidth(), TEST_LOCATION );
-  DALI_TEST_EQUALS( 60u, bitmap.GetHeight(), TEST_LOCATION );
-  DALI_TEST_EQUALS( Pixel::RGBA8888, bitmap.GetPixelFormat(), TEST_LOCATION );
+  DALI_TEST_EQUALS(120u, bitmap.GetWidth(), TEST_LOCATION);
+  DALI_TEST_EQUALS(60u, bitmap.GetHeight(), TEST_LOCATION);
+  DALI_TEST_EQUALS(Pixel::L8, bitmap.GetPixelFormat(), TEST_LOCATION);
 
   tet_result(TET_PASS);
 
   tet_result(TET_PASS);
+
+  END_TEST;
+}
+
+int UtcDaliTextRenderingControllerRenderWithCompressRGBA(void)
+{
+  EnvironmentVariable::SetTestEnvironmentVariable(DALI_RENDERED_GLYPH_COMPRESS_POLICY, "m");
+
+  tet_infoline(" UtcDaliTextRenderingControllerRenderWithCompressRGBA");
+  ToolkitTestApplication application;
+
+  // Load some fonts.
+  TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+
+  char*             pathNamePtr = get_current_dir_name();
+  const std::string pathName(pathNamePtr);
+  free(pathNamePtr);
+
+  fontClient.GetFontId(pathName + DEFAULT_FONT_DIR + "/tizen/BreezeColorEmoji.ttf", EMOJI_FONT_SIZE);
+  fontClient.GetFontId(pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf");
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  // Configures the text controller similarly to the text-label.
+  ConfigureTextLabel(controller);
+
+  // Sets the text.
+  controller->SetMarkupProcessorEnabled(true);
+  controller->SetText("<font family='TizenSansRegular'>Hello world </font><font family='BreezeColorEmoji'>\xF0\x9F\x98\x81</font>");
+
+  // Creates the text's model and relais-out the text.
+  const Size relayoutSize(120.f, 60.f);
+  controller->Relayout(relayoutSize);
+
+  // Tests the rendering controller has been created.
+  TypesetterPtr renderingController = Typesetter::New(controller->GetTextModel());
+  DALI_TEST_CHECK(renderingController);
+
+  // Renders the text and creates the final bitmap.
+  PixelData bitmap = renderingController->Render(relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT);
+  DALI_TEST_CHECK(bitmap);
+
+  DALI_TEST_EQUALS(120u, bitmap.GetWidth(), TEST_LOCATION);
+  DALI_TEST_EQUALS(60u, bitmap.GetHeight(), TEST_LOCATION);
+  DALI_TEST_EQUALS(Pixel::RGBA8888, bitmap.GetPixelFormat(), TEST_LOCATION);
+
+  // Changes vertical alignment.
+  controller->SetVerticalAlignment(Text::VerticalAlignment::CENTER);
+  controller->Relayout(relayoutSize);
+
+  // Renders the text and creates the final bitmap.
+  bitmap = renderingController->Render(relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT);
+  DALI_TEST_CHECK(bitmap);
+
+  DALI_TEST_EQUALS(120u, bitmap.GetWidth(), TEST_LOCATION);
+  DALI_TEST_EQUALS(60u, bitmap.GetHeight(), TEST_LOCATION);
+  DALI_TEST_EQUALS(Pixel::RGBA8888, bitmap.GetPixelFormat(), TEST_LOCATION);
+
+  controller->SetVerticalAlignment(Text::VerticalAlignment::BOTTOM);
+  controller->Relayout(relayoutSize);
+
+  // Renders the text and creates the final bitmap.
+  bitmap = renderingController->Render(relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT);
+  DALI_TEST_CHECK(bitmap);
+
+  DALI_TEST_EQUALS(120u, bitmap.GetWidth(), TEST_LOCATION);
+  DALI_TEST_EQUALS(60u, bitmap.GetHeight(), TEST_LOCATION);
+  DALI_TEST_EQUALS(Pixel::RGBA8888, bitmap.GetPixelFormat(), TEST_LOCATION);
+
+  tet_result(TET_PASS);
+
+  END_TEST;
+}
+
+int UtcDaliTextRenderingControllerRenderWithCompressLuminance(void)
+{
+  EnvironmentVariable::SetTestEnvironmentVariable(DALI_RENDERED_GLYPH_COMPRESS_POLICY, "m");
+
+  tet_infoline(" UtcDaliTextRenderingControllerRenderWithCompressLuminance");
+  ToolkitTestApplication application;
+
+  // Load some fonts.
+  TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+
+  char*             pathNamePtr = get_current_dir_name();
+  const std::string pathName(pathNamePtr);
+  free(pathNamePtr);
+
+  fontClient.GetFontId(pathName + DEFAULT_FONT_DIR + "/tizen/BreezeColorEmoji.ttf", EMOJI_FONT_SIZE);
+  fontClient.GetFontId(pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf");
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  // Configures the text controller similarly to the text-label.
+  ConfigureTextLabel(controller);
+
+  // Sets the text.
+  controller->SetMarkupProcessorEnabled(true);
+  controller->SetText("<font family='TizenSansRegular'>Hello world </font><font family='BreezeColorEmoji'>\xF0\x9F\x98\x81</font>");
+
+  // Creates the text's model and relais-out the text.
+  const Size relayoutSize(120.f, 60.f);
+  controller->Relayout(relayoutSize);
+
+  // Tests the rendering controller has been created.
+  TypesetterPtr renderingController = Typesetter::New(controller->GetTextModel());
+  DALI_TEST_CHECK(renderingController);
+
+  // Renders the text and creates the final bitmap.
+  PixelData bitmap = renderingController->Render(relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT, Typesetter::RENDER_TEXT_AND_STYLES, false, Pixel::L8);
+  DALI_TEST_CHECK(bitmap);
+
+  DALI_TEST_EQUALS(120u, bitmap.GetWidth(), TEST_LOCATION);
+  DALI_TEST_EQUALS(60u, bitmap.GetHeight(), TEST_LOCATION);
+  DALI_TEST_EQUALS(Pixel::L8, bitmap.GetPixelFormat(), TEST_LOCATION);
+
+  // Changes vertical alignment.
+  controller->SetVerticalAlignment(Text::VerticalAlignment::CENTER);
+  controller->Relayout(relayoutSize);
+
+  // Renders the text and creates the final bitmap.
+  bitmap = renderingController->Render(relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT, Typesetter::RENDER_TEXT_AND_STYLES, false, Pixel::L8);
+  DALI_TEST_CHECK(bitmap);
+
+  DALI_TEST_EQUALS(120u, bitmap.GetWidth(), TEST_LOCATION);
+  DALI_TEST_EQUALS(60u, bitmap.GetHeight(), TEST_LOCATION);
+  DALI_TEST_EQUALS(Pixel::L8, bitmap.GetPixelFormat(), TEST_LOCATION);
+
+  controller->SetVerticalAlignment(Text::VerticalAlignment::BOTTOM);
+  controller->Relayout(relayoutSize);
+
+  // Renders the text and creates the final bitmap.
+  bitmap = renderingController->Render(relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT, Typesetter::RENDER_TEXT_AND_STYLES, false, Pixel::L8);
+  DALI_TEST_CHECK(bitmap);
+
+  DALI_TEST_EQUALS(120u, bitmap.GetWidth(), TEST_LOCATION);
+  DALI_TEST_EQUALS(60u, bitmap.GetHeight(), TEST_LOCATION);
+  DALI_TEST_EQUALS(Pixel::L8, bitmap.GetPixelFormat(), TEST_LOCATION);
+
+  tet_result(TET_PASS);
+
   END_TEST;
 }
 
   END_TEST;
 }
 
@@ -154,45 +368,45 @@ int UtcDaliTextTypesetterVerticalLineAlignment(void)
   ControllerPtr controller = Controller::New();
 
   // Configures the text controller similarly to the text-label.
   ControllerPtr controller = Controller::New();
 
   // Configures the text controller similarly to the text-label.
-  ConfigureTextLabel( controller );
+  ConfigureTextLabel(controller);
 
   // Sets the text.
 
   // Sets the text.
-  controller->SetMarkupProcessorEnabled( true );
-  controller->SetText( "<font family='TizenSansRegular'>Hello world</font>" );
+  controller->SetMarkupProcessorEnabled(true);
+  controller->SetText("<font family='TizenSansRegular'>Hello world</font>");
 
   // Creates the text's model and relais-out the text.
 
   // Creates the text's model and relais-out the text.
-  const Size relayoutSize( 120.f, 60.f );
-  controller->Relayout( relayoutSize );
+  const Size relayoutSize(120.f, 60.f);
+  controller->Relayout(relayoutSize);
 
   // Tests the rendering controller has been created.
 
   // Tests the rendering controller has been created.
-  TypesetterPtr renderingController = Typesetter::New( controller->GetTextModel() );
-  DALI_TEST_CHECK( renderingController );
+  TypesetterPtr renderingController = Typesetter::New(controller->GetTextModel());
+  DALI_TEST_CHECK(renderingController);
 
   {
 
   {
-    controller->SetVerticalLineAlignment( Dali::Toolkit::DevelText::VerticalLineAlignment::TOP );
-    controller->Relayout( relayoutSize );
+    controller->SetVerticalLineAlignment(Dali::Toolkit::DevelText::VerticalLineAlignment::TOP);
+    controller->Relayout(relayoutSize);
 
     // Renders the text and creates the final bitmap.
 
     // Renders the text and creates the final bitmap.
-    auto bitmap = renderingController->Render( relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT );
-    DALI_TEST_EQUALS( 60u, bitmap.GetHeight(), TEST_LOCATION );
+    auto bitmap = renderingController->Render(relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT);
+    DALI_TEST_EQUALS(60u, bitmap.GetHeight(), TEST_LOCATION);
   }
 
   {
   }
 
   {
-    controller->SetVerticalLineAlignment( Dali::Toolkit::DevelText::VerticalLineAlignment::MIDDLE );
-    controller->Relayout( relayoutSize );
+    controller->SetVerticalLineAlignment(Dali::Toolkit::DevelText::VerticalLineAlignment::MIDDLE);
+    controller->Relayout(relayoutSize);
 
     // Renders the text and creates the final bitmap.
 
     // Renders the text and creates the final bitmap.
-    auto bitmap = renderingController->Render( relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT );
-    DALI_TEST_EQUALS( 60u, bitmap.GetHeight(), TEST_LOCATION );
+    auto bitmap = renderingController->Render(relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT);
+    DALI_TEST_EQUALS(60u, bitmap.GetHeight(), TEST_LOCATION);
   }
 
   {
   }
 
   {
-    controller->SetVerticalLineAlignment( Dali::Toolkit::DevelText::VerticalLineAlignment::BOTTOM );
-    controller->Relayout( relayoutSize );
+    controller->SetVerticalLineAlignment(Dali::Toolkit::DevelText::VerticalLineAlignment::BOTTOM);
+    controller->Relayout(relayoutSize);
 
     // Renders the text and creates the final bitmap.
 
     // Renders the text and creates the final bitmap.
-    auto bitmap = renderingController->Render( relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT );
-    DALI_TEST_EQUALS( 60u, bitmap.GetHeight(), TEST_LOCATION );
+    auto bitmap = renderingController->Render(relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT);
+    DALI_TEST_EQUALS(60u, bitmap.GetHeight(), TEST_LOCATION);
   }
 
   tet_result(TET_PASS);
   }
 
   tet_result(TET_PASS);
@@ -205,45 +419,45 @@ int UtcDaliTextTypesetterBitmapFont(void)
   ToolkitTestApplication application;
 
   DevelText::BitmapFontDescription fontDescription;
   ToolkitTestApplication application;
 
   DevelText::BitmapFontDescription fontDescription;
-  fontDescription.name = "Digits";
-  fontDescription.underlinePosition = 0.f;
+  fontDescription.name               = "Digits";
+  fontDescription.underlinePosition  = 0.f;
   fontDescription.underlineThickness = 0.f;
   fontDescription.underlineThickness = 0.f;
-  fontDescription.isColorFont = true;
+  fontDescription.isColorFont        = true;
 
 
-  fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0031.png", "0", 34.f, 0.f } );
-  fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0032.png", "1", 34.f, 0.f } );
+  fontDescription.glyphs.push_back({TEST_RESOURCE_DIR "/fonts/bitmap/u0031.png", "0", 34.f, 0.f});
+  fontDescription.glyphs.push_back({TEST_RESOURCE_DIR "/fonts/bitmap/u0032.png", "1", 34.f, 0.f});
 
   TextAbstraction::BitmapFont bitmapFont;
 
   TextAbstraction::BitmapFont bitmapFont;
-  DevelText::CreateBitmapFont( fontDescription, bitmapFont );
+  DevelText::CreateBitmapFont(fontDescription, bitmapFont);
 
   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
 
   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
-  fontClient.GetFontId( bitmapFont );
+  fontClient.GetFontId(bitmapFont);
 
   // Creates a text controller.
   ControllerPtr controller = Controller::New();
 
   // Configures the text controller similarly to the text-label.
 
   // Creates a text controller.
   ControllerPtr controller = Controller::New();
 
   // Configures the text controller similarly to the text-label.
-  ConfigureTextLabel( controller );
+  ConfigureTextLabel(controller);
 
   // Sets the text.
 
   // Sets the text.
-  controller->SetMarkupProcessorEnabled( true );
-  controller->SetText( "<font family='Digits'><color 'value'='red'>0</color></font>" );
+  controller->SetMarkupProcessorEnabled(true);
+  controller->SetText("<font family='Digits'><color 'value'='red'>0</color></font>");
 
   // Creates the text's model and relais-out the text.
 
   // Creates the text's model and relais-out the text.
-  const Size relayoutSize( 31.f, 34.f );
-  controller->Relayout( relayoutSize );
+  const Size relayoutSize(31.f, 34.f);
+  controller->Relayout(relayoutSize);
 
   // Tests the rendering controller has been created.
 
   // Tests the rendering controller has been created.
-  TypesetterPtr renderingController = Typesetter::New( controller->GetTextModel() );
-  DALI_TEST_CHECK( renderingController );
+  TypesetterPtr renderingController = Typesetter::New(controller->GetTextModel());
+  DALI_TEST_CHECK(renderingController);
 
 
-  controller->Relayout( relayoutSize );
+  controller->Relayout(relayoutSize);
 
   // Renders the text and creates the final bitmap.
 
   // Renders the text and creates the final bitmap.
-  auto bitmap = renderingController->Render( relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT );
+  auto bitmap = renderingController->Render(relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT);
 
 
-  DALI_TEST_EQUALS( 31u, bitmap.GetWidth(), TEST_LOCATION );
-  DALI_TEST_EQUALS( 34u, bitmap.GetHeight(), TEST_LOCATION );
+  DALI_TEST_EQUALS(31u, bitmap.GetWidth(), TEST_LOCATION);
+  DALI_TEST_EQUALS(34u, bitmap.GetHeight(), TEST_LOCATION);
 
   tet_result(TET_PASS);
   END_TEST;
 
   tet_result(TET_PASS);
   END_TEST;
index 847954f..5913134 100644 (file)
@@ -215,14 +215,36 @@ struct AtlasRenderer::Impl
                                  glyphBufferData,
                                  style.outline);
 
                                  glyphBufferData,
                                  style.outline);
 
+        uint32_t glyphBufferSize = glyphBufferData.width * glyphBufferData.height * Pixel::GetBytesPerPixel(glyphBufferData.format);
+        // If glyph buffer data don't have ownership, Or if we need to decompress, create new memory and replace ownership.
+        if(!glyphBufferData.isBufferOwned || glyphBufferData.compressType != TextAbstraction::FontClient::GlyphBufferData::CompressType::NO_COMPRESS)
+        {
+          uint8_t* newBuffer = (uint8_t*)malloc(glyphBufferSize);
+          if(DALI_LIKELY(newBuffer != nullptr))
+          {
+            TextAbstraction::FontClient::GlyphBufferData::Decompress(glyphBufferData, newBuffer);
+            if(glyphBufferData.isBufferOwned)
+            {
+              // Release previous buffer
+              free(glyphBufferData.buffer);
+            }
+            glyphBufferData.isBufferOwned = true;
+            glyphBufferData.buffer        = newBuffer;
+            glyphBufferData.compressType  = TextAbstraction::FontClient::GlyphBufferData::CompressType::NO_COMPRESS;
+          }
+        }
+
         // Create the pixel data.
         bitmap = PixelData::New(glyphBufferData.buffer,
         // Create the pixel data.
         bitmap = PixelData::New(glyphBufferData.buffer,
-                                glyphBufferData.width * glyphBufferData.height * GetBytesPerPixel(glyphBufferData.format),
+                                glyphBufferSize,
                                 glyphBufferData.width,
                                 glyphBufferData.height,
                                 glyphBufferData.format,
                                 PixelData::FREE);
 
                                 glyphBufferData.width,
                                 glyphBufferData.height,
                                 glyphBufferData.format,
                                 PixelData::FREE);
 
+        // Change buffer ownership.
+        glyphBufferData.isBufferOwned = false;
+
         if(bitmap)
         {
           // Ensure that the next image will fit into the current block size
         if(bitmap)
         {
           // Ensure that the next image will fit into the current block size
index da397ac..cad5ea3 100644 (file)
@@ -50,7 +50,7 @@ const float ONE_AND_A_HALF(1.5f);
  * @param y The value between [0..255]
  * @return (x*y)/255
  */
  * @param y The value between [0..255]
  * @return (x*y)/255
  */
-inline uint8_t MultiplyAndNormalizeColor(const uint8_t& x, const uint8_t& y) noexcept
+inline uint8_t MultiplyAndNormalizeColor(const uint8_t x, const uint8_t y) noexcept
 {
   const uint32_t xy = static_cast<const uint32_t>(x) * y;
   return ((xy << 15) + (xy << 7) + xy) >> 23;
 {
   const uint32_t xy = static_cast<const uint32_t>(x) * y;
   return ((xy << 15) + (xy << 7) + xy) >> 23;
@@ -79,11 +79,11 @@ struct GlyphData
  * @param[in] style The style of the text.
  * @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] style The style of the text.
  * @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).
  */
-void TypesetGlyph(GlyphData&           data,
-                  const Vector2* const position,
-                  const Vector4* const color,
-                  Typesetter::Style    style,
-                  Pixel::Format        pixelFormat)
+void TypesetGlyph(GlyphData& __restrict__ data,
+                  const Vector2* const __restrict__ position,
+                  const Vector4* const __restrict__ color,
+                  const Typesetter::Style style,
+                  const Pixel::Format     pixelFormat)
 {
   if((0u == data.glyphBitmap.width) || (0u == data.glyphBitmap.height))
   {
 {
   if((0u == data.glyphBitmap.width) || (0u == data.glyphBitmap.height))
   {
@@ -114,7 +114,7 @@ void TypesetGlyph(GlyphData&           data,
 
   if(Pixel::RGBA8888 == pixelFormat)
   {
 
   if(Pixel::RGBA8888 == pixelFormat)
   {
-    uint32_t* bitmapBuffer = reinterpret_cast<uint32_t*>(data.bitmapBuffer.GetBuffer());
+    uint32_t* __restrict__ bitmapBuffer = reinterpret_cast<uint32_t*>(data.bitmapBuffer.GetBuffer());
     // Skip basic line.
     bitmapBuffer += (lineIndexRangeMin + yOffset) * static_cast<int32_t>(data.width);
 
     // Skip basic line.
     bitmapBuffer += (lineIndexRangeMin + yOffset) * static_cast<int32_t>(data.width);
 
@@ -133,12 +133,16 @@ void TypesetGlyph(GlyphData&           data,
 
     const bool swapChannelsBR = Pixel::BGRA8888 == data.glyphBitmap.format;
 
 
     const bool swapChannelsBR = Pixel::BGRA8888 == data.glyphBitmap.format;
 
-    // Pointer to the color glyph if there is one.
-    const uint8_t* glyphBuffer = data.glyphBitmap.buffer;
+    // Offset byte value of glyph bitmap.
+    uint32_t glyphOffet = 0u;
+
+    // Allocate scanline memory for glyph bitmap if we need.
+    const bool useLocalScanline         = data.glyphBitmap.compressType != TextAbstraction::FontClient::GlyphBufferData::CompressType::NO_COMPRESS;
+    uint8_t* __restrict__ glyphScanline = useLocalScanline ? (uint8_t*)malloc(data.glyphBitmap.width * glyphPixelSize) : data.glyphBitmap.buffer;
 
     // Precalculate input color's packed result.
 
     // Precalculate input color's packed result.
-    uint32_t packedInputColor       = 0u;
-    uint8_t* packedInputColorBuffer = reinterpret_cast<uint8_t*>(&packedInputColor);
+    uint32_t packedInputColor                    = 0u;
+    uint8_t* __restrict__ packedInputColorBuffer = reinterpret_cast<uint8_t*>(&packedInputColor);
 
     *(packedInputColorBuffer + 3u) = static_cast<uint8_t>(color->a * 255);
     *(packedInputColorBuffer + 2u) = static_cast<uint8_t>(color->b * 255);
 
     *(packedInputColorBuffer + 3u) = static_cast<uint8_t>(color->a * 255);
     *(packedInputColorBuffer + 2u) = static_cast<uint8_t>(color->b * 255);
@@ -146,20 +150,35 @@ void TypesetGlyph(GlyphData&           data,
     *(packedInputColorBuffer)      = static_cast<uint8_t>(color->r * 255);
 
     // Skip basic line of glyph.
     *(packedInputColorBuffer)      = static_cast<uint8_t>(color->r * 255);
 
     // Skip basic line of glyph.
-    glyphBuffer += (lineIndexRangeMin) * static_cast<int32_t>(data.glyphBitmap.width) * glyphPixelSize;
+    if(useLocalScanline)
+    {
+      for(int32_t lineIndex = 0; lineIndex < lineIndexRangeMin; ++lineIndex)
+      {
+        TextAbstraction::FontClient::GlyphBufferData::DecompressScanline(data.glyphBitmap, glyphScanline, glyphOffet);
+      }
+    }
+    else
+    {
+      glyphScanline += lineIndexRangeMin * static_cast<int32_t>(data.glyphBitmap.width * glyphPixelSize);
+    }
 
     // Traverse the pixels of the glyph line per line.
     if(isColorGlyph)
     {
       for(int32_t lineIndex = lineIndexRangeMin; lineIndex < lineIndexRangeMax; ++lineIndex)
       {
 
     // Traverse the pixels of the glyph line per line.
     if(isColorGlyph)
     {
       for(int32_t lineIndex = lineIndexRangeMin; lineIndex < lineIndexRangeMax; ++lineIndex)
       {
+        if(useLocalScanline)
+        {
+          TextAbstraction::FontClient::GlyphBufferData::DecompressScanline(data.glyphBitmap, glyphScanline, glyphOffet);
+        }
+
         for(int32_t index = indexRangeMin; index < indexRangeMax; ++index)
         {
           const int32_t xOffsetIndex = xOffset + index;
 
           // Retrieves the color from the color glyph.
         for(int32_t index = indexRangeMin; index < indexRangeMax; ++index)
         {
           const int32_t xOffsetIndex = xOffset + index;
 
           // Retrieves the color from the color glyph.
-          uint32_t packedColorGlyph       = *(reinterpret_cast<const uint32_t*>(glyphBuffer + (index << 2)));
-          uint8_t* packedColorGlyphBuffer = reinterpret_cast<uint8_t*>(&packedColorGlyph);
+          uint32_t packedColorGlyph                    = *(reinterpret_cast<const uint32_t*>(glyphScanline + (index << 2)));
+          uint8_t* __restrict__ packedColorGlyphBuffer = reinterpret_cast<uint8_t*>(&packedColorGlyph);
 
           // Update the alpha channel.
           const uint8_t colorAlpha       = MultiplyAndNormalizeColor(*(packedInputColorBuffer + 3u), *(packedColorGlyphBuffer + 3u));
 
           // Update the alpha channel.
           const uint8_t colorAlpha       = MultiplyAndNormalizeColor(*(packedInputColorBuffer + 3u), *(packedColorGlyphBuffer + 3u));
@@ -194,18 +213,27 @@ void TypesetGlyph(GlyphData&           data,
           // Set the color into the final pixel buffer.
           *(bitmapBuffer + xOffsetIndex) = packedColorGlyph;
         }
           // Set the color into the final pixel buffer.
           *(bitmapBuffer + xOffsetIndex) = packedColorGlyph;
         }
+
         bitmapBuffer += data.width;
         bitmapBuffer += data.width;
-        glyphBuffer += data.glyphBitmap.width * glyphPixelSize;
+        if(!useLocalScanline)
+        {
+          glyphScanline += data.glyphBitmap.width * glyphPixelSize;
+        }
       }
     }
     else
     {
       for(int32_t lineIndex = lineIndexRangeMin; lineIndex < lineIndexRangeMax; ++lineIndex)
       {
       }
     }
     else
     {
       for(int32_t lineIndex = lineIndexRangeMin; lineIndex < lineIndexRangeMax; ++lineIndex)
       {
+        if(useLocalScanline)
+        {
+          TextAbstraction::FontClient::GlyphBufferData::DecompressScanline(data.glyphBitmap, glyphScanline, glyphOffet);
+        }
+
         for(int32_t index = indexRangeMin; index < indexRangeMax; ++index)
         {
           // Update the alpha channel.
         for(int32_t index = indexRangeMin; index < indexRangeMax; ++index)
         {
           // Update the alpha channel.
-          const uint8_t alpha = *(glyphBuffer + index * glyphPixelSize + glyphAlphaIndex);
+          const uint8_t alpha = *(glyphScanline + index * glyphPixelSize + glyphAlphaIndex);
 
           // Copy non-transparent pixels only
           if(alpha > 0u)
 
           // Copy non-transparent pixels only
           if(alpha > 0u)
@@ -231,8 +259,8 @@ void TypesetGlyph(GlyphData&           data,
             {
               // Pack the given color into a 32bit buffer. The alpha channel will be updated later for each pixel.
               // The format is RGBA8888.
             {
               // Pack the given color into a 32bit buffer. The alpha channel will be updated later for each pixel.
               // The format is RGBA8888.
-              uint32_t packedColor       = 0u;
-              uint8_t* packedColorBuffer = reinterpret_cast<uint8_t*>(&packedColor);
+              uint32_t packedColor                    = 0u;
+              uint8_t* __restrict__ packedColorBuffer = reinterpret_cast<uint8_t*>(&packedColor);
 
               // Color is pre-muliplied with its alpha.
               *(packedColorBuffer + 3u) = MultiplyAndNormalizeColor(*(packedInputColorBuffer + 3u), currentAlpha);
 
               // Color is pre-muliplied with its alpha.
               *(packedColorBuffer + 3u) = MultiplyAndNormalizeColor(*(packedInputColorBuffer + 3u), currentAlpha);
@@ -245,32 +273,64 @@ void TypesetGlyph(GlyphData&           data,
             }
           }
         }
             }
           }
         }
+
         bitmapBuffer += data.width;
         bitmapBuffer += data.width;
-        glyphBuffer += data.glyphBitmap.width * glyphPixelSize;
+        if(!useLocalScanline)
+        {
+          glyphScanline += data.glyphBitmap.width * glyphPixelSize;
+        }
       }
     }
       }
     }
+
+    if(useLocalScanline)
+    {
+      free(glyphScanline);
+    }
   }
   else // Pixel::L8
   {
     // Below codes required only if not color glyph.
     if(!isColorGlyph)
     {
   }
   else // Pixel::L8
   {
     // Below codes required only if not color glyph.
     if(!isColorGlyph)
     {
-      uint8_t*       bitmapBuffer = data.bitmapBuffer.GetBuffer();
-      const uint8_t* glyphBuffer  = data.glyphBitmap.buffer;
+      uint8_t* __restrict__ bitmapBuffer = data.bitmapBuffer.GetBuffer();
+
+      // Offset byte value of glyph bitmap.
+      uint32_t glyphOffet = 0u;
+
+      // Allocate scanline memory for glyph bitmap if we need.
+      const bool useLocalScanline         = data.glyphBitmap.compressType != TextAbstraction::FontClient::GlyphBufferData::CompressType::NO_COMPRESS;
+      uint8_t* __restrict__ glyphScanline = useLocalScanline ? (uint8_t*)malloc(data.glyphBitmap.width * glyphPixelSize) : data.glyphBitmap.buffer;
 
       // Skip basic line.
       bitmapBuffer += (lineIndexRangeMin + yOffset) * static_cast<int32_t>(data.width);
 
       // Skip basic line.
       bitmapBuffer += (lineIndexRangeMin + yOffset) * static_cast<int32_t>(data.width);
-      glyphBuffer += (lineIndexRangeMin) * static_cast<int32_t>(data.glyphBitmap.width) * glyphPixelSize;
+
+      // Skip basic line of glyph.
+      if(useLocalScanline)
+      {
+        for(int32_t lineIndex = 0; lineIndex < lineIndexRangeMin; ++lineIndex)
+        {
+          TextAbstraction::FontClient::GlyphBufferData::DecompressScanline(data.glyphBitmap, glyphScanline, glyphOffet);
+        }
+      }
+      else
+      {
+        glyphScanline += lineIndexRangeMin * static_cast<int32_t>(data.glyphBitmap.width * glyphPixelSize);
+      }
 
       // Traverse the pixels of the glyph line per line.
       for(int32_t lineIndex = lineIndexRangeMin; lineIndex < lineIndexRangeMax; ++lineIndex)
       {
 
       // Traverse the pixels of the glyph line per line.
       for(int32_t lineIndex = lineIndexRangeMin; lineIndex < lineIndexRangeMax; ++lineIndex)
       {
+        if(useLocalScanline)
+        {
+          TextAbstraction::FontClient::GlyphBufferData::DecompressScanline(data.glyphBitmap, glyphScanline, glyphOffet);
+        }
+
         for(int32_t index = indexRangeMin; index < indexRangeMax; ++index)
         {
           const int32_t xOffsetIndex = xOffset + index;
 
           // Update the alpha channel.
         for(int32_t index = indexRangeMin; index < indexRangeMax; ++index)
         {
           const int32_t xOffsetIndex = xOffset + index;
 
           // Update the alpha channel.
-          const uint8_t alpha = *(glyphBuffer + index * glyphPixelSize + glyphAlphaIndex);
+          const uint8_t alpha = *(glyphScanline + index * glyphPixelSize + glyphAlphaIndex);
 
           // Copy non-transparent pixels only
           if(alpha > 0u)
 
           // Copy non-transparent pixels only
           if(alpha > 0u)
@@ -287,7 +347,15 @@ void TypesetGlyph(GlyphData&           data,
         }
 
         bitmapBuffer += data.width;
         }
 
         bitmapBuffer += data.width;
-        glyphBuffer += data.glyphBitmap.width * glyphPixelSize;
+        if(!useLocalScanline)
+        {
+          glyphScanline += data.glyphBitmap.width * glyphPixelSize;
+        }
+      }
+
+      if(useLocalScanline)
+      {
+        free(glyphScanline);
       }
     }
   }
       }
     }
   }
@@ -295,14 +363,14 @@ void TypesetGlyph(GlyphData&           data,
 
 /// Draws the specified underline color to the buffer
 void DrawUnderline(
 
 /// Draws the specified underline color to the buffer
 void DrawUnderline(
-  const uint32_t&                 bufferWidth,
-  const uint32_t&                 bufferHeight,
+  const uint32_t                  bufferWidth,
+  const uint32_t                  bufferHeight,
   GlyphData&                      glyphData,
   GlyphData&                      glyphData,
-  const float&                    baseline,
-  const float&                    currentUnderlinePosition,
-  const float&                    maxUnderlineHeight,
-  const float&                    lineExtentLeft,
-  const float&                    lineExtentRight,
+  const float                     baseline,
+  const float                     currentUnderlinePosition,
+  const float                     maxUnderlineHeight,
+  const float                     lineExtentLeft,
+  const float                     lineExtentRight,
   const UnderlineStyleProperties& commonUnderlineProperties,
   const UnderlineStyleProperties& currentUnderlineProperties,
   const LineRun&                  line)
   const UnderlineStyleProperties& commonUnderlineProperties,
   const UnderlineStyleProperties& currentUnderlineProperties,
   const LineRun&                  line)
@@ -431,14 +499,14 @@ void DrawUnderline(
 
 /// Draws the background color to the buffer
 void DrawBackgroundColor(
 
 /// Draws the background color to the buffer
 void DrawBackgroundColor(
-  Vector4         backgroundColor,
-  const uint32_t& bufferWidth,
-  const uint32_t& bufferHeight,
-  GlyphData&      glyphData,
-  const float&    baseline,
-  const LineRun&  line,
-  const float&    lineExtentLeft,
-  const float&    lineExtentRight)
+  Vector4        backgroundColor,
+  const uint32_t bufferWidth,
+  const uint32_t bufferHeight,
+  GlyphData&     glyphData,
+  const float    baseline,
+  const LineRun& line,
+  const float    lineExtentLeft,
+  const float    lineExtentRight)
 {
   const int32_t yRangeMin = std::max(0, static_cast<int32_t>(glyphData.verticalOffset + baseline - line.ascender));
   const int32_t yRangeMax = std::min(static_cast<int32_t>(bufferHeight), static_cast<int32_t>(glyphData.verticalOffset + baseline - line.descender));
 {
   const int32_t yRangeMin = std::max(0, static_cast<int32_t>(glyphData.verticalOffset + baseline - line.ascender));
   const int32_t yRangeMax = std::min(static_cast<int32_t>(bufferHeight), static_cast<int32_t>(glyphData.verticalOffset + baseline - line.descender));
@@ -491,7 +559,7 @@ void DrawBackgroundColor(
   }
 }
 
   }
 }
 
-Devel::PixelBuffer DrawGlyphsBackground(const ViewModel* model, Devel::PixelBuffer& buffer, const uint32_t& bufferWidth, const uint32_t& bufferHeight, bool ignoreHorizontalAlignment, int32_t horizontalOffset, int32_t verticalOffset)
+Devel::PixelBuffer DrawGlyphsBackground(const ViewModel* model, Devel::PixelBuffer& buffer, const uint32_t bufferWidth, const uint32_t bufferHeight, const bool ignoreHorizontalAlignment, const int32_t horizontalOffset, const int32_t verticalOffset)
 {
   // Retrieve lines, glyphs, positions and colors from the view model.
   const Length            modelNumberOfLines           = model->GetNumberOfLines();
 {
   // Retrieve lines, glyphs, positions and colors from the view model.
   const Length            modelNumberOfLines           = model->GetNumberOfLines();
@@ -598,14 +666,14 @@ Devel::PixelBuffer DrawGlyphsBackground(const ViewModel* model, Devel::PixelBuff
 }
 
 /// Draws the specified strikethrough color to the buffer
 }
 
 /// Draws the specified strikethrough color to the buffer
-void DrawStrikethrough(const uint32_t&                     bufferWidth,
-                       const uint32_t&                     bufferHeight,
+void DrawStrikethrough(const uint32_t                      bufferWidth,
+                       const uint32_t                      bufferHeight,
                        GlyphData&                          glyphData,
                        GlyphData&                          glyphData,
-                       const float&                        baseline,
-                       const float&                        strikethroughStartingYPosition,
-                       const float&                        maxStrikethroughHeight,
-                       const float&                        lineExtentLeft,
-                       const float&                        lineExtentRight,
+                       const float                         baseline,
+                       const float                         strikethroughStartingYPosition,
+                       const float                         maxStrikethroughHeight,
+                       const float                         lineExtentLeft,
+                       const float                         lineExtentRight,
                        const StrikethroughStyleProperties& commonStrikethroughProperties,
                        const StrikethroughStyleProperties& currentStrikethroughProperties,
                        const LineRun&                      line)
                        const StrikethroughStyleProperties& commonStrikethroughProperties,
                        const StrikethroughStyleProperties& currentStrikethroughProperties,
                        const LineRun&                      line)
@@ -674,7 +742,7 @@ void DrawStrikethrough(const uint32_t&                     bufferWidth,
  *
  * @return An image buffer.
  */
  *
  * @return An image buffer.
  */
-inline Devel::PixelBuffer CreateTransparentImageBuffer(const uint32_t& bufferWidth, const uint32_t& bufferHeight, const Pixel::Format& pixelFormat)
+inline Devel::PixelBuffer CreateTransparentImageBuffer(const uint32_t bufferWidth, const uint32_t bufferHeight, const Pixel::Format pixelFormat)
 {
   Devel::PixelBuffer imageBuffer = Devel::PixelBuffer::New(bufferWidth, bufferHeight, pixelFormat);
 
 {
   Devel::PixelBuffer imageBuffer = Devel::PixelBuffer::New(bufferWidth, bufferHeight, pixelFormat);
 
@@ -712,7 +780,7 @@ inline Devel::PixelBuffer CreateTransparentImageBuffer(const uint32_t& bufferWid
  * False if we store the combined image buffer result into bottomPixelBuffer.
  *
  */
  * False if we store the combined image buffer result into bottomPixelBuffer.
  *
  */
-void CombineImageBuffer(Devel::PixelBuffer& topPixelBuffer, Devel::PixelBuffer& bottomPixelBuffer, const uint32_t& bufferWidth, const uint32_t& bufferHeight, bool storeResultIntoTop)
+void CombineImageBuffer(Devel::PixelBuffer& __restrict__ topPixelBuffer, Devel::PixelBuffer& __restrict__ bottomPixelBuffer, const uint32_t bufferWidth, const uint32_t bufferHeight, bool storeResultIntoTop)
 {
   // Assume that we always combine two RGBA images
   // Jump with 4bytes for optimize runtime.
 {
   // Assume that we always combine two RGBA images
   // Jump with 4bytes for optimize runtime.
@@ -749,8 +817,8 @@ void CombineImageBuffer(Devel::PixelBuffer& topPixelBuffer, Devel::PixelBuffer&
 
   const uint32_t bufferSizeInt = bufferWidth * bufferHeight;
 
 
   const uint32_t bufferSizeInt = bufferWidth * bufferHeight;
 
-  uint32_t* combinedBuffer        = storeResultIntoTop ? topBuffer : bottomBuffer;
-  uint8_t*  topAlphaBufferPointer = reinterpret_cast<uint8_t*>(topBuffer) + 3;
+  uint32_t* __restrict__ combinedBuffer       = storeResultIntoTop ? topBuffer : bottomBuffer;
+  uint8_t* __restrict__ topAlphaBufferPointer = reinterpret_cast<uint8_t*>(topBuffer) + 3;
 
   for(uint32_t pixelIndex = 0; pixelIndex < bufferSizeInt; ++pixelIndex)
   {
 
   for(uint32_t pixelIndex = 0; pixelIndex < bufferSizeInt; ++pixelIndex)
   {
@@ -780,8 +848,8 @@ void CombineImageBuffer(Devel::PixelBuffer& topPixelBuffer, Devel::PixelBuffer&
     {
       // At least one pixel is not fully opaque
       // "Over" blend the the pixel from topBuffer with the pixel in bottomBuffer
     {
       // At least one pixel is not fully opaque
       // "Over" blend the the pixel from topBuffer with the pixel in bottomBuffer
-      uint32_t blendedBottomBufferColor       = *(bottomBuffer);
-      uint8_t* blendedBottomBufferColorBuffer = reinterpret_cast<uint8_t*>(&blendedBottomBufferColor);
+      uint32_t blendedBottomBufferColor                    = *(bottomBuffer);
+      uint8_t* __restrict__ blendedBottomBufferColorBuffer = reinterpret_cast<uint8_t*>(&blendedBottomBufferColor);
 
       blendedBottomBufferColorBuffer[0] = MultiplyAndNormalizeColor(blendedBottomBufferColorBuffer[0], 255 - topAlpha);
       blendedBottomBufferColorBuffer[1] = MultiplyAndNormalizeColor(blendedBottomBufferColorBuffer[1], 255 - topAlpha);
 
       blendedBottomBufferColorBuffer[0] = MultiplyAndNormalizeColor(blendedBottomBufferColorBuffer[0], 255 - topAlpha);
       blendedBottomBufferColorBuffer[1] = MultiplyAndNormalizeColor(blendedBottomBufferColorBuffer[1], 255 - topAlpha);
@@ -994,18 +1062,18 @@ PixelData Typesetter::Render(const Vector2& size, Toolkit::DevelText::TextDirect
   return pixelData;
 }
 
   return pixelData;
 }
 
-Devel::PixelBuffer Typesetter::CreateImageBuffer(const uint32_t& bufferWidth, const uint32_t& bufferHeight, Typesetter::Style style, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat, const int32_t& horizontalOffset, const int32_t& verticalOffset, GlyphIndex fromGlyphIndex, GlyphIndex toGlyphIndex)
+Devel::PixelBuffer Typesetter::CreateImageBuffer(const uint32_t bufferWidth, const uint32_t bufferHeight, const Typesetter::Style style, const bool ignoreHorizontalAlignment, const Pixel::Format pixelFormat, const int32_t horizontalOffset, const int32_t verticalOffset, const GlyphIndex fromGlyphIndex, const GlyphIndex toGlyphIndex)
 {
   // Retrieve lines, glyphs, positions and colors from the view model.
 {
   // Retrieve lines, glyphs, positions and colors from the view model.
-  const Length            modelNumberOfLines = mModel->GetNumberOfLines();
-  const LineRun* const    modelLinesBuffer   = mModel->GetLines();
-  const GlyphInfo* const  glyphsBuffer       = mModel->GetGlyphs();
-  const Vector2* const    positionBuffer     = mModel->GetLayout();
-  const Vector4* const    colorsBuffer       = mModel->GetColors();
-  const ColorIndex* const colorIndexBuffer   = mModel->GetColorIndices();
-  const GlyphInfo*        hyphens            = mModel->GetHyphens();
-  const Length*           hyphenIndices      = mModel->GetHyphenIndices();
-  const Length            hyphensCount       = mModel->GetHyphensCount();
+  const Length modelNumberOfLines                       = mModel->GetNumberOfLines();
+  const LineRun* const __restrict__ modelLinesBuffer    = mModel->GetLines();
+  const GlyphInfo* const __restrict__ glyphsBuffer      = mModel->GetGlyphs();
+  const Vector2* const __restrict__ positionBuffer      = mModel->GetLayout();
+  const Vector4* const __restrict__ colorsBuffer        = mModel->GetColors();
+  const ColorIndex* const __restrict__ colorIndexBuffer = mModel->GetColorIndices();
+  const GlyphInfo* __restrict__ hyphens                 = mModel->GetHyphens();
+  const Length* __restrict__ hyphenIndices              = mModel->GetHyphenIndices();
+  const Length hyphensCount                             = mModel->GetHyphensCount();
 
   // Elided text info. Indices according to elided text and Ellipsis position.
   const auto startIndexOfGlyphs              = mModel->GetStartIndexOfElidedGlyphs();
 
   // Elided text info. Indices according to elided text and Ellipsis position.
   const auto startIndexOfGlyphs              = mModel->GetStartIndexOfElidedGlyphs();
@@ -1030,10 +1098,10 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const uint32_t& bufferWidth, co
   TextAbstraction::FontClient fontClient  = TextAbstraction::FontClient::Get();
   Length                      hyphenIndex = 0;
 
   TextAbstraction::FontClient fontClient  = TextAbstraction::FontClient::Get();
   Length                      hyphenIndex = 0;
 
-  const Character*              textBuffer                = mModel->GetTextBuffer();
-  float                         calculatedAdvance         = 0.f;
-  const Vector<CharacterIndex>& glyphToCharacterMap       = mModel->GetGlyphsToCharacters();
-  const CharacterIndex*         glyphToCharacterMapBuffer = glyphToCharacterMap.Begin();
+  const Character* __restrict__ textBuffer                       = mModel->GetTextBuffer();
+  float calculatedAdvance                                        = 0.f;
+  const Vector<CharacterIndex>& __restrict__ glyphToCharacterMap = mModel->GetGlyphsToCharacters();
+  const CharacterIndex* __restrict__ glyphToCharacterMapBuffer   = glyphToCharacterMap.Begin();
 
   const DevelText::VerticalLineAlignment::Type verLineAlign = mModel->GetVerticalLineAlignment();
 
 
   const DevelText::VerticalLineAlignment::Type verLineAlign = mModel->GetVerticalLineAlignment();
 
@@ -1078,7 +1146,7 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const uint32_t& bufferWidth, co
     const float modelCharacterSpacing = mModel->GetCharacterSpacing();
 
     // Get the character-spacing runs.
     const float modelCharacterSpacing = mModel->GetCharacterSpacing();
 
     // Get the character-spacing runs.
-    const Vector<CharacterSpacingGlyphRun>& characterSpacingGlyphRuns = mModel->GetCharacterSpacingGlyphRuns();
+    const Vector<CharacterSpacingGlyphRun>& __restrict__ characterSpacingGlyphRuns = mModel->GetCharacterSpacingGlyphRuns();
 
     // Aggregate underline-style-properties from mModel
     const UnderlineStyleProperties modelUnderlineProperties{mModel->GetUnderlineType(),
 
     // Aggregate underline-style-properties from mModel
     const UnderlineStyleProperties modelUnderlineProperties{mModel->GetUnderlineType(),
@@ -1307,8 +1375,12 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const uint32_t& bufferWidth, co
           glyphData.verticalOffset += glyphData.glyphBitmap.outlineOffsetY;
         }
 
           glyphData.verticalOffset += glyphData.glyphBitmap.outlineOffsetY;
         }
 
-        // free the glyphBitmap.buffer as it is now copied into glyphData.bitmapBuffer
-        free(glyphData.glyphBitmap.buffer);
+        // free the glyphBitmap.buffer if it is owner of buffer
+        if(glyphData.glyphBitmap.isBufferOwned)
+        {
+          free(glyphData.glyphBitmap.buffer);
+          glyphData.glyphBitmap.isBufferOwned = false;
+        }
         glyphData.glyphBitmap.buffer = NULL;
       }
 
         glyphData.glyphBitmap.buffer = NULL;
       }
 
@@ -1354,7 +1426,7 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const uint32_t& bufferWidth, co
   return glyphData.bitmapBuffer;
 }
 
   return glyphData.bitmapBuffer;
 }
 
-Devel::PixelBuffer Typesetter::ApplyUnderlineMarkupImageBuffer(Devel::PixelBuffer topPixelBuffer, const uint32_t& bufferWidth, const uint32_t& bufferHeight, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat, const int32_t& horizontalOffset, const int32_t& verticalOffset)
+Devel::PixelBuffer Typesetter::ApplyUnderlineMarkupImageBuffer(Devel::PixelBuffer topPixelBuffer, const uint32_t bufferWidth, const uint32_t bufferHeight, const bool ignoreHorizontalAlignment, const Pixel::Format pixelFormat, const int32_t horizontalOffset, const int32_t verticalOffset)
 {
   // Underline-tags (this is for Markup case)
   // Get the underline runs.
 {
   // Underline-tags (this is for Markup case)
   // Get the underline runs.
@@ -1386,7 +1458,7 @@ Devel::PixelBuffer Typesetter::ApplyUnderlineMarkupImageBuffer(Devel::PixelBuffe
   return topPixelBuffer;
 }
 
   return topPixelBuffer;
 }
 
-Devel::PixelBuffer Typesetter::ApplyStrikethroughMarkupImageBuffer(Devel::PixelBuffer topPixelBuffer, const uint32_t& bufferWidth, const uint32_t& bufferHeight, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat, const int32_t& horizontalOffset, const int32_t& verticalOffset)
+Devel::PixelBuffer Typesetter::ApplyStrikethroughMarkupImageBuffer(Devel::PixelBuffer topPixelBuffer, const uint32_t bufferWidth, const uint32_t bufferHeight, const bool ignoreHorizontalAlignment, const Pixel::Format pixelFormat, const int32_t horizontalOffset, const int32_t verticalOffset)
 {
   // strikethrough-tags (this is for Markup case)
   // Get the strikethrough runs.
 {
   // strikethrough-tags (this is for Markup case)
   // Get the strikethrough runs.
@@ -1418,7 +1490,7 @@ Devel::PixelBuffer Typesetter::ApplyStrikethroughMarkupImageBuffer(Devel::PixelB
   return topPixelBuffer;
 }
 
   return topPixelBuffer;
 }
 
-Devel::PixelBuffer Typesetter::ApplyMarkupProcessorOnPixelBuffer(Devel::PixelBuffer topPixelBuffer, const uint32_t& bufferWidth, const uint32_t& bufferHeight, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat, const int32_t& horizontalOffset, const int32_t& verticalOffset)
+Devel::PixelBuffer Typesetter::ApplyMarkupProcessorOnPixelBuffer(Devel::PixelBuffer topPixelBuffer, const uint32_t bufferWidth, const uint32_t bufferHeight, const bool ignoreHorizontalAlignment, const Pixel::Format pixelFormat, const int32_t horizontalOffset, const int32_t verticalOffset)
 {
   // Apply the markup-Processor if enabled
   const bool markupProcessorEnabled = mModel->IsMarkupProcessorEnabled();
 {
   // Apply the markup-Processor if enabled
   const bool markupProcessorEnabled = mModel->IsMarkupProcessorEnabled();
index 3f9dd66..3a71c31 100644 (file)
@@ -144,7 +144,7 @@ private:
    *
    * @return An image buffer with the text.
    */
    *
    * @return An image buffer with the text.
    */
-  Devel::PixelBuffer CreateImageBuffer(const uint32_t& bufferWidth, const uint32_t& bufferHeight, Typesetter::Style style, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat, const int32_t& horizontalOffset, const int32_t& verticalOffset, TextAbstraction::GlyphIndex fromGlyphIndex, TextAbstraction::GlyphIndex toGlyphIndex);
+  Devel::PixelBuffer CreateImageBuffer(const uint32_t bufferWidth, const uint32_t bufferHeight, const Typesetter::Style style, const bool ignoreHorizontalAlignment, const Pixel::Format pixelFormat, const int32_t horizontalOffset, const int32_t verticalOffset, const TextAbstraction::GlyphIndex fromGlyphIndex, const TextAbstraction::GlyphIndex toGlyphIndex);
 
   /**
    * @brief Apply behaviour of tags if the markup-processor is enabled.
 
   /**
    * @brief Apply behaviour of tags if the markup-processor is enabled.
@@ -159,7 +159,7 @@ private:
    *
    * @return The image buffer with the markup.
    */
    *
    * @return The image buffer with the markup.
    */
-  Devel::PixelBuffer ApplyMarkupProcessorOnPixelBuffer(Devel::PixelBuffer topPixelBuffer, const uint32_t& bufferWidth, const uint32_t& bufferHeight, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat, const int32_t& horizontalOffset, const int32_t& verticalOffset);
+  Devel::PixelBuffer ApplyMarkupProcessorOnPixelBuffer(Devel::PixelBuffer topPixelBuffer, const uint32_t bufferWidth, const uint32_t bufferHeight, const bool ignoreHorizontalAlignment, const Pixel::Format pixelFormat, const int32_t horizontalOffset, const int32_t verticalOffset);
 
   /**
    * @brief Apply markup underline tags.
 
   /**
    * @brief Apply markup underline tags.
@@ -180,7 +180,7 @@ private:
    *
    * @return The image buffer with the markup.
    */
    *
    * @return The image buffer with the markup.
    */
-  Devel::PixelBuffer ApplyUnderlineMarkupImageBuffer(Devel::PixelBuffer topPixelBuffer, const uint32_t& bufferWidth, const uint32_t& bufferHeight, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat, const int32_t& horizontalOffset, const int32_t& verticalOffset);
+  Devel::PixelBuffer ApplyUnderlineMarkupImageBuffer(Devel::PixelBuffer topPixelBuffer, const uint32_t bufferWidth, const uint32_t bufferHeight, const bool ignoreHorizontalAlignment, const Pixel::Format pixelFormat, const int32_t horizontalOffset, const int32_t verticalOffset);
 
   /**
    * @brief Apply markup strikethrough tags.
 
   /**
    * @brief Apply markup strikethrough tags.
@@ -201,7 +201,7 @@ private:
    *
    * @return The image buffer with the markup.
    */
    *
    * @return The image buffer with the markup.
    */
-  Devel::PixelBuffer ApplyStrikethroughMarkupImageBuffer(Devel::PixelBuffer topPixelBuffer, const uint32_t& bufferWidth, const uint32_t& bufferHeight, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat, const int32_t& horizontalOffset, const int32_t& verticalOffset);
+  Devel::PixelBuffer ApplyStrikethroughMarkupImageBuffer(Devel::PixelBuffer topPixelBuffer, const uint32_t bufferWidth, const uint32_t bufferHeight, const bool ignoreHorizontalAlignment, const Pixel::Format pixelFormat, const int32_t horizontalOffset, const int32_t verticalOffset);
 
 protected:
   /**
 
 protected:
   /**