[truetype] Fix 'sbix' table handling.
* src/sfnt/ttsbit.c (tt_face_load_sbix_image): Correct calculation of 'metrics->horiBearingY'. Set vertical metrics. * src/sfnt/sfobjs.c (sfnt_load_face): Adjust setting of `FT_FACE_FLAG_SBIX`. Handle metrics of fonts with 'sbix' table. * src/truetype/ttgload.c (TT_Load_Glyph): For 'sbix' embedded bitmaps, apply bbox offset and bearing values of the corresponding glyph in the 'glyf' table if it exists and has a contour. * src/truetype/ttobjs.c (tt_face_init): Handle font with 'sbix' table. Fixes issue #998.
This commit is contained in:
parent
907715a6a2
commit
ac4c1ebf7e
|
@ -851,12 +851,6 @@
|
||||||
is_apple_sbit = 0;
|
is_apple_sbit = 0;
|
||||||
is_apple_sbix = !face->goto_table( face, TTAG_sbix, stream, 0 );
|
is_apple_sbix = !face->goto_table( face, TTAG_sbix, stream, 0 );
|
||||||
|
|
||||||
/* Apple 'sbix' color bitmaps are rendered scaled and then the 'glyf'
|
|
||||||
* outline rendered on top. We don't support that yet, so just ignore
|
|
||||||
* the 'glyf' outline and advertise it as a bitmap-only font. */
|
|
||||||
if ( is_apple_sbix )
|
|
||||||
has_outline = FALSE;
|
|
||||||
|
|
||||||
/* if this font doesn't contain outlines, we try to load */
|
/* if this font doesn't contain outlines, we try to load */
|
||||||
/* a `bhed' table */
|
/* a `bhed' table */
|
||||||
if ( !has_outline && sfnt->load_bhed )
|
if ( !has_outline && sfnt->load_bhed )
|
||||||
|
@ -1059,10 +1053,12 @@
|
||||||
|
|
||||||
if ( has_outline == TRUE )
|
if ( has_outline == TRUE )
|
||||||
{
|
{
|
||||||
|
/* by default (and for backward compatibility) we handle */
|
||||||
|
/* fonts with an 'sbix' table as bitmap-only */
|
||||||
|
if ( is_apple_sbix )
|
||||||
|
flags |= FT_FACE_FLAG_SBIX; /* with 'sbix' bitmaps */
|
||||||
|
else
|
||||||
flags |= FT_FACE_FLAG_SCALABLE; /* scalable outlines */
|
flags |= FT_FACE_FLAG_SCALABLE; /* scalable outlines */
|
||||||
|
|
||||||
if ( face->sbit_table_type == TT_SBIT_TABLE_TYPE_SBIX )
|
|
||||||
flags |= FT_FACE_FLAG_SBIX; /* and 'sbix' bitmaps */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The sfnt driver only supports bitmap fonts natively, thus we */
|
/* The sfnt driver only supports bitmap fonts natively, thus we */
|
||||||
|
@ -1286,7 +1282,8 @@
|
||||||
*
|
*
|
||||||
* Set up metrics.
|
* Set up metrics.
|
||||||
*/
|
*/
|
||||||
if ( FT_IS_SCALABLE( root ) )
|
if ( FT_IS_SCALABLE( root ) ||
|
||||||
|
FT_HAS_SBIX( root ) )
|
||||||
{
|
{
|
||||||
/* XXX What about if outline header is missing */
|
/* XXX What about if outline header is missing */
|
||||||
/* (e.g. sfnt wrapped bitmap)? */
|
/* (e.g. sfnt wrapped bitmap)? */
|
||||||
|
|
|
@ -1580,17 +1580,34 @@
|
||||||
|
|
||||||
if ( !error )
|
if ( !error )
|
||||||
{
|
{
|
||||||
FT_Short abearing;
|
FT_Short abearing; /* not used here */
|
||||||
FT_UShort aadvance;
|
FT_UShort aadvance;
|
||||||
|
|
||||||
|
|
||||||
tt_face_get_metrics( face, FALSE, glyph_index, &abearing, &aadvance );
|
tt_face_get_metrics( face, FALSE, glyph_index, &abearing, &aadvance );
|
||||||
|
|
||||||
metrics->horiBearingX = (FT_Short)originOffsetX;
|
metrics->horiBearingX = (FT_Short)originOffsetX;
|
||||||
metrics->horiBearingY = (FT_Short)( -originOffsetY + metrics->height );
|
metrics->vertBearingX = (FT_Short)originOffsetX;
|
||||||
|
|
||||||
|
metrics->horiBearingY = (FT_Short)( originOffsetY + metrics->height );
|
||||||
|
metrics->vertBearingY = (FT_Short)originOffsetY;
|
||||||
|
|
||||||
metrics->horiAdvance = (FT_UShort)( aadvance *
|
metrics->horiAdvance = (FT_UShort)( aadvance *
|
||||||
face->root.size->metrics.x_ppem /
|
face->root.size->metrics.x_ppem /
|
||||||
face->header.Units_Per_EM );
|
face->header.Units_Per_EM );
|
||||||
|
|
||||||
|
if ( face->vertical_info )
|
||||||
|
tt_face_get_metrics( face, TRUE, glyph_index, &abearing, &aadvance );
|
||||||
|
else if ( face->os2.version != 0xFFFFU )
|
||||||
|
aadvance = (FT_UShort)FT_ABS( face->os2.sTypoAscender -
|
||||||
|
face->os2.sTypoDescender );
|
||||||
|
else
|
||||||
|
aadvance = (FT_UShort)FT_ABS( face->horizontal.Ascender -
|
||||||
|
face->horizontal.Descender );
|
||||||
|
|
||||||
|
metrics->vertAdvance = (FT_UShort)( aadvance *
|
||||||
|
face->root.size->metrics.x_ppem /
|
||||||
|
face->header.Units_Per_EM );
|
||||||
}
|
}
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
|
|
|
@ -2897,8 +2897,12 @@
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( FT_IS_SCALABLE( glyph->face ) )
|
if ( FT_IS_SCALABLE( glyph->face ) ||
|
||||||
|
FT_HAS_SBIX( glyph->face ) )
|
||||||
{
|
{
|
||||||
|
TT_Face face = (TT_Face)glyph->face;
|
||||||
|
|
||||||
|
|
||||||
/* for the bbox we need the header only */
|
/* for the bbox we need the header only */
|
||||||
(void)tt_loader_init( &loader, size, glyph, load_flags, TRUE );
|
(void)tt_loader_init( &loader, size, glyph, load_flags, TRUE );
|
||||||
(void)load_truetype_glyph( &loader, glyph_index, 0, TRUE );
|
(void)load_truetype_glyph( &loader, glyph_index, 0, TRUE );
|
||||||
|
@ -2906,6 +2910,35 @@
|
||||||
glyph->linearHoriAdvance = loader.linear;
|
glyph->linearHoriAdvance = loader.linear;
|
||||||
glyph->linearVertAdvance = loader.vadvance;
|
glyph->linearVertAdvance = loader.vadvance;
|
||||||
|
|
||||||
|
/* Bitmaps from the 'sbix' table need special treatment: */
|
||||||
|
/* if there is a glyph contour, the bitmap origin must be */
|
||||||
|
/* shifted to be relative to the lower left corner of the */
|
||||||
|
/* glyph bounding box, also taking the left-side bearing */
|
||||||
|
/* (or top bearing) into account. */
|
||||||
|
if ( face->sbit_table_type == TT_SBIT_TABLE_TYPE_SBIX &&
|
||||||
|
loader.n_contours > 0 )
|
||||||
|
{
|
||||||
|
FT_Int bitmap_left;
|
||||||
|
FT_Int bitmap_top;
|
||||||
|
|
||||||
|
|
||||||
|
if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
|
||||||
|
{
|
||||||
|
/* This is a guess, since Apple's CoreText engine doesn't */
|
||||||
|
/* really do vertical typesetting. */
|
||||||
|
bitmap_left = loader.bbox.xMin;
|
||||||
|
bitmap_top = loader.top_bearing;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bitmap_left = loader.left_bearing;
|
||||||
|
bitmap_top = loader.bbox.yMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
glyph->bitmap_left += FT_MulFix( bitmap_left, x_scale ) >> 6;
|
||||||
|
glyph->bitmap_top += FT_MulFix( bitmap_top, y_scale ) >> 6;
|
||||||
|
}
|
||||||
|
|
||||||
/* sanity checks: if `xxxAdvance' in the sbit metric */
|
/* sanity checks: if `xxxAdvance' in the sbit metric */
|
||||||
/* structure isn't set, use `linearXXXAdvance' */
|
/* structure isn't set, use `linearXXXAdvance' */
|
||||||
if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance )
|
if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance )
|
||||||
|
|
|
@ -727,7 +727,8 @@
|
||||||
if ( error )
|
if ( error )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
if ( FT_IS_SCALABLE( ttface ) )
|
if ( FT_IS_SCALABLE( ttface ) ||
|
||||||
|
FT_HAS_SBIX( ttface ) )
|
||||||
{
|
{
|
||||||
#ifdef FT_CONFIG_OPTION_INCREMENTAL
|
#ifdef FT_CONFIG_OPTION_INCREMENTAL
|
||||||
if ( !ttface->internal->incremental_interface )
|
if ( !ttface->internal->incremental_interface )
|
||||||
|
|
Loading…
Reference in New Issue