#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
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;
}
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.
#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 );
}
if ( FT_Err_Ok == error )
{
FT_BitmapGlyph bitmapGlyph = (FT_BitmapGlyph)glyph;
- ConvertBitmap( bitmap, bitmapGlyph->bitmap );
+ ConvertBitmap( data, bitmapGlyph->bitmap );
}
else
{
}
else
{
- ConvertBitmap( bitmap, ftFace->glyph->bitmap );
+ ConvertBitmap( data, ftFace->glyph->bitmap );
}
// Created FT_Glyph object must be released with FT_Done_Glyph
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 )
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");
// 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() ) );
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 )
{
{
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;
}
#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;
}