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.
This commit is contained in:
parent
57f73d1f77
commit
37e193e935
35
ChangeLog
35
ChangeLog
@ -1,4 +1,37 @@
|
||||
2016-10-29 Werner Lemberg <wl@gnu.org>
|
||||
2016-11-06 Seigo Nonaka <nona@google.com>
|
||||
Werner Lemberg <wl@gnu.org>
|
||||
|
||||
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.
|
||||
|
||||
2016-11-06 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
Synchronize with gnulib (#49448).
|
||||
|
||||
|
@ -37,6 +37,9 @@ CHANGES BETWEEN 2.7 and 2.7.1
|
||||
blend coordinates of the currently selected variation instance
|
||||
has been added to the Multiple Masters interface.
|
||||
|
||||
- A new load flag `FT_LOAD_BITMAP_METRICS_ONLY' to retrieve bitmap
|
||||
information without loading the (embedded) bitmap itself.
|
||||
|
||||
|
||||
======================================================================
|
||||
|
||||
|
@ -2802,6 +2802,14 @@ FT_BEGIN_HEADER
|
||||
*
|
||||
* Currently, this flag is only implemented for TrueType fonts.
|
||||
*
|
||||
* FT_LOAD_BITMAP_METRICS_ONLY ::
|
||||
* This flag is used to request loading of the metrics and bitmap
|
||||
* image information of a (possibly embedded) bitmap glyph without
|
||||
* allocating or copying the bitmap image data itself. No effect if
|
||||
* the target glyph is not a bitmap image.
|
||||
*
|
||||
* This flag unsets @FT_LOAD_RENDER.
|
||||
*
|
||||
* FT_LOAD_CROP_BITMAP ::
|
||||
* Ignored. Deprecated.
|
||||
*
|
||||
@ -2848,6 +2856,7 @@ FT_BEGIN_HEADER
|
||||
/* Bits 16..19 are used by `FT_LOAD_TARGET_' */
|
||||
#define FT_LOAD_COLOR ( 1L << 20 )
|
||||
#define FT_LOAD_COMPUTE_METRICS ( 1L << 21 )
|
||||
#define FT_LOAD_BITMAP_METRICS_ONLY ( 1L << 22 )
|
||||
|
||||
/* */
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,23 +1108,10 @@
|
||||
for ( write = column; p < limit; p++, write += bitmap->pitch )
|
||||
*write = *p;
|
||||
}
|
||||
|
||||
slot->internal->flags = FT_GLYPH_OWN_BITMAP;
|
||||
}
|
||||
|
||||
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 ) );
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user