Avoid Svace DEREF_OF_NULL warnings
[platform/core/uifw/dali-adaptor.git] / text / dali / internal / text-abstraction / font-client-plugin-impl.cpp
index 56e297c..970f0ff 100644 (file)
@@ -25,6 +25,7 @@
 #include <dali/integration-api/debug.h>
 #include <dali/integration-api/platform-abstraction.h>
 #include <dali/internal/text-abstraction/font-client-helper.h>
+#include <platform-abstractions/portable/image-operations.h>
 #include <adaptor-impl.h>
 
 // EXTERNAL INCLUDES
@@ -339,11 +340,15 @@ void FontClient::Plugin::GetDefaultPlatformFontDescription( FontDescription& fon
     FcInitReinitialize(); // FcInitBringUptoDate did not seem to reload config file as was still getting old default font.
 
     FcPattern* matchPattern = FcPatternCreate();
-    FcConfigSubstitute(NULL, matchPattern, FcMatchPattern);
-    FcDefaultSubstitute( matchPattern );
 
-    MatchFontDescriptionToPattern( matchPattern, mDefaultFontDescription );
-    FcPatternDestroy( matchPattern );
+    if( matchPattern )
+    {
+      FcConfigSubstitute( NULL, matchPattern, FcMatchPattern );
+      FcDefaultSubstitute( matchPattern );
+
+      MatchFontDescriptionToPattern( matchPattern, mDefaultFontDescription );
+      FcPatternDestroy( matchPattern );
+    }
 
     mDefaultFontDescriptionCached = true;
   }
