} // namespace
-
-
using Dali::Vector;
namespace Dali
#ifdef ENABLE_VECTOR_BASED_TEXT_RENDERING
mVectorFontCache = new VectorFontCache( mFreeTypeLibrary );
#endif
-
}
FontClient::Plugin::~Plugin()
switch( fontIdCacheItem.type )
{
- case FontDescription::FACE_FONT:
- {
- const FontFaceCacheItem& font = mFontFaceCache[fontIdCacheItem.id];
+ case FontDescription::FACE_FONT:
+ {
+ const FontFaceCacheItem& font = mFontFaceCache[fontIdCacheItem.id];
- FT_Face ftFace = font.mFreeTypeFace;
+ FT_Face ftFace = font.mFreeTypeFace;
#ifdef FREETYPE_BITMAP_SUPPORT
- // Check to see if we should be loading a Fixed Size bitmap?
- if( font.mIsFixedSizeBitmap )
- {
- FT_Select_Size( ftFace, font.mFixedSizeIndex ); ///< @todo: needs to be investigated why it's needed to select the size again.
- int error = FT_Load_Glyph( ftFace, glyph.index, FT_LOAD_COLOR );
- if ( FT_Err_Ok == error )
+ // Check to see if we should be loading a Fixed Size bitmap?
+ if( font.mIsFixedSizeBitmap )
{
- glyph.width = font.mFixedWidthPixels;
- glyph.height = font.mFixedHeightPixels;
- glyph.advance = font.mFixedWidthPixels;
- glyph.xBearing = 0.0f;
- glyph.yBearing = font.mFixedHeightPixels;
+ FT_Select_Size( ftFace, font.mFixedSizeIndex ); ///< @todo: needs to be investigated why it's needed to select the size again.
+ int error = FT_Load_Glyph( ftFace, glyph.index, FT_LOAD_COLOR );
+ if ( FT_Err_Ok == error )
+ {
+ glyph.width = font.mFixedWidthPixels;
+ glyph.height = font.mFixedHeightPixels;
+ glyph.advance = font.mFixedWidthPixels;
+ glyph.xBearing = 0.0f;
+ glyph.yBearing = font.mFixedHeightPixels;
- // Adjust the metrics if the fixed-size font should be down-scaled
- const float desiredFixedSize = static_cast<float>( font.mRequestedPointSize ) * FROM_266 / POINTS_PER_INCH * mDpiVertical;
+ // Adjust the metrics if the fixed-size font should be down-scaled
+ const float desiredFixedSize = static_cast<float>( font.mRequestedPointSize ) * FROM_266 / POINTS_PER_INCH * mDpiVertical;
- if( desiredFixedSize > 0.f )
- {
- const float scaleFactor = desiredFixedSize / font.mFixedHeightPixels;
+ if( desiredFixedSize > 0.f )
+ {
+ const float scaleFactor = desiredFixedSize / font.mFixedHeightPixels;
- glyph.width = glyph.width * scaleFactor ;
- glyph.height = glyph.height * scaleFactor;
- glyph.advance = glyph.advance * scaleFactor;
- glyph.xBearing = glyph.xBearing * scaleFactor;
- glyph.yBearing = glyph.yBearing * scaleFactor;
+ glyph.width = glyph.width * scaleFactor ;
+ glyph.height = glyph.height * scaleFactor;
+ glyph.advance = glyph.advance * scaleFactor;
+ glyph.xBearing = glyph.xBearing * scaleFactor;
+ glyph.yBearing = glyph.yBearing * scaleFactor;
- glyph.scaleFactor = scaleFactor;
+ glyph.scaleFactor = scaleFactor;
+ }
+ }
+ else
+ {
+ DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::GetBitmapMetrics. FreeType Bitmap Load_Glyph error %d\n", error );
+ success = false;
}
}
else
- {
- DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::GetBitmapMetrics. FreeType Bitmap Load_Glyph error %d\n", error );
- success = false;
- }
- }
- else
#endif
- {
- int error = FT_Load_Glyph( ftFace, glyph.index, FT_LOAD_NO_AUTOHINT );
-
- if( FT_Err_Ok == error )
{
- glyph.width = static_cast< float >( ftFace->glyph->metrics.width ) * FROM_266;
- glyph.height = static_cast< float >( ftFace->glyph->metrics.height ) * FROM_266 ;
- if( horizontal )
+ int error = FT_Load_Glyph( ftFace, glyph.index, FT_LOAD_NO_AUTOHINT );
+
+ if( FT_Err_Ok == error )
{
- glyph.xBearing += static_cast< float >( ftFace->glyph->metrics.horiBearingX ) * FROM_266;
- glyph.yBearing += static_cast< float >( ftFace->glyph->metrics.horiBearingY ) * FROM_266;
+ glyph.width = static_cast< float >( ftFace->glyph->metrics.width ) * FROM_266;
+ glyph.height = static_cast< float >( ftFace->glyph->metrics.height ) * FROM_266 ;
+ if( horizontal )
+ {
+ glyph.xBearing += static_cast< float >( ftFace->glyph->metrics.horiBearingX ) * FROM_266;
+ glyph.yBearing += static_cast< float >( ftFace->glyph->metrics.horiBearingY ) * FROM_266;
+ }
+ else
+ {
+ glyph.xBearing += static_cast< float >( ftFace->glyph->metrics.vertBearingX ) * FROM_266;
+ glyph.yBearing += static_cast< float >( ftFace->glyph->metrics.vertBearingY ) * FROM_266;
+ }
}
else
{
- glyph.xBearing += static_cast< float >( ftFace->glyph->metrics.vertBearingX ) * FROM_266;
- glyph.yBearing += static_cast< float >( ftFace->glyph->metrics.vertBearingY ) * FROM_266;
+ success = false;
}
}
- else
- {
- success = false;
- }
+ break;
}
- break;
- }
- case FontDescription::BITMAP_FONT:
- {
- BitmapFontCacheItem& bitmapFontCacheItem = mBitmapFontCache[fontIdCacheItem.id];
-
- unsigned int index = 0u;
- for( auto& item : bitmapFontCacheItem.font.glyphs )
+ case FontDescription::BITMAP_FONT:
{
- if( item.utf32 == glyph.index )
+ BitmapFontCacheItem& bitmapFontCacheItem = mBitmapFontCache[fontIdCacheItem.id];
+
+ unsigned int index = 0u;
+ for( auto& item : bitmapFontCacheItem.font.glyphs )
{
- Devel::PixelBuffer& pixelBuffer = bitmapFontCacheItem.pixelBuffers[index];
- if( !pixelBuffer )
+ if( item.utf32 == glyph.index )
{
- pixelBuffer = LoadImageFromFile( item.url );
- }
+ Devel::PixelBuffer& pixelBuffer = bitmapFontCacheItem.pixelBuffers[index];
+ if( !pixelBuffer )
+ {
+ pixelBuffer = LoadImageFromFile( item.url );
+ }
- glyph.width = static_cast< float >( pixelBuffer.GetWidth() );
- glyph.height = static_cast< float >( pixelBuffer.GetHeight() );
- glyph.xBearing = 0.f;
- glyph.yBearing = glyph.height + item.descender;
- glyph.advance = glyph.width;
- glyph.scaleFactor = 1.f;
- break;
+ glyph.width = static_cast< float >( pixelBuffer.GetWidth() );
+ glyph.height = static_cast< float >( pixelBuffer.GetHeight() );
+ glyph.xBearing = 0.f;
+ glyph.yBearing = glyph.height + item.descender;
+ glyph.advance = glyph.width;
+ glyph.scaleFactor = 1.f;
+ break;
+ }
+ ++index;
}
- ++index;
- }
- success = true;
- break;
- }
- default:
- {
- DALI_LOG_INFO(gLogFilter, Debug::General, " Invalid type of font\n");
- }
+ success = true;
+ break;
+ }
+ default:
+ {
+ DALI_LOG_INFO(gLogFilter, Debug::General, " Invalid type of font\n");
+ }
}
}
else
switch( fontIdCacheItem.type )
{
- case FontDescription::FACE_FONT:
- {
- // For the software italics.
- bool isShearRequired = false;
+ case FontDescription::FACE_FONT:
+ {
+ // For the software italics.
+ bool isShearRequired = false;
- const FontFaceCacheItem& fontFaceCacheItem = mFontFaceCache[fontIdCacheItem.id];
- FT_Face ftFace = fontFaceCacheItem.mFreeTypeFace;
+ const FontFaceCacheItem& fontFaceCacheItem = mFontFaceCache[fontIdCacheItem.id];
+ FT_Face ftFace = fontFaceCacheItem.mFreeTypeFace;
- FT_Error error;
+ FT_Error error;
#ifdef FREETYPE_BITMAP_SUPPORT
- // Check to see if this is fixed size bitmap
- if( fontFaceCacheItem.mIsFixedSizeBitmap )
- {
- error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_COLOR );
- }
- else
-#endif
- {
- error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_NO_AUTOHINT );
- }
- if( FT_Err_Ok == error )
- {
- if( isBoldRequired && !( ftFace->style_flags & FT_STYLE_FLAG_BOLD ) )
+ // Check to see if this is fixed size bitmap
+ if( fontFaceCacheItem.mIsFixedSizeBitmap )
{
- // Does the software bold.
- FT_GlyphSlot_Embolden( ftFace->glyph );
+ error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_COLOR );
}
-
- if( isItalicRequired && !( ftFace->style_flags & FT_STYLE_FLAG_ITALIC ) )
+ else
+#endif
{
- // Will do the software italic.
- isShearRequired = true;
+ error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_NO_AUTOHINT );
}
+ if( FT_Err_Ok == error )
+ {
+ if( isBoldRequired && !( ftFace->style_flags & FT_STYLE_FLAG_BOLD ) )
+ {
+ // Does the software bold.
+ FT_GlyphSlot_Embolden( ftFace->glyph );
+ }
- FT_Glyph glyph;
- error = FT_Get_Glyph( ftFace->glyph, &glyph );
+ if( isItalicRequired && !( ftFace->style_flags & FT_STYLE_FLAG_ITALIC ) )
+ {
+ // Will do the software italic.
+ isShearRequired = true;
+ }
- // Convert to bitmap if necessary
- if ( FT_Err_Ok == error )
- {
- if( glyph->format != FT_GLYPH_FORMAT_BITMAP )
+ FT_Glyph glyph;
+ error = FT_Get_Glyph( ftFace->glyph, &glyph );
+
+ // Convert to bitmap if necessary
+ if( FT_Err_Ok == error )
{
- // Check whether we should create a bitmap for the outline
- if( glyph->format == FT_GLYPH_FORMAT_OUTLINE && outlineWidth > 0 )
+ if( glyph->format != FT_GLYPH_FORMAT_BITMAP )
{
- // Set up a stroker
- FT_Stroker stroker;
- error = FT_Stroker_New( mFreeTypeLibrary, &stroker );
-
- if( FT_Err_Ok == error )
+ // Check whether we should create a bitmap for the outline
+ if( glyph->format == FT_GLYPH_FORMAT_OUTLINE && outlineWidth > 0 )
{
- FT_Stroker_Set( stroker, outlineWidth * 64, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0 );
- error = FT_Glyph_StrokeBorder( &glyph, stroker, 0, 1 );
+ // Set up a stroker
+ FT_Stroker stroker;
+ error = FT_Stroker_New( mFreeTypeLibrary, &stroker );
if( FT_Err_Ok == error )
{
- FT_Stroker_Done( stroker );
+ FT_Stroker_Set( stroker, outlineWidth * 64, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0 );
+ error = FT_Glyph_StrokeBorder( &glyph, stroker, 0, 1 );
+
+ if( FT_Err_Ok == error )
+ {
+ FT_Stroker_Done( stroker );
+ }
+ else
+ {
+ DALI_LOG_ERROR( "FT_Glyph_StrokeBorder Failed with error: %d\n", error );
+ }
}
else
{
- DALI_LOG_ERROR( "FT_Glyph_StrokeBorder Failed with error: %d\n", error );
+ DALI_LOG_ERROR( "FT_Stroker_New Failed with error: %d\n", error );
}
}
+
+ error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL, 0, 1 );
+ if( FT_Err_Ok == error )
+ {
+ FT_BitmapGlyph bitmapGlyph = reinterpret_cast< FT_BitmapGlyph >( glyph );
+ ConvertBitmap( data, bitmapGlyph->bitmap, isShearRequired );
+ }
else
{
- DALI_LOG_ERROR( "FT_Stroker_New Failed with error: %d\n", error );
+ DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::CreateBitmap. FT_Get_Glyph Failed with error: %d\n", error );
}
}
-
- error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL, 0, 1 );
- if( FT_Err_Ok == error )
- {
- FT_BitmapGlyph bitmapGlyph = reinterpret_cast< FT_BitmapGlyph >( glyph );
- ConvertBitmap( data, bitmapGlyph->bitmap, isShearRequired );
- }
else
{
- DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::CreateBitmap. FT_Get_Glyph Failed with error: %d\n", error );
+ ConvertBitmap( data, ftFace->glyph->bitmap, isShearRequired );
}
- }
- else
- {
- ConvertBitmap( data, ftFace->glyph->bitmap, isShearRequired );
- }
- data.isColorEmoji = fontFaceCacheItem.mIsFixedSizeBitmap;
+ data.isColorEmoji = fontFaceCacheItem.mIsFixedSizeBitmap;
- // Created FT_Glyph object must be released with FT_Done_Glyph
- FT_Done_Glyph( glyph );
+ // Created FT_Glyph object must be released with FT_Done_Glyph
+ FT_Done_Glyph( glyph );
+ }
+ }
+ else
+ {
+ DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::CreateBitmap. FT_Load_Glyph Failed with error: %d\n", error );
}
+ break;
}
- else
+ case FontDescription::BITMAP_FONT:
{
- DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::CreateBitmap. FT_Load_Glyph Failed with error: %d\n", error );
- }
- break;
- }
- case FontDescription::BITMAP_FONT:
- {
- BitmapFontCacheItem& bitmapFontCacheItem = mBitmapFontCache[fontIdCacheItem.id];
+ BitmapFontCacheItem& bitmapFontCacheItem = mBitmapFontCache[fontIdCacheItem.id];
- unsigned int index = 0u;
- for( auto& item : bitmapFontCacheItem.font.glyphs )
- {
- if( item.utf32 == glyphIndex )
+ unsigned int index = 0u;
+ for( auto& item : bitmapFontCacheItem.font.glyphs )
{
- Devel::PixelBuffer& pixelBuffer = bitmapFontCacheItem.pixelBuffers[index];
- if( !pixelBuffer )
+ if( item.utf32 == glyphIndex )
{
- pixelBuffer = LoadImageFromFile( item.url );
- }
+ Devel::PixelBuffer& pixelBuffer = bitmapFontCacheItem.pixelBuffers[index];
+ if( !pixelBuffer )
+ {
+ pixelBuffer = LoadImageFromFile( item.url );
+ }
- data.width = pixelBuffer.GetWidth();
- data.height = pixelBuffer.GetHeight();
+ data.width = pixelBuffer.GetWidth();
+ data.height = pixelBuffer.GetHeight();
- data.isColorBitmap = bitmapFontCacheItem.font.isColorFont;
+ data.isColorBitmap = bitmapFontCacheItem.font.isColorFont;
- ConvertBitmap( data, data.width, data.height, pixelBuffer.GetBuffer() );
+ ConvertBitmap( data, data.width, data.height, pixelBuffer.GetBuffer() );
- // Sets the pixel format.
- data.format = pixelBuffer.GetPixelFormat();
- break;
+ // Sets the pixel format.
+ data.format = pixelBuffer.GetPixelFormat();
+ break;
+ }
+ ++index;
}
- ++index;
+ break;
+ }
+ default:
+ {
+ DALI_LOG_INFO(gLogFilter, Debug::General, " Invalid type of font\n");
}
- break;
- }
- default:
- {
- DALI_LOG_INFO(gLogFilter, Debug::General, " Invalid type of font\n");
- }
}
}
else
switch( fontIdCacheItem.type )
{
- case FontDescription::FACE_FONT:
- {
+ case FontDescription::FACE_FONT:
+ {
#ifdef FREETYPE_BITMAP_SUPPORT
- const FontFaceCacheItem& item = mFontFaceCache[fontIdCacheItem.id];
- FT_Face ftFace = item.mFreeTypeFace;
+ const FontFaceCacheItem& item = mFontFaceCache[fontIdCacheItem.id];
+ FT_Face ftFace = item.mFreeTypeFace;
- // Check to see if this is fixed size bitmap
- if( item.mHasColorTables )
+ // Check to see if this is fixed size bitmap
+ if( item.mHasColorTables )
+ {
+ error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_COLOR );
+ }
+#endif
+ break;
+ }
+ case FontDescription::BITMAP_FONT:
{
- error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_COLOR );
+ error = FT_Err_Ok; // Will return true;
+ break;
+ }
+ default:
+ {
+ DALI_LOG_INFO(gLogFilter, Debug::General, " Invalid type of font\n");
}
-#endif
- break;
- }
- case FontDescription::BITMAP_FONT:
- {
- error = FT_Err_Ok; // Will return true;
- break;
- }
- default:
- {
- DALI_LOG_INFO(gLogFilter, Debug::General, " Invalid type of font\n");
- }
}
}
switch( type )
{
- case FontDescription::FACE_FONT:
- {
- // Reserve some space to avoid reallocations.
- const Length numberOfGlyphs = static_cast<Length>( 1.3f * static_cast<float>( numberOfCharacters ) );
- mIndices.Reserve( numberOfGlyphs );
- mAdvance.Reserve( numberOfGlyphs );
- mCharacterMap.Reserve( numberOfGlyphs );
- mOffset.Reserve( 2u * numberOfGlyphs );
-
- // Retrieve a FreeType font's face.
- FT_Face face = fontClientImpl.GetFreetypeFace( fontId );
- if( nullptr == face )
+ case FontDescription::FACE_FONT:
{
- // Nothing to do if the face is null.
- return 0u;
- }
-
- unsigned int horizontalDpi = 0u;
- unsigned int verticalDpi = 0u;
- fontClient.GetDpi( horizontalDpi, verticalDpi );
+ // Reserve some space to avoid reallocations.
+ const Length numberOfGlyphs = static_cast<Length>( 1.3f * static_cast<float>( numberOfCharacters ) );
+ mIndices.Reserve( numberOfGlyphs );
+ mAdvance.Reserve( numberOfGlyphs );
+ mCharacterMap.Reserve( numberOfGlyphs );
+ mOffset.Reserve( 2u * numberOfGlyphs );
+
+ // Retrieve a FreeType font's face.
+ FT_Face face = fontClientImpl.GetFreetypeFace( fontId );
+ if( nullptr == face )
+ {
+ // Nothing to do if the face is null.
+ return 0u;
+ }
- FT_Set_Char_Size( face,
- 0u,
- fontClient.GetPointSize( fontId ),
- horizontalDpi,
- verticalDpi );
+ unsigned int horizontalDpi = 0u;
+ unsigned int verticalDpi = 0u;
+ fontClient.GetDpi( horizontalDpi, verticalDpi );
- /* Get our harfbuzz font struct */
- hb_font_t* harfBuzzFont;
- harfBuzzFont = hb_ft_font_create( face, NULL );
+ FT_Set_Char_Size( face,
+ 0u,
+ fontClient.GetPointSize( fontId ),
+ horizontalDpi,
+ verticalDpi );
- /* Create a buffer for harfbuzz to use */
- hb_buffer_t* harfBuzzBuffer = hb_buffer_create();
+ /* Get our harfbuzz font struct */
+ hb_font_t* harfBuzzFont;
+ harfBuzzFont = hb_ft_font_create( face, NULL );
- const bool rtlDirection = IsRightToLeftScript( script );
- hb_buffer_set_direction( harfBuzzBuffer,
- rtlDirection ? HB_DIRECTION_RTL : HB_DIRECTION_LTR ); /* or LTR */
+ /* Create a buffer for harfbuzz to use */
+ hb_buffer_t* harfBuzzBuffer = hb_buffer_create();
- hb_buffer_set_script( harfBuzzBuffer,
- SCRIPT_TO_HARFBUZZ[ script ] ); /* see hb-unicode.h */
+ const bool rtlDirection = IsRightToLeftScript( script );
+ hb_buffer_set_direction( harfBuzzBuffer,
+ rtlDirection ? HB_DIRECTION_RTL : HB_DIRECTION_LTR ); /* or LTR */
+ hb_buffer_set_script( harfBuzzBuffer,
+ SCRIPT_TO_HARFBUZZ[ script ] ); /* see hb-unicode.h */
- char* currentLocale = setlocale(LC_MESSAGES,NULL);
- std::istringstream stringStream( currentLocale );
- std::string localeString;
- std::getline(stringStream, localeString, '_');
- hb_buffer_set_language( harfBuzzBuffer, hb_language_from_string( localeString.c_str(), localeString.size() ) );
+ char* currentLocale = setlocale(LC_MESSAGES,NULL);
- /* Layout the text */
- hb_buffer_add_utf32( harfBuzzBuffer, text, numberOfCharacters, 0u, numberOfCharacters );
+ std::istringstream stringStream( currentLocale );
+ std::string localeString;
+ std::getline(stringStream, localeString, '_');
+ hb_buffer_set_language( harfBuzzBuffer, hb_language_from_string( localeString.c_str(), localeString.size() ) );
- hb_shape( harfBuzzFont, harfBuzzBuffer, NULL, 0u );
+ /* Layout the text */
+ hb_buffer_add_utf32( harfBuzzBuffer, text, numberOfCharacters, 0u, numberOfCharacters );
- /* Get glyph data */
- unsigned int glyphCount;
- hb_glyph_info_t* glyphInfo = hb_buffer_get_glyph_infos( harfBuzzBuffer, &glyphCount );
- hb_glyph_position_t *glyphPositions = hb_buffer_get_glyph_positions( harfBuzzBuffer, &glyphCount );
- const GlyphIndex lastGlyphIndex = glyphCount - 1u;
- for( GlyphIndex i = 0u; i < glyphCount; )
- {
- if( rtlDirection )
- {
- // If the direction is right to left, Harfbuzz retrieves the glyphs in the visual order.
- // The glyphs are needed in the logical order to layout the text in lines.
- // Do not change the order of the glyphs if they belong to the same cluster.
- GlyphIndex rtlIndex = lastGlyphIndex - i;
+ hb_shape( harfBuzzFont, harfBuzzBuffer, NULL, 0u );
- unsigned int cluster = glyphInfo[rtlIndex].cluster;
- unsigned int previousCluster = cluster;
- Length numberOfGlyphsInCluster = 0u;
+ /* Get glyph data */
+ unsigned int glyphCount;
+ hb_glyph_info_t* glyphInfo = hb_buffer_get_glyph_infos( harfBuzzBuffer, &glyphCount );
+ hb_glyph_position_t *glyphPositions = hb_buffer_get_glyph_positions( harfBuzzBuffer, &glyphCount );
+ const GlyphIndex lastGlyphIndex = glyphCount - 1u;
- while( ( cluster == previousCluster ) )
+ for( GlyphIndex i = 0u; i < glyphCount; )
+ {
+ if( rtlDirection )
{
- ++numberOfGlyphsInCluster;
- previousCluster = cluster;
+ // If the direction is right to left, Harfbuzz retrieves the glyphs in the visual order.
+ // The glyphs are needed in the logical order to layout the text in lines.
+ // Do not change the order of the glyphs if they belong to the same cluster.
+ GlyphIndex rtlIndex = lastGlyphIndex - i;
- if( rtlIndex > 0u )
- {
- --rtlIndex;
+ unsigned int cluster = glyphInfo[rtlIndex].cluster;
+ unsigned int previousCluster = cluster;
+ Length numberOfGlyphsInCluster = 0u;
- cluster = glyphInfo[rtlIndex].cluster;
- }
- else
+ while( ( cluster == previousCluster ) )
{
- break;
+ ++numberOfGlyphsInCluster;
+ previousCluster = cluster;
+
+ if( rtlIndex > 0u )
+ {
+ --rtlIndex;
+
+ cluster = glyphInfo[rtlIndex].cluster;
+ }
+ else
+ {
+ break;
+ }
}
- }
- rtlIndex = lastGlyphIndex - ( i + ( numberOfGlyphsInCluster - 1u ) );
+ rtlIndex = lastGlyphIndex - ( i + ( numberOfGlyphsInCluster - 1u ) );
- for( GlyphIndex j = 0u; j < numberOfGlyphsInCluster; ++j )
- {
- const GlyphIndex index = rtlIndex + j;
+ for( GlyphIndex j = 0u; j < numberOfGlyphsInCluster; ++j )
+ {
+ const GlyphIndex index = rtlIndex + j;
- mIndices.PushBack( glyphInfo[index].codepoint );
- mAdvance.PushBack( floor( glyphPositions[index].x_advance * FROM_266 ) );
- mCharacterMap.PushBack( glyphInfo[index].cluster );
- mOffset.PushBack( floor( glyphPositions[index].x_offset * FROM_266 ) );
- mOffset.PushBack( floor( glyphPositions[index].y_offset * FROM_266 ) );
+ mIndices.PushBack( glyphInfo[index].codepoint );
+ mAdvance.PushBack( floor( glyphPositions[index].x_advance * FROM_266 ) );
+ mCharacterMap.PushBack( glyphInfo[index].cluster );
+ mOffset.PushBack( floor( glyphPositions[index].x_offset * FROM_266 ) );
+ mOffset.PushBack( floor( glyphPositions[index].y_offset * FROM_266 ) );
+ }
+
+ i += numberOfGlyphsInCluster;
}
+ else
+ {
+ mIndices.PushBack( glyphInfo[i].codepoint );
+ mAdvance.PushBack( floor( glyphPositions[i].x_advance * FROM_266 ) );
+ mCharacterMap.PushBack( glyphInfo[i].cluster );
+ mOffset.PushBack( floor( glyphPositions[i].x_offset * FROM_266 ) );
+ mOffset.PushBack( floor( glyphPositions[i].y_offset * FROM_266 ) );
- i += numberOfGlyphsInCluster;
+ ++i;
+ }
}
- else
- {
- mIndices.PushBack( glyphInfo[i].codepoint );
- mAdvance.PushBack( floor( glyphPositions[i].x_advance * FROM_266 ) );
- mCharacterMap.PushBack( glyphInfo[i].cluster );
- mOffset.PushBack( floor( glyphPositions[i].x_offset * FROM_266 ) );
- mOffset.PushBack( floor( glyphPositions[i].y_offset * FROM_266 ) );
- ++i;
+ /* Cleanup */
+ hb_buffer_destroy( harfBuzzBuffer );
+ hb_font_destroy( harfBuzzFont );
+ break;
+ }
+ case FontDescription::BITMAP_FONT:
+ {
+ // Reserve some space to avoid reallocations.
+ // The advance and offset tables can be initialized with zeros as it's not needed to get metrics from the bitmaps here.
+ mIndices.Resize( numberOfCharacters );
+ mAdvance.Resize( numberOfCharacters, 0u );
+ mCharacterMap.Reserve( numberOfCharacters );
+ mOffset.Resize( 2u * numberOfCharacters, 0.f );
+
+ // The utf32 character can be used as the glyph's index.
+ std::copy( text, text + numberOfCharacters, mIndices.Begin() );
+
+ // The glyph to character map is 1 to 1.
+ for( unsigned int index = 0u; index < numberOfCharacters; ++index )
+ {
+ mCharacterMap.PushBack( index );
}
+ break;
}
-
- /* Cleanup */
- hb_buffer_destroy( harfBuzzBuffer );
- hb_font_destroy( harfBuzzFont );
- break;
- }
- case FontDescription::BITMAP_FONT:
- {
- // Reserve some space to avoid reallocations.
- // The advance and offset tables can be initialized with zeros as it's not needed to get metrics from the bitmaps here.
- mIndices.Resize( numberOfCharacters );
- mAdvance.Resize( numberOfCharacters, 0u );
- mCharacterMap.Reserve( numberOfCharacters );
- mOffset.Resize( 2u * numberOfCharacters, 0.f );
-
- // The utf32 character can be used as the glyph's index.
- std::copy( text, text + numberOfCharacters, mIndices.Begin() );
-
- // The glyph to character map is 1 to 1.
- for( unsigned int index = 0u; index < numberOfCharacters; ++index )
+ default:
{
- mCharacterMap.PushBack( index );
+ DALI_LOG_INFO(gLogFilter, Debug::General, " Invalid type of font\n");
}
- break;
- }
- default:
- {
- DALI_LOG_INFO(gLogFilter, Debug::General, " Invalid type of font\n");
- }
}
return mIndices.Count();