Merge "[AT-SPI] Rework intercepting key events" into devel/master
[platform/core/uifw/dali-adaptor.git] / dali / internal / text / text-abstraction / cairo-renderer.cpp
index 4bccb0b..ed70ccb 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.
@@ -92,7 +92,7 @@ struct GlyphBuffer
     DELETE
   };
 
-  GlyphBuffer(Dali::TextAbstraction::FontClient::GlyphBufferData& data, DestructorType type)
+  GlyphBuffer(Dali::TextAbstraction::GlyphBufferData& data, DestructorType type)
   : data(data),
     type(type)
   {
@@ -114,8 +114,8 @@ struct GlyphBuffer
     }
   }
 
-  Dali::TextAbstraction::FontClient::GlyphBufferData& data;
-  DestructorType                                      type;
+  Dali::TextAbstraction::GlyphBufferData& data;
+  DestructorType                          type;
 };
 
 /**
@@ -364,12 +364,12 @@ bool ConvertSizeForCairo(
 void CopyImageToSurface(
   const TextAbstraction::TextRenderer::Parameters& parameters,
   const Pixel::Format                              pixelFormat,
-  TextAbstraction::FontClient::GlyphBufferData&    data,
+  TextAbstraction::GlyphBufferData&                data,
   unsigned char*                                   buffer,
   const int                                        rgbaCase,
   const double                                     glyphX,
   const double                                     glyphY,
-  const int                                        strideWidth,
+  const unsigned int                               strideWidth,
   const Vector4&                                   color,
   const bool                                       doBlendWithTextColor)
 {
@@ -685,9 +685,9 @@ Devel::PixelBuffer RenderTextCairo(const TextAbstraction::TextRenderer::Paramete
 
   // This function provides a stride value that will respect all alignment requirements of the
   // accelerated image-rendering code within cairo.
-  const int stride      = cairo_format_stride_for_width(cairoFormat,
+  const int          stride      = cairo_format_stride_for_width(cairoFormat,
                                                    static_cast<int>(parameters.width));
-  const int strideWidth = stride / bpp;
+  const unsigned int strideWidth = static_cast<unsigned int>(std::abs(stride)) / bpp;
 
   // Convert from DALi glyphs to Cairo glyphs.
   std::vector<cairo_glyph_t> cairoGlyphs;
@@ -736,7 +736,7 @@ Devel::PixelBuffer RenderTextCairo(const TextAbstraction::TextRenderer::Paramete
   Devel::PixelBuffer pixelBuffer = Devel::PixelBuffer::New(strideWidth, parameters.height, pixelFormat);
 
   unsigned char*     buffer     = pixelBuffer.GetBuffer();
-  const unsigned int bufferSize = stride * parameters.height;
+  const unsigned int bufferSize = static_cast<unsigned int>(std::abs(stride)) * parameters.height;
   memset(buffer, 0, bufferSize);
 
   std::unique_ptr<cairo_surface_t, void (*)(cairo_surface_t*)> surfacePtr(cairo_image_surface_create_for_data(buffer,
@@ -853,8 +853,7 @@ Devel::PixelBuffer RenderTextCairo(const TextAbstraction::TextRenderer::Paramete
           const cairo_glyph_t& glyph = *(cairoGlyphsBuffer + index);
 
           // Retrieve the image
-          TextAbstraction::FontClient::GlyphBufferData data;
-          std::unique_ptr<GlyphBuffer>                 glyphBufferPtr(new GlyphBuffer(data, GlyphBuffer::FREE));
+          TextAbstraction::GlyphBufferData data;
           if(isEmoji)
           {
             data.width  = parameters.glyphs[run.glyphIndex].width;
@@ -893,6 +892,28 @@ Devel::PixelBuffer RenderTextCairo(const TextAbstraction::TextRenderer::Paramete
             unsigned int       heightOut = data.height;
             const unsigned int pixelSize = Pixel::GetBytesPerPixel(data.format);
 
+            // If we need to decompress, create new memory and replace ownership.
+            if(data.compressionType != TextAbstraction::GlyphBufferData::CompressionType::NO_COMPRESSION)
+            {
+              uint8_t* newBuffer = (uint8_t*)malloc(widthOut * heightOut * pixelSize);
+              if(DALI_LIKELY(newBuffer != nullptr))
+              {
+                TextAbstraction::GlyphBufferData::Decompress(data, newBuffer);
+                if(data.isBufferOwned)
+                {
+                  // Release previous buffer
+                  free(data.buffer);
+                }
+                data.isBufferOwned   = true;
+                data.buffer          = newBuffer;
+                data.compressionType = TextAbstraction::GlyphBufferData::CompressionType::NO_COMPRESSION;
+              }
+              else
+              {
+                DALI_LOG_ERROR("malloc is failed. request malloc size : %u x %u x %u\n", widthOut, heightOut, pixelSize);
+              }
+            }
+
             Dali::Internal::Platform::RotateByShear(data.buffer,
                                                     data.width,
                                                     data.height,
@@ -904,10 +925,15 @@ Devel::PixelBuffer RenderTextCairo(const TextAbstraction::TextRenderer::Paramete
                                                     heightOut);
             if(nullptr != pixelsOut)
             {
-              free(data.buffer);
-              data.buffer = pixelsOut;
-              data.width  = widthOut;
-              data.height = heightOut;
+              if(data.isBufferOwned)
+              {
+                free(data.buffer);
+              }
+              data.isBufferOwned   = true;
+              data.compressionType = Dali::TextAbstraction::GlyphBufferData::CompressionType::NO_COMPRESSION;
+              data.buffer          = pixelsOut;
+              data.width           = widthOut;
+              data.height          = heightOut;
             }
 
             glyphX = centerX - 0.5 * static_cast<double>(data.width);