[sfnt, truetype] Improve handling of missing sbits.
Requested by Behdad. Modern bitmap-only SFNTs like `NotoColorEmoji.ttf' don't contain entries in the bitmap strike(s) for empty glyphs. Instead, they rely that a space glyph gets created from the font's metrics data. This commit makes FreeType behave accordingly. * include/freetype/fterrdef.h (FT_Err_Missing_Bitmap): New error code. * src/sfnt/ttsbit.c (tt_sbit_decoder_load_image): Change error codes to make a distinction between a missing bitmap in a composite and a simple missing bitmap. * src/truetype/ttgload.c (TT_Load_Glyph): For a missing bitmap (in a bitmap-only font), synthesize an empty bitmap glyph if metrics are available.
This commit is contained in:
parent
e77ee789fa
commit
b45043c440
22
ChangeLog
22
ChangeLog
@ -1,3 +1,25 @@
|
||||
2017-08-11 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
[sfnt, truetype] Improve handling of missing sbits.
|
||||
|
||||
Requested by Behdad.
|
||||
|
||||
Modern bitmap-only SFNTs like `NotoColorEmoji.ttf' don't contain
|
||||
entries in the bitmap strike(s) for empty glyphs. Instead, they
|
||||
rely that a space glyph gets created from the font's metrics data.
|
||||
This commit makes FreeType behave accordingly.
|
||||
|
||||
* include/freetype/fterrdef.h (FT_Err_Missing_Bitmap): New error
|
||||
code.
|
||||
|
||||
* src/sfnt/ttsbit.c (tt_sbit_decoder_load_image): Change error codes
|
||||
to make a distinction between a missing bitmap in a composite and a
|
||||
simple missing bitmap.
|
||||
|
||||
* src/truetype/ttgload.c (TT_Load_Glyph): For a missing bitmap (in a
|
||||
bitmap-only font), synthesize an empty bitmap glyph if metrics are
|
||||
available.
|
||||
|
||||
2017-08-10 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
[base] Minor API improvement for default variation axis setting.
|
||||
|
@ -233,6 +233,8 @@
|
||||
"invalid PostScript (post) table" )
|
||||
FT_ERRORDEF_( DEF_In_Glyf_Bytecode, 0x9C,
|
||||
"found FDEF or IDEF opcode in glyf bytecode" )
|
||||
FT_ERRORDEF_( Missing_Bitmap, 0x9D,
|
||||
"missing bitmap in strike" )
|
||||
|
||||
/* CFF, CID, and Type 1 errors */
|
||||
|
||||
|
@ -1448,10 +1448,17 @@
|
||||
return FT_THROW( Invalid_Table );
|
||||
|
||||
NoBitmap:
|
||||
if ( recurse_count )
|
||||
{
|
||||
FT_TRACE4(( "tt_sbit_decoder_load_image:"
|
||||
" missing subglyph sbit with glyph index %d\n",
|
||||
glyph_index ));
|
||||
return FT_THROW( Invalid_Composite );
|
||||
}
|
||||
|
||||
FT_TRACE4(( "tt_sbit_decoder_load_image:"
|
||||
" no sbit found for glyph index %d\n", glyph_index ));
|
||||
|
||||
return FT_THROW( Invalid_Argument );
|
||||
return FT_THROW( Missing_Bitmap );
|
||||
}
|
||||
|
||||
|
||||
|
@ -87,7 +87,7 @@
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Return the vertical metrics in font units for a given glyph. */
|
||||
/* See macro `TT_LOADER_SET_PP' below for explanations. */
|
||||
/* See function `tt_loader_set_pp' below for explanations. */
|
||||
/* */
|
||||
FT_LOCAL_DEF( void )
|
||||
TT_Get_VMetrics( TT_Face face,
|
||||
@ -2625,7 +2625,58 @@
|
||||
IS_DEFAULT_INSTANCE )
|
||||
{
|
||||
error = load_sbit_image( size, glyph, glyph_index, load_flags );
|
||||
if ( error )
|
||||
if ( FT_ERR_EQ( error, Missing_Bitmap ) )
|
||||
{
|
||||
/* the bitmap strike is incomplete and misses the requested glyph; */
|
||||
/* if we have a bitmap-only font, return an empty glyph */
|
||||
if ( !FT_IS_SCALABLE( glyph->face ) )
|
||||
{
|
||||
TT_Face face = (TT_Face)glyph->face;
|
||||
FT_Short left_bearing = 0, top_bearing = 0;
|
||||
FT_UShort advance_width = 0, advance_height = 0;
|
||||
|
||||
|
||||
/* to return an empty glyph, however, we need metrics data */
|
||||
/* from the `hmtx' (or `vmtx') table; the assumption is that */
|
||||
/* empty glyphs are missing intentionally, representing */
|
||||
/* whitespace - not having at least horizontal metrics is */
|
||||
/* thus considered an error */
|
||||
if ( !face->horz_metrics_size )
|
||||
return error;
|
||||
|
||||
/* we now construct an empty bitmap glyph */
|
||||
TT_Get_HMetrics( face, glyph_index,
|
||||
&left_bearing,
|
||||
&advance_width );
|
||||
TT_Get_VMetrics( face, glyph_index,
|
||||
0,
|
||||
&top_bearing,
|
||||
&advance_height );
|
||||
|
||||
glyph->outline.n_points = 0;
|
||||
glyph->outline.n_contours = 0;
|
||||
|
||||
glyph->metrics.width = 0;
|
||||
glyph->metrics.height = 0;
|
||||
|
||||
glyph->metrics.horiBearingX = left_bearing;
|
||||
glyph->metrics.horiBearingY = 0;
|
||||
glyph->metrics.horiAdvance = advance_width;
|
||||
|
||||
glyph->metrics.vertBearingX = 0;
|
||||
glyph->metrics.vertBearingY = top_bearing;
|
||||
glyph->metrics.vertAdvance = advance_height;
|
||||
|
||||
glyph->format = FT_GLYPH_FORMAT_BITMAP;
|
||||
glyph->bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
|
||||
|
||||
glyph->bitmap_left = 0;
|
||||
glyph->bitmap_top = 0;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
}
|
||||
else if ( error )
|
||||
{
|
||||
/* return error if font is not scalable */
|
||||
if ( !FT_IS_SCALABLE( glyph->face ) )
|
||||
|
Loading…
Reference in New Issue
Block a user