@@ -461,12 +466,7 @@ FontId FontClient::Plugin::FindFontForCharacter( const FontList& fontList,
 
       if( preferColor )
       {
-        PixelData bitmap = CreateBitmap( fontId, GetGlyphIndex(fontId,charcode) );
-        if( bitmap &&
-            Pixel::BGRA8888 == bitmap.GetPixelFormat() )
-        {
-          foundColor = true;
-        }
+        foundColor = IsColorGlyph( fontId, GetGlyphIndex( fontId, charcode ) );
       }
 
       // Keep going unless we prefer a different (color) font.
@@ -879,21 +879,18 @@ bool FontClient::Plugin::GetVectorMetrics( GlyphInfo* array,
 #endif
 }
 
-PixelData FontClient::Plugin::CreateBitmap( FontId fontId,
-                                              GlyphIndex glyphIndex )
+void FontClient::Plugin::CreateBitmap( FontId fontId, GlyphIndex glyphIndex, Dali::TextAbstraction::FontClient::GlyphBufferData& data )
 {
-  PixelData bitmap;
-
-  if( fontId > 0 &&
-      fontId-1 < mFontCache.size() )
+  if( ( fontId > 0 ) &&
+      ( fontId - 1u < mFontCache.size() ) )
   {
-    FT_Face ftFace = mFontCache[fontId-1].mFreeTypeFace;
+    FT_Face ftFace = mFontCache[fontId - 1u].mFreeTypeFace;
 
     FT_Error error;
 
 #ifdef FREETYPE_BITMAP_SUPPORT
     // Check to see if this is fixed size bitmap
-    if ( mFontCache[fontId-1].mIsFixedSizeBitmap )
+    if ( mFontCache[fontId - 1u].mIsFixedSizeBitmap )
     {
       error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_COLOR );
     }
@@ -916,7 +913,7 @@ PixelData FontClient::Plugin::CreateBitmap( FontId fontId,
           if ( FT_Err_Ok == error )
           {
             FT_BitmapGlyph bitmapGlyph = (FT_BitmapGlyph)glyph;
-            ConvertBitmap( bitmap, bitmapGlyph->bitmap );
+            ConvertBitmap( data, bitmapGlyph->bitmap );
           }
           else
           {
@@ -925,7 +922,7 @@ PixelData FontClient::Plugin::CreateBitmap( FontId fontId,
         }
         else
         {
-          ConvertBitmap( bitmap, ftFace->glyph->bitmap );
+          ConvertBitmap( data, ftFace->glyph->bitmap );
         }
 
         // Created FT_Glyph object must be released with FT_Done_Glyph
@@ -937,8 +934,21 @@ PixelData FontClient::Plugin::CreateBitmap( FontId fontId,
       DALI_LOG_ERROR( "FT_Load_Glyph Failed with error: %d\n", error );
     }
   }
+}
+
+PixelData FontClient::Plugin::CreateBitmap( FontId fontId,
+                                            GlyphIndex glyphIndex )
+{
+  TextAbstraction::FontClient::GlyphBufferData data;
+
+  CreateBitmap( fontId, glyphIndex, data );
 
-  return bitmap;
+  return PixelData::New( data.buffer,
+                         data.width * data.height * Pixel::GetBytesPerPixel( data.format ),
+                         data.width,
+                         data.height,
+                         data.format,
+                         PixelData::DELETE_ARRAY );
 }
 
 void FontClient::Plugin::CreateVectorBlob( FontId fontId, GlyphIndex glyphIndex, VectorBlob*& blob, unsigned int& blobLength, unsigned int& nominalWidth, unsigned int& nominalHeight )
@@ -999,6 +1009,28 @@ const GlyphInfo& FontClient::Plugin::GetEllipsisGlyph( PointSize26Dot6 requested
   return item.glyph;
 }
 
+bool FontClient::Plugin::IsColorGlyph( FontId fontId, GlyphIndex glyphIndex )
+{
+  FT_Error error = -1;
+
+#ifdef FREETYPE_BITMAP_SUPPORT
+  if( ( fontId > 0 ) &&
+      ( fontId - 1u < mFontCache.size() ) )
+  {
+    const FontFaceCacheItem& item = mFontCache[fontId - 1u];
+    FT_Face ftFace = item.mFreeTypeFace;
+
+    // Check to see if this is fixed size bitmap
+    if( item.mIsFixedSizeBitmap )
+    {
+      error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_COLOR );
+    }
+  }
+#endif
+
+  return FT_Err_Ok == error;
+}
+
 void FontClient::Plugin::InitSystemFonts()
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::InitSystemFonts \n");
@@ -1079,6 +1111,11 @@ FcPattern* FontClient::Plugin::CreateFontFamilyPattern( const FontDescription& f
   // a pattern holds a set of names, each name refers to a property of the font
   FcPattern* fontFamilyPattern = FcPatternCreate();
 
+  if( !fontFamilyPattern )
+  {
+    return NULL;
+  }
+
   // add a property to the pattern for the font family
   FcPatternAddString( fontFamilyPattern, FC_FAMILY, reinterpret_cast<const FcChar8*>( fontDescription.family.c_str() ) );
 
@@ -1294,8 +1331,7 @@ FontId FontClient::Plugin::CreateFont( const FontPath& path,
   return id;
 }
 
-void FontClient::Plugin::ConvertBitmap( PixelData& destBitmap,
-                                        FT_Bitmap srcBitmap )
+void FontClient::Plugin::ConvertBitmap( TextAbstraction::FontClient::GlyphBufferData& data, FT_Bitmap srcBitmap )
 {
   if( srcBitmap.width*srcBitmap.rows > 0 )
   {
@@ -1303,12 +1339,14 @@ void FontClient::Plugin::ConvertBitmap( PixelData& destBitmap,
     {
       case FT_PIXEL_MODE_GRAY:
       {
-        if( srcBitmap.pitch == static_cast< int >( srcBitmap.width ) )
+        if( srcBitmap.pitch == static_cast<int>( srcBitmap.width ) )
         {
-          unsigned int bufferSize( srcBitmap.width * srcBitmap.rows );
-          unsigned char* buffer = new unsigned char[bufferSize];
-          memcpy( buffer, srcBitmap.buffer,bufferSize );
-          destBitmap = PixelData::New( buffer, bufferSize, srcBitmap.width, srcBitmap.rows, Pixel::L8, PixelData::DELETE_ARRAY );
+          const unsigned int bufferSize = srcBitmap.width * srcBitmap.rows;
+          data.buffer = new unsigned char[bufferSize];
+          data.width = srcBitmap.width;
+          data.height = srcBitmap.rows;
+          data.format = Pixel::L8;
+          memcpy( data.buffer, srcBitmap.buffer, bufferSize );
         }
         break;
       }
@@ -1316,12 +1354,35 @@ void FontClient::Plugin::ConvertBitmap( PixelData& destBitmap,
 #ifdef FREETYPE_BITMAP_SUPPORT
       case FT_PIXEL_MODE_BGRA:
       {
-        if ( srcBitmap.pitch == static_cast< int >( srcBitmap.width << 2 ) )
+        if( srcBitmap.pitch == static_cast<int>( srcBitmap.width << 2u ) )
         {
-          unsigned int bufferSize( srcBitmap.width * srcBitmap.rows * 4 );
-          unsigned char* buffer = new unsigned char[bufferSize];
-          memcpy( buffer, srcBitmap.buffer,bufferSize );
-          destBitmap = PixelData::New( buffer, bufferSize, srcBitmap.width, srcBitmap.rows, Pixel::BGRA8888, PixelData::DELETE_ARRAY );
+          // Set the input dimensions.
+          const ImageDimensions inputDimensions( srcBitmap.width, srcBitmap.rows );
+
+          // Set the output dimensions.
+          // If the output dimension is not given, the input dimension is set
+          // and won't be downscaling.
+          data.width = ( data.width == 0 ) ? srcBitmap.width : data.width;
+          data.height = ( data.height == 0 ) ? srcBitmap.rows : data.height;
+          const ImageDimensions desiredDimensions( data.width, data.height );
+
+          // Creates the output buffer
+          const unsigned int bufferSize = data.width * data.height * 4u;
+          data.buffer = new unsigned char[bufferSize]; // @note The caller is responsible for deallocating the bitmap data using delete[].
+
+          if( inputDimensions == desiredDimensions )
+          {
+            // There isn't downscaling.
+            memcpy( data.buffer, srcBitmap.buffer, bufferSize );
+          }
+          else
+          {
+            Dali::Internal::Platform::LanczosSample4BPP( srcBitmap.buffer,
+                                                         inputDimensions,
+                                                         data.buffer,
+                                                         desiredDimensions );
+          }
+          data.format = Pixel::BGRA8888;
         }
         break;
       }