diff options
author | Werner Lemberg <wl@gnu.org> | 2016-11-06 12:32:51 +0100 |
---|---|---|
committer | Werner Lemberg <wl@gnu.org> | 2016-11-06 12:32:51 +0100 |
commit | 37e193e9357bdccbfb8a4437ddfdc06efd9e140c (patch) | |
tree | d787e77dd3a13277a3afbbdda72cc008b8d6947f /src | |
parent | 57f73d1f77b058ecd9ccac922c311cd9e37ce26e (diff) | |
download | freetype2-37e193e9357bdccbfb8a4437ddfdc06efd9e140c.tar.gz |
Introduce a way of quickly retrieving (embedded) bitmap metrics.
`FT_Load_Glyph' doesn't generate a bitmap for a non-bitmap glyph
until the user calls `FT_Render_Glyph'. However, it always
allocates memory for bitmaps and copies or decodes the contents of a
bitmap glyph, which can be quite slow for PNG data.
* include/freetype/freetype.h (FT_LOAD_BITMAP_METRICS_ONLY): New
macro.
* src/base/ftobjs.c (FT_Load_Glyph): Unset FT_LOAD_RENDER if
FT_LOAD_BITMAP_METRICS_ONLY is used.
* src/sfnt/ttsbit.c (tt_sbit_decoder_alloc_bitmap,
tt_sbit_decoder_load_bitmap): Add argument to control allocation of
the glyph slot.
(tt_sbit_decoder_load_image, tt_sbit_decoder_load_compound,
tt_face_load_sbit_image): Updated.
* src/pcf/pcfdrivr.c (PCF_Glyph_Load): Quickly exit if
`FT_LOAD_BITMAP_METRICS_ONLY' is set.
* src/pfr/pfrsbit.c, src/pfr/pfrsbit.h (pfr_slot_load_bitmap): Add
argument to control allocation of the glyph slot.
* src/pfr/pfrobjs (pfr_slot_load): Updated.
* src/winfonts/winfnt.c (FNT_Load_Glyph): Ditto.
* docs/CHANGES: Updated.
Diffstat (limited to 'src')
-rw-r--r-- | src/base/ftobjs.c | 3 | ||||
-rw-r--r-- | src/pcf/pcfdrivr.c | 35 | ||||
-rw-r--r-- | src/pfr/pfrobjs.c | 6 | ||||
-rw-r--r-- | src/pfr/pfrsbit.c | 6 | ||||
-rw-r--r-- | src/pfr/pfrsbit.h | 3 | ||||
-rw-r--r-- | src/sfnt/ttsbit.c | 47 | ||||
-rw-r--r-- | src/winfonts/winfnt.c | 44 |
7 files changed, 88 insertions, 56 deletions
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index 9006b598b..060d78e0e 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -641,6 +641,9 @@ load_flags &= ~FT_LOAD_RENDER; } + if ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) + load_flags &= ~FT_LOAD_RENDER; + /* * Determine whether we need to auto-hint or not. * The general rules are: diff --git a/src/pcf/pcfdrivr.c b/src/pcf/pcfdrivr.c index a0db8070f..476882ff9 100644 --- a/src/pcf/pcfdrivr.c +++ b/src/pcf/pcfdrivr.c @@ -492,8 +492,6 @@ THE SOFTWARE. PCF_Metric metric; FT_ULong bytes; - FT_UNUSED( load_flags ); - FT_TRACE1(( "PCF_Glyph_Load: glyph index %d\n", glyph_index )); @@ -550,6 +548,24 @@ THE SOFTWARE. return FT_THROW( Invalid_File_Format ); } + slot->format = FT_GLYPH_FORMAT_BITMAP; + slot->bitmap_left = metric->leftSideBearing; + slot->bitmap_top = metric->ascent; + + slot->metrics.horiAdvance = (FT_Pos)( metric->characterWidth * 64 ); + slot->metrics.horiBearingX = (FT_Pos)( metric->leftSideBearing * 64 ); + slot->metrics.horiBearingY = (FT_Pos)( metric->ascent * 64 ); + slot->metrics.width = (FT_Pos)( ( metric->rightSideBearing - + metric->leftSideBearing ) * 64 ); + slot->metrics.height = (FT_Pos)( bitmap->rows * 64 ); + + ft_synthesize_vertical_metrics( &slot->metrics, + ( face->accel.fontAscent + + face->accel.fontDescent ) * 64 ); + + if ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) + goto Exit; + /* XXX: to do: are there cases that need repadding the bitmap? */ bytes = (FT_ULong)bitmap->pitch * bitmap->rows; @@ -582,21 +598,6 @@ THE SOFTWARE. } } - slot->format = FT_GLYPH_FORMAT_BITMAP; - slot->bitmap_left = metric->leftSideBearing; - slot->bitmap_top = metric->ascent; - - slot->metrics.horiAdvance = (FT_Pos)( metric->characterWidth * 64 ); - slot->metrics.horiBearingX = (FT_Pos)( metric->leftSideBearing * 64 ); - slot->metrics.horiBearingY = (FT_Pos)( metric->ascent * 64 ); - slot->metrics.width = (FT_Pos)( ( metric->rightSideBearing - - metric->leftSideBearing ) * 64 ); - slot->metrics.height = (FT_Pos)( bitmap->rows * 64 ); - - ft_synthesize_vertical_metrics( &slot->metrics, - ( face->accel.fontAscent + - face->accel.fontDescent ) * 64 ); - Exit: return error; } diff --git a/src/pfr/pfrobjs.c b/src/pfr/pfrobjs.c index 769a3b616..06996d6f3 100644 --- a/src/pfr/pfrobjs.c +++ b/src/pfr/pfrobjs.c @@ -342,7 +342,11 @@ /* try to load an embedded bitmap */ if ( ( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP ) ) == 0 ) { - error = pfr_slot_load_bitmap( slot, size, gindex ); + error = pfr_slot_load_bitmap( + slot, + size, + gindex, + ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) != 0 ); if ( error == 0 ) goto Exit; } diff --git a/src/pfr/pfrsbit.c b/src/pfr/pfrsbit.c index 144f50c0b..f9dbf734b 100644 --- a/src/pfr/pfrsbit.c +++ b/src/pfr/pfrsbit.c @@ -578,7 +578,8 @@ FT_LOCAL( FT_Error ) pfr_slot_load_bitmap( PFR_Slot glyph, PFR_Size size, - FT_UInt glyph_index ) + FT_UInt glyph_index, + FT_Bool metrics_only ) { FT_Error error; PFR_Face face = (PFR_Face) glyph->root.face; @@ -775,6 +776,9 @@ glyph->root.bitmap_left = (FT_Int)xpos; glyph->root.bitmap_top = (FT_Int)( ypos + (FT_Long)ysize ); + if ( metrics_only ) + goto Exit1; + /* Allocate and read bitmap data */ { FT_ULong len = (FT_ULong)glyph->root.bitmap.pitch * ysize; diff --git a/src/pfr/pfrsbit.h b/src/pfr/pfrsbit.h index 94ead28ca..676ad55a9 100644 --- a/src/pfr/pfrsbit.h +++ b/src/pfr/pfrsbit.h @@ -26,7 +26,8 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) pfr_slot_load_bitmap( PFR_Slot glyph, PFR_Size size, - FT_UInt glyph_index ); + FT_UInt glyph_index, + FT_Bool metrics_only ); FT_END_HEADER diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c index b5986aa7c..8d8b9e73c 100644 --- a/src/sfnt/ttsbit.c +++ b/src/sfnt/ttsbit.c @@ -536,7 +536,8 @@ static FT_Error - tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder ) + tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder, + FT_Bool metrics_only ) { FT_Error error = FT_Err_Ok; FT_UInt width, height; @@ -599,6 +600,9 @@ if ( size == 0 ) goto Exit; /* exit successfully! */ + if ( metrics_only ) + goto Exit; /* only metrics are requested */ + error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size ); if ( error ) goto Exit; @@ -665,7 +669,8 @@ FT_UInt glyph_index, FT_Int x_pos, FT_Int y_pos, - FT_UInt recurse_count ); + FT_UInt recurse_count, + FT_Bool metrics_only ); typedef FT_Error (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder decoder, @@ -995,7 +1000,9 @@ gindex, x_pos + dx, y_pos + dy, - recurse_count + 1 ); + recurse_count + 1, + /* request full bitmap image */ + FALSE ); if ( error ) break; } @@ -1077,7 +1084,8 @@ FT_ULong glyph_size, FT_Int x_pos, FT_Int y_pos, - FT_UInt recurse_count ) + FT_UInt recurse_count, + FT_Bool metrics_only ) { FT_Error error; FT_Stream stream = decoder->stream; @@ -1199,11 +1207,15 @@ if ( !decoder->bitmap_allocated ) { - error = tt_sbit_decoder_alloc_bitmap( decoder ); + error = tt_sbit_decoder_alloc_bitmap( decoder, metrics_only ); + if ( error ) goto Fail; } + if ( metrics_only ) + goto Fail; /* this is not an error */ + error = loader( decoder, p, p_limit, x_pos, y_pos, recurse_count ); } @@ -1220,7 +1232,8 @@ FT_UInt glyph_index, FT_Int x_pos, FT_Int y_pos, - FT_UInt recurse_count ) + FT_UInt recurse_count, + FT_Bool metrics_only ) { FT_Byte* p = decoder->eblc_base + decoder->strike_index_array; FT_Byte* p_limit = decoder->eblc_limit; @@ -1405,7 +1418,8 @@ image_end, x_pos, y_pos, - recurse_count ); + recurse_count, + metrics_only ); Failure: return FT_THROW( Invalid_Table ); @@ -1567,11 +1581,13 @@ error = tt_sbit_decoder_init( decoder, face, strike_index, metrics ); if ( !error ) { - error = tt_sbit_decoder_load_image( decoder, - glyph_index, - 0, - 0, - 0 ); + error = tt_sbit_decoder_load_image( + decoder, + glyph_index, + 0, + 0, + 0, + ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) != 0 ); tt_sbit_decoder_done( decoder ); } } @@ -1592,9 +1608,10 @@ } /* Flatten color bitmaps if color was not requested. */ - if ( !error && - !( load_flags & FT_LOAD_COLOR ) && - map->pixel_mode == FT_PIXEL_MODE_BGRA ) + if ( !error && + !( load_flags & FT_LOAD_COLOR ) && + !( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) && + map->pixel_mode == FT_PIXEL_MODE_BGRA ) { FT_Bitmap new_map; FT_Library library = face->root.glyph->library; diff --git a/src/winfonts/winfnt.c b/src/winfonts/winfnt.c index b412f105d..99cc96617 100644 --- a/src/winfonts/winfnt.c +++ b/src/winfonts/winfnt.c @@ -1000,8 +1000,6 @@ FT_ULong offset; FT_Bool new_format; - FT_UNUSED( load_flags ); - if ( !face ) { @@ -1055,6 +1053,26 @@ goto Exit; } + bitmap->rows = font->header.pixel_height; + bitmap->pixel_mode = FT_PIXEL_MODE_MONO; + + slot->bitmap_left = 0; + slot->bitmap_top = font->header.ascent; + slot->format = FT_GLYPH_FORMAT_BITMAP; + + /* now set up metrics */ + slot->metrics.width = (FT_Pos)( bitmap->width << 6 ); + slot->metrics.height = (FT_Pos)( bitmap->rows << 6 ); + slot->metrics.horiAdvance = (FT_Pos)( bitmap->width << 6 ); + slot->metrics.horiBearingX = 0; + slot->metrics.horiBearingY = slot->bitmap_top << 6; + + ft_synthesize_vertical_metrics( &slot->metrics, + (FT_Pos)( bitmap->rows << 6 ) ); + + if ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) + goto Exit; + /* jump to glyph data */ p = font->fnt_frame + /* font->header.bits_offset */ + offset; @@ -1066,10 +1084,7 @@ FT_Byte* write; - bitmap->pitch = (int)pitch; - bitmap->rows = font->header.pixel_height; - bitmap->pixel_mode = FT_PIXEL_MODE_MONO; - + bitmap->pitch = (int)pitch; if ( !pitch || offset + pitch * bitmap->rows > font->header.file_size ) { @@ -1093,22 +1108,9 @@ for ( write = column; p < limit; p++, write += bitmap->pitch ) *write = *p; } - } - slot->internal->flags = FT_GLYPH_OWN_BITMAP; - slot->bitmap_left = 0; - slot->bitmap_top = font->header.ascent; - slot->format = FT_GLYPH_FORMAT_BITMAP; - - /* now set up metrics */ - slot->metrics.width = (FT_Pos)( bitmap->width << 6 ); - slot->metrics.height = (FT_Pos)( bitmap->rows << 6 ); - slot->metrics.horiAdvance = (FT_Pos)( bitmap->width << 6 ); - slot->metrics.horiBearingX = 0; - slot->metrics.horiBearingY = slot->bitmap_top << 6; - - ft_synthesize_vertical_metrics( &slot->metrics, - (FT_Pos)( bitmap->rows << 6 ) ); + slot->internal->flags = FT_GLYPH_OWN_BITMAP; + } Exit: return error; |