[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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index 008962b..614ff68 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -851,12 +851,6 @@
is_apple_sbit = 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 */
/* a `bhed' table */
if ( !has_outline && sfnt->load_bhed )
@@ -1059,10 +1053,12 @@
if ( has_outline == TRUE )
{
- 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 */
+ /* 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 */
}
/* The sfnt driver only supports bitmap fonts natively, thus we */
@@ -1286,7 +1282,8 @@
*
* 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 */
/* (e.g. sfnt wrapped bitmap)? */
diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c
index 179e9cc..0ab6026 100644
--- a/src/sfnt/ttsbit.c
+++ b/src/sfnt/ttsbit.c
@@ -1580,17 +1580,34 @@
if ( !error )
{
- FT_Short abearing;
+ FT_Short abearing; /* not used here */
FT_UShort aadvance;
tt_face_get_metrics( face, FALSE, glyph_index, &abearing, &aadvance );
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 *
face->root.size->metrics.x_ppem /
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;
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index b19f7a2..b189f98 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -2897,8 +2897,12 @@
}
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 */
(void)tt_loader_init( &loader, size, glyph, load_flags, TRUE );
(void)load_truetype_glyph( &loader, glyph_index, 0, TRUE );
@@ -2906,6 +2910,35 @@
glyph->linearHoriAdvance = loader.linear;
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 */
/* structure isn't set, use `linearXXXAdvance' */
if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance )
diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c
index 9cb1af6..f4f3c69 100644
--- a/src/truetype/ttobjs.c
+++ b/src/truetype/ttobjs.c
@@ -727,7 +727,8 @@
if ( error )
goto Exit;
- if ( FT_IS_SCALABLE( ttface ) )
+ if ( FT_IS_SCALABLE( ttface ) ||
+ FT_HAS_SBIX( ttface ) )
{
#ifdef FT_CONFIG_OPTION_INCREMENTAL
if ( !ttface->internal->incremental_interface )