Merge "[AT-SPI] Rework intercepting key events" into devel/master
[platform/core/uifw/dali-adaptor.git] / dali / internal / text / text-abstraction / plugin / font-client-utils.cpp
index 9141ca1..a6d56fa 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.
 
 #if defined(DEBUG_ENABLED)
 extern Dali::Integration::Log::Filter* gFontClientLogFilter;
+
+#define FONT_LOG_DESCRIPTION(fontDescription, prefix)                                                                            \
+  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, #prefix "  description; family : [%s]\n", fontDescription.family.c_str()); \
+  DALI_LOG_INFO(gFontClientLogFilter, Debug::Verbose,                                                                            \
+                "                 path : [%s]\n"                                                                                 \
+                "                width : [%s]\n"                                                                                 \
+                "               weight : [%s]\n"                                                                                 \
+                "                slant : [%s]\n\n",                                                                              \
+                fontDescription.path.c_str(),                                                                                    \
+                FontWidth::Name[fontDescription.width],                                                                          \
+                FontWeight::Name[fontDescription.weight],                                                                        \
+                FontSlant::Name[fontDescription.slant])
+
+#define FONT_LOG_REQUEST(charcode, requestedPointSize, preferColor) \
+  DALI_LOG_INFO(gFontClientLogFilter, Debug::General,               \
+                "           character : %p\n"                       \
+                "  requestedPointSize : %d\n"                       \
+                "         preferColor : %s\n",                      \
+                charcode,                                           \
+                requestedPointSize,                                 \
+                (preferColor ? "true" : "false"))
+
+#else
+
+#define FONT_LOG_DESCRIPTION(fontDescription, prefix)
+#define FONT_LOG_REQUEST(charcode, requestedPointSize, preferColor)
+
 #endif
 
 namespace Dali::TextAbstraction::Internal
@@ -104,10 +131,15 @@ const FontSlant::Type IntToSlantType(int slant)
   return static_cast<FontSlant::Type>(ValueToIndex(slant, FONT_SLANT_TYPE_TO_INT, NUM_FONT_SLANT_TYPE - 1u));
 }
 
-const int DEFAULT_FONT_WIDTH(100);
-const int DEFAULT_FONT_WEIGHT(80);
-const int DEFAULT_FONT_SLANT(0);
+const char* DEFAULT_FONT_FAMILY_NAME("Tizen");
+const int   DEFAULT_FONT_WIDTH(100);
+const int   DEFAULT_FONT_WEIGHT(80);
+const int   DEFAULT_FONT_SLANT(0);
 
+const std::string_view DefaultFontFamily()
+{
+  return DEFAULT_FONT_FAMILY_NAME;
+}
 const FontWidth::Type DefaultFontWidth()
 {
   return IntToWidthType(DEFAULT_FONT_WIDTH);
@@ -129,7 +161,7 @@ const FontSlant::Type DefaultFontSlant()
  * @param[in] srcHeight The height of the bitmap.
  * @param[in] srcBuffer The buffer of the bitmap.
  */
-void ConvertBitmap(TextAbstraction::FontClient::GlyphBufferData& data, unsigned int srcWidth, unsigned int srcHeight, const unsigned char* const srcBuffer)
+void ConvertBitmap(TextAbstraction::GlyphBufferData& data, unsigned int srcWidth, unsigned int srcHeight, const unsigned char* const srcBuffer, const Pixel::Format srcFormat)
 {
   // Set the input dimensions.
   const ImageDimensions inputDimensions(srcWidth, srcHeight);
@@ -141,22 +173,38 @@ void ConvertBitmap(TextAbstraction::FontClient::GlyphBufferData& data, unsigned
   data.height = (data.height == 0) ? srcHeight : data.height;
   const ImageDimensions desiredDimensions(data.width, data.height);
 
+  data.format = srcFormat;
+
+  // Note we don't compress here
+  data.compressionType = TextAbstraction::GlyphBufferData::CompressionType::NO_COMPRESSION;
+
+  const uint32_t bytePerPixel = Dali::Pixel::GetBytesPerPixel(srcFormat);
+
   // Creates the output buffer
-  const unsigned int bufferSize = data.width * data.height * 4u;
-  data.buffer                   = (uint8_t*)malloc(bufferSize * sizeof(uint8_t)); // @note The caller is responsible for deallocating the bitmap data using free.
+  const uint32_t bufferSize = data.width * data.height * bytePerPixel;
 
   if(inputDimensions == desiredDimensions)
   {
     // There isn't downscaling.
-    memcpy(data.buffer, srcBuffer, bufferSize);
+    data.isBufferOwned = false;
+    data.buffer        = const_cast<uint8_t*>(srcBuffer);
   }
   else
   {
-    Dali::Internal::Platform::LanczosSample4BPP(srcBuffer,
-                                                inputDimensions,
-                                                srcWidth,
-                                                data.buffer,
-                                                desiredDimensions);
+    data.isBufferOwned = true;
+    data.buffer        = (uint8_t*)malloc(bufferSize); // @note The caller is responsible for deallocating the bitmap data using free.
+
+    if(DALI_UNLIKELY(!data.buffer))
+    {
+      DALI_LOG_ERROR("malloc is failed. request malloc size : %u\n", bufferSize);
+      return;
+    }
+    Dali::Internal::Platform::LanczosSample(srcBuffer,
+                                            inputDimensions,
+                                            srcWidth,
+                                            srcFormat,
+                                            data.buffer,
+                                            desiredDimensions);
   }
 }
 
@@ -169,8 +217,9 @@ void ConvertBitmap(TextAbstraction::FontClient::GlyphBufferData& data, unsigned
  * @param[in] moveBuffer Whether the bitmap buffer move. True if just copy buffer pointer. False if we use memcpy. (Default is false.)
  * @note If you set moveBuffer=true, the bitmap's buffer moved frome srcBitmap to data. So srcBitmap buffer changed as nullptr.
  */
-void ConvertBitmap(TextAbstraction::FontClient::GlyphBufferData& data, FT_Bitmap& srcBitmap, bool isShearRequired, bool moveBuffer)
+void ConvertBitmap(TextAbstraction::GlyphBufferData& data, FT_Bitmap& srcBitmap, bool isShearRequired, bool moveBuffer)
 {
+  data.buffer = nullptr;
   if(srcBitmap.width * srcBitmap.rows > 0)
   {
     switch(srcBitmap.pixel_mode)
@@ -261,19 +310,21 @@ void ConvertBitmap(TextAbstraction::FontClient::GlyphBufferData& data, FT_Bitmap
           data.height = height;
           data.format = Pixel::L8; // Sets the pixel format.
 
+          // Note we don't compress here
+          data.compressionType = TextAbstraction::GlyphBufferData::CompressionType::NO_COMPRESSION;
+
           if(moveBuffer)
           {
-            data.buffer = pixelsIn;
+            data.isBufferOwned = true;
+            data.buffer        = pixelsIn;
 
             // Happy trick for copyless convert bitmap!
             srcBitmap.buffer = nullptr;
           }
           else
           {
-            const unsigned int bufferSize = width * height;
-            data.buffer                   = (uint8_t*)malloc(bufferSize * sizeof(uint8_t)); // @note The caller is responsible for deallocating the bitmap data using free.
-
-            memcpy(data.buffer, pixelsIn, bufferSize);
+            data.isBufferOwned = false;
+            data.buffer        = pixelsIn;
           }
 
           if(releaseRequiredPixelPtr)
@@ -290,10 +341,7 @@ void ConvertBitmap(TextAbstraction::FontClient::GlyphBufferData& data, FT_Bitmap
         if(srcBitmap.pitch == static_cast<int>(srcBitmap.width << 2u))
         {
           // Color glyph doesn't support copyless convert bitmap. Just memcpy
-          ConvertBitmap(data, srcBitmap.width, srcBitmap.rows, srcBitmap.buffer);
-
-          // Sets the pixel format.
-          data.format = Pixel::BGRA8888;
+          ConvertBitmap(data, srcBitmap.width, srcBitmap.rows, srcBitmap.buffer, Pixel::BGRA8888);
         }
         break;
       }
@@ -384,4 +432,67 @@ FcCharSet* CreateCharacterSetFromDescription(const FontDescription& description)
   return characterSet;
 }
 
+bool MatchFontDescriptionToPattern(FcPattern* pattern, Dali::TextAbstraction::FontDescription& fontDescription, FcCharSet** characterSet)
+{
+  DALI_LOG_TRACE_METHOD(gFontClientLogFilter);
+
+  FcResult   result = FcResultMatch;
+  FcPattern* match  = FcFontMatch(nullptr /* use default configure */, pattern, &result); // Creates a new font pattern that needs to be destroyed by calling FcPatternDestroy.
+
+  const bool matched = nullptr != match;
+  DALI_LOG_INFO(gFontClientLogFilter, Debug::General, "  pattern matched : %s\n", (matched ? "true" : "false"));
+
+  if(matched)
+  {
+    int width  = 0;
+    int weight = 0;
+    int slant  = 0;
+    GetFcString(match, FC_FILE, fontDescription.path);
+    GetFcString(match, FC_FAMILY, fontDescription.family);
+    GetFcInt(match, FC_WIDTH, width);
+    GetFcInt(match, FC_WEIGHT, weight);
+    GetFcInt(match, FC_SLANT, slant);
+    fontDescription.width  = IntToWidthType(width);
+    fontDescription.weight = IntToWeightType(weight);
+    fontDescription.slant  = IntToSlantType(slant);
+
+    // Retrieve the character set and increase the reference counter.
+    FcPatternGetCharSet(match, FC_CHARSET, 0u, characterSet);
+    *characterSet = FcCharSetCopy(*characterSet);
+
+    // destroyed the matched pattern
+    FcPatternDestroy(match);
+    FONT_LOG_DESCRIPTION(fontDescription, "");
+  }
+  return matched;
+}
+
+bool GetFcString(const FcPattern* const pattern, const char* const n, std::string& string)
+{
+  FcChar8*       file   = nullptr;
+  const FcResult retVal = FcPatternGetString(pattern, n, 0u, &file);
+
+  if(FcResultMatch == retVal)
+  {
+    // Have to use reinterpret_cast because FcChar8 is unsigned char*, not a const char*.
+    string.assign(reinterpret_cast<const char*>(file));
+
+    return true;
+  }
+
+  return false;
+}
+
+bool GetFcInt(const _FcPattern* const pattern, const char* const n, int& intVal)
+{
+  const FcResult retVal = FcPatternGetInteger(pattern, n, 0u, &intVal);
+
+  if(FcResultMatch == retVal)
+  {
+    return true;
+  }
+
+  return false;
+}
+
 } // namespace Dali::TextAbstraction::Internal