Werner Lemberg pushed to branch wl/sbix at FreeType / FreeType
Commits:
-
30d4dfd0
by Werner Lemberg at 2022-03-17T11:50:22+01:00
-
f9408f1f
by Werner Lemberg at 2022-03-17T11:51:19+01:00
-
f2092d0a
by Werner Lemberg at 2022-03-17T11:51:19+01:00
-
ad1b5676
by Werner Lemberg at 2022-03-17T11:51:19+01:00
-
21ca82be
by Werner Lemberg at 2022-03-17T11:51:19+01:00
8 changed files:
- include/freetype/freetype.h
- include/freetype/ftchapters.h
- include/freetype/ftdriver.h
- src/sfnt/sfdriver.c
- src/sfnt/sfobjs.c
- src/sfnt/sfobjs.h
- src/sfnt/ttsbit.c
- src/truetype/ttgload.c
Changes:
... | ... | @@ -154,6 +154,8 @@ FT_BEGIN_HEADER |
154 | 154 | * FT_FACE_FLAG_EXTERNAL_STREAM
|
155 | 155 | * FT_FACE_FLAG_HINTER
|
156 | 156 | * FT_FACE_FLAG_SVG
|
157 | + * FT_FACE_FLAG_SBIX
|
|
158 | + * FT_FACE_FLAG_SBIX_OVERLAY
|
|
157 | 159 | *
|
158 | 160 | * FT_HAS_HORIZONTAL
|
159 | 161 | * FT_HAS_VERTICAL
|
... | ... | @@ -163,6 +165,8 @@ FT_BEGIN_HEADER |
163 | 165 | * FT_HAS_COLOR
|
164 | 166 | * FT_HAS_MULTIPLE_MASTERS
|
165 | 167 | * FT_HAS_SVG
|
168 | + * FT_HAS_SBIX
|
|
169 | + * FT_HAS_SBIX_OVERLAY
|
|
166 | 170 | *
|
167 | 171 | * FT_IS_SFNT
|
168 | 172 | * FT_IS_SCALABLE
|
... | ... | @@ -227,6 +231,7 @@ FT_BEGIN_HEADER |
227 | 231 | * FT_LOAD_NO_SCALE
|
228 | 232 | * FT_LOAD_NO_HINTING
|
229 | 233 | * FT_LOAD_NO_BITMAP
|
234 | + * FT_LOAD_SBITS_ONLY
|
|
230 | 235 | * FT_LOAD_NO_AUTOHINT
|
231 | 236 | * FT_LOAD_COLOR
|
232 | 237 | *
|
... | ... | @@ -1235,6 +1240,14 @@ FT_BEGIN_HEADER |
1235 | 1240 | *
|
1236 | 1241 | * FT_FACE_FLAG_SVG ::
|
1237 | 1242 | * [Since 2.12] The face has an 'SVG~' OpenType table.
|
1243 | + *
|
|
1244 | + * FT_FACE_FLAG_SBIX ::
|
|
1245 | + * [Since 2.12] The face has an 'sbix' OpenType table.
|
|
1246 | + *
|
|
1247 | + * FT_FACE_FLAG_SBIX_OVERLAY ::
|
|
1248 | + * [Since 2.12] The face has an 'sbix' OpenType table where outlines
|
|
1249 | + * should be drawn on top of bitmap strikes.
|
|
1250 | + *
|
|
1238 | 1251 | */
|
1239 | 1252 | #define FT_FACE_FLAG_SCALABLE ( 1L << 0 )
|
1240 | 1253 | #define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 )
|
... | ... | @@ -1253,6 +1266,8 @@ FT_BEGIN_HEADER |
1253 | 1266 | #define FT_FACE_FLAG_COLOR ( 1L << 14 )
|
1254 | 1267 | #define FT_FACE_FLAG_VARIATION ( 1L << 15 )
|
1255 | 1268 | #define FT_FACE_FLAG_SVG ( 1L << 16 )
|
1269 | +#define FT_FACE_FLAG_SBIX ( 1L << 17 )
|
|
1270 | +#define FT_FACE_FLAG_SBIX_OVERLAY ( 1L << 18 )
|
|
1256 | 1271 | |
1257 | 1272 | |
1258 | 1273 | /**************************************************************************
|
... | ... | @@ -1509,6 +1524,92 @@ FT_BEGIN_HEADER |
1509 | 1524 | ( !!( (face)->face_flags & FT_FACE_FLAG_SVG ) )
|
1510 | 1525 | |
1511 | 1526 | |
1527 | + /**************************************************************************
|
|
1528 | + *
|
|
1529 | + * @macro:
|
|
1530 | + * FT_HAS_SBIX
|
|
1531 | + *
|
|
1532 | + * @description:
|
|
1533 | + * A macro that returns true whenever a face object contains an 'sbix'
|
|
1534 | + * OpenType table.
|
|
1535 | + *
|
|
1536 | + * Currently, FreeType only supports bitmap glyphs in PNG format (i.e.,
|
|
1537 | + * JPEG and TIFF formats are unsupported, as are Apple-specific formats
|
|
1538 | + * not part of the OpenType specification).
|
|
1539 | + *
|
|
1540 | + * @note:
|
|
1541 | + * Here is some pseudo code that roughly illustrates how to implement
|
|
1542 | + * 'sbix' handling according to the OpenType specification.
|
|
1543 | + *
|
|
1544 | + * ```
|
|
1545 | + * if ( FT_HAS_SBIX( face ) )
|
|
1546 | + * {
|
|
1547 | + * <sort `face->available_size` as necessary into
|
|
1548 | + * `preferred_sizes`[*]>
|
|
1549 | + *
|
|
1550 | + * for ( i = 0; i < face->num_fixed_sizes; i++ )
|
|
1551 | + * {
|
|
1552 | + * size = preferred_sizes[i].size;
|
|
1553 | + *
|
|
1554 | + * error = FT_Set_Pixel_Sizes( face, size, size );
|
|
1555 | + * <error handling omitted>
|
|
1556 | + *
|
|
1557 | + * // check whether we have a glyph in a bitmap strike
|
|
1558 | + * error = FT_Load_Glyph( face,
|
|
1559 | + * glyph_index,
|
|
1560 | + * FT_LOAD_SBITS_ONLY |
|
|
1561 | + * FT_LOAD_BITMAP_METRICS_ONLY )
|
|
1562 | + * if ( error == FT_Err_Invalid_Argument )
|
|
1563 | + * continue;
|
|
1564 | + * else if ( error )
|
|
1565 | + * <other error handling omitted>
|
|
1566 | + * else
|
|
1567 | + * break;
|
|
1568 | + * }
|
|
1569 | + *
|
|
1570 | + * if ( i != face->num_fixed_sizes )
|
|
1571 | + * <load embedded bitmap with `FT_Load_Glyph`,
|
|
1572 | + * scale it, display it, etc.>
|
|
1573 | + *
|
|
1574 | + * if ( i == face->num_fixed_sizes ||
|
|
1575 | + * FT_HAS_SBIX_OVERLAY( face ) )
|
|
1576 | + * <load outline glyph with `FT_Load_Glyph`,
|
|
1577 | + * scale it, display it, etc.>
|
|
1578 | + * }
|
|
1579 | + * ```
|
|
1580 | + *
|
|
1581 | + * [*] Assuming a target value of 400dpi and available strike sizes 100,
|
|
1582 | + * 200, 300, and 400dpi, a possible order might be [400, 200, 300, 100]:
|
|
1583 | + * scaling 200dpi to 400dpi usually gives better results than scaling
|
|
1584 | + * 300dpi to 400dpi; it is also much faster. However, scaling 100dpi to
|
|
1585 | + * 400dpi can yield a too pixelated result, thus the preference might be
|
|
1586 | + * 300dpi over 100dpi.
|
|
1587 | + *
|
|
1588 | + * @since:
|
|
1589 | + * 2.12
|
|
1590 | + */
|
|
1591 | +#define FT_HAS_SBIX( face ) \
|
|
1592 | + ( !!( (face)->face_flags & FT_FACE_FLAG_SBIX ) )
|
|
1593 | + |
|
1594 | + |
|
1595 | + /**************************************************************************
|
|
1596 | + *
|
|
1597 | + * @macro:
|
|
1598 | + * FT_HAS_SBIX_OVERLAY
|
|
1599 | + *
|
|
1600 | + * @description:
|
|
1601 | + * A macro that returns true whenever a face object contains an 'sbix'
|
|
1602 | + * OpenType table with bit~1 in its `flags` field set, instructing the
|
|
1603 | + * application to overlay the bitmap strike with the corresponding
|
|
1604 | + * outline glyph. See @FT_HAS_SBIX for pseudo code how to use it.
|
|
1605 | + *
|
|
1606 | + * @since:
|
|
1607 | + * 2.12
|
|
1608 | + */
|
|
1609 | +#define FT_HAS_SBIX_OVERLAY( face ) \
|
|
1610 | + ( !!( (face)->face_flags & FT_FACE_FLAG_SBIX_OVERLAY ) )
|
|
1611 | + |
|
1612 | + |
|
1512 | 1613 | /**************************************************************************
|
1513 | 1614 | *
|
1514 | 1615 | * @enum:
|
... | ... | @@ -2976,6 +3077,15 @@ FT_BEGIN_HEADER |
2976 | 3077 | *
|
2977 | 3078 | * @FT_LOAD_NO_SCALE always sets this flag.
|
2978 | 3079 | *
|
3080 | + * FT_LOAD_SBITS_ONLY ::
|
|
3081 | + * [Since 2.12] This is the opposite of @FT_LOAD_NO_BITMAP, more or
|
|
3082 | + * less: @FT_Load_Glyph returns `FT_Err_Invalid_Argument` if the face
|
|
3083 | + * contains a bitmap strike for the given size (or the strike selected
|
|
3084 | + * by @FT_Select_Size) but there is no glyph in the strike.
|
|
3085 | + *
|
|
3086 | + * Note that this load flag was part of FreeType since version 2.0.6
|
|
3087 | + * but previously tagged as internal.
|
|
3088 | + *
|
|
2979 | 3089 | * FT_LOAD_VERTICAL_LAYOUT ::
|
2980 | 3090 | * Load the glyph for vertical text layout. In particular, the
|
2981 | 3091 | * `advance` value in the @FT_GlyphSlotRec structure is set to the
|
... | ... | @@ -3120,6 +3230,7 @@ FT_BEGIN_HEADER |
3120 | 3230 | #define FT_LOAD_IGNORE_TRANSFORM ( 1L << 11 )
|
3121 | 3231 | #define FT_LOAD_MONOCHROME ( 1L << 12 )
|
3122 | 3232 | #define FT_LOAD_LINEAR_DESIGN ( 1L << 13 )
|
3233 | +#define FT_LOAD_SBITS_ONLY ( 1L << 14 )
|
|
3123 | 3234 | #define FT_LOAD_NO_AUTOHINT ( 1L << 15 )
|
3124 | 3235 | /* Bits 16-19 are used by `FT_LOAD_TARGET_` */
|
3125 | 3236 | #define FT_LOAD_COLOR ( 1L << 20 )
|
... | ... | @@ -3130,7 +3241,6 @@ FT_BEGIN_HEADER |
3130 | 3241 | |
3131 | 3242 | /* used internally only by certain font drivers */
|
3132 | 3243 | #define FT_LOAD_ADVANCE_ONLY ( 1L << 8 )
|
3133 | -#define FT_LOAD_SBITS_ONLY ( 1L << 14 )
|
|
3134 | 3244 | #define FT_LOAD_SVG_ONLY ( 1L << 23 )
|
3135 | 3245 | |
3136 | 3246 |
... | ... | @@ -80,10 +80,11 @@ |
80 | 80 | * @sections:
|
81 | 81 | * auto_hinter
|
82 | 82 | * cff_driver
|
83 | - * t1_cid_driver
|
|
84 | - * tt_driver
|
|
85 | - * pcf_driver
|
|
86 | 83 | * ot_svg_driver
|
84 | + * pcf_driver
|
|
85 | + * sfnt_driver
|
|
86 | + * tt_driver
|
|
87 | + * t1_cid_driver
|
|
87 | 88 | * properties
|
88 | 89 | * parameter_tags
|
89 | 90 | * lcd_rendering
|
... | ... | @@ -198,6 +198,29 @@ FT_BEGIN_HEADER |
198 | 198 | */
|
199 | 199 | |
200 | 200 | |
201 | + /**************************************************************************
|
|
202 | + *
|
|
203 | + * @section:
|
|
204 | + * sfnt_driver
|
|
205 | + *
|
|
206 | + * @title:
|
|
207 | + * The SFNT driver
|
|
208 | + *
|
|
209 | + * @abstract:
|
|
210 | + * Controlling the SFNT driver module.
|
|
211 | + *
|
|
212 | + * @description:
|
|
213 | + * It is possible to control the behaviour of FreeType's SFNT driver
|
|
214 | + * (which handles the basic infrastructure for OpenType fonts) with
|
|
215 | + * @FT_Property_Set and @FT_Property_Get.
|
|
216 | + *
|
|
217 | + * The SFNT driver's module name is 'sfnt'; a single property
|
|
218 | + * @sbix-not-scalable is available, as documented in the @properties
|
|
219 | + * section.
|
|
220 | + *
|
|
221 | + */
|
|
222 | + |
|
223 | + |
|
201 | 224 | /**************************************************************************
|
202 | 225 | *
|
203 | 226 | * @section:
|
... | ... | @@ -633,6 +656,42 @@ FT_BEGIN_HEADER |
633 | 656 | */
|
634 | 657 | |
635 | 658 | |
659 | + /**************************************************************************
|
|
660 | + *
|
|
661 | + * @property:
|
|
662 | + * sbix-not-scalable
|
|
663 | + *
|
|
664 | + * @description:
|
|
665 | + * The 'sbix' table provides data for bitmap fonts. It can interact with
|
|
666 | + * outline glyphs, making it necessary to tag the font as scalable in
|
|
667 | + * this case. Older versions of FreeType, however, didn't implement this
|
|
668 | + * interaction and always tagged fonts with an 'sbix' table as
|
|
669 | + * non-scalable.
|
|
670 | + *
|
|
671 | + * If this property is set, FreeType's old behaviour gets activated, that
|
|
672 | + * is, don't set @FT_FACE_FLAG_SCALABLE and don't look at outline glyphs.
|
|
673 | + *
|
|
674 | + * @note:
|
|
675 | + * This property can be used with @FT_Property_Get also.
|
|
676 | + *
|
|
677 | + * @example:
|
|
678 | + * ```
|
|
679 | + * FT_Library library;
|
|
680 | + * FT_Bool sbix_not_scalable = TRUE;
|
|
681 | + *
|
|
682 | + *
|
|
683 | + * FT_Init_FreeType( &library );
|
|
684 | + *
|
|
685 | + * FT_Property_Set( library, "sfnt",
|
|
686 | + * "sbix-not-scalable",
|
|
687 | + * &sbix_not_scalable );
|
|
688 | + * ```
|
|
689 | + *
|
|
690 | + * @since:
|
|
691 | + * 2.12
|
|
692 | + */
|
|
693 | + |
|
694 | + |
|
636 | 695 | /**************************************************************************
|
637 | 696 | *
|
638 | 697 | * @enum:
|
... | ... | @@ -55,6 +55,7 @@ |
55 | 55 | |
56 | 56 | #include <freetype/internal/services/svgldict.h>
|
57 | 57 | #include <freetype/internal/services/svpostnm.h>
|
58 | +#include <freetype/internal/services/svprop.h>
|
|
58 | 59 | #include <freetype/internal/services/svsfnt.h>
|
59 | 60 | #include <freetype/internal/services/svttcmap.h>
|
60 | 61 | |
... | ... | @@ -74,6 +75,98 @@ |
74 | 75 | #define FT_COMPONENT sfdriver
|
75 | 76 | |
76 | 77 | |
78 | + /*
|
|
79 | + * PROPERTY SERVICE
|
|
80 | + *
|
|
81 | + */
|
|
82 | + static FT_Error
|
|
83 | + sfnt_property_set( FT_Module module, /* SFNT_Driver */
|
|
84 | + const char* property_name,
|
|
85 | + const void* value,
|
|
86 | + FT_Bool value_is_string )
|
|
87 | + {
|
|
88 | +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
|
|
89 | + |
|
90 | + FT_Error error = FT_Err_Ok;
|
|
91 | + SFNT_Driver driver = (SFNT_Driver)module;
|
|
92 | + |
|
93 | + |
|
94 | + if ( !ft_strcmp( property_name, "sbix-not-scalable" ) )
|
|
95 | + {
|
|
96 | + FT_Bool* sbix_not_scalable = (FT_Bool*)value;
|
|
97 | + |
|
98 | + |
|
99 | + if ( value_is_string == TRUE )
|
|
100 | + {
|
|
101 | + error = FT_THROW( Invalid_Argument );
|
|
102 | + goto Exit;
|
|
103 | + }
|
|
104 | + |
|
105 | + driver->sbix_not_scalable = *sbix_not_scalable;
|
|
106 | + }
|
|
107 | + else
|
|
108 | + error = FT_THROW( Missing_Property );
|
|
109 | + |
|
110 | + Exit:
|
|
111 | + return error;
|
|
112 | + |
|
113 | +#else /* !TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
|
|
114 | + |
|
115 | + FT_UNUSED( module );
|
|
116 | + FT_UNUSED( property_name );
|
|
117 | + FT_UNUSED( value );
|
|
118 | + FT_UNUSED( value_is_string );
|
|
119 | + |
|
120 | + return FT_THROW( Missing_Property );
|
|
121 | + |
|
122 | +#endif /* !TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
|
|
123 | + }
|
|
124 | + |
|
125 | + |
|
126 | + static FT_Error
|
|
127 | + sfnt_property_get( FT_Module module, /* SFNT_Driver */
|
|
128 | + const char* property_name,
|
|
129 | + const void* value )
|
|
130 | + {
|
|
131 | +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
|
|
132 | + |
|
133 | + FT_Error error = FT_Err_Ok;
|
|
134 | + SFNT_Driver driver = (SFNT_Driver)module;
|
|
135 | + |
|
136 | + |
|
137 | + if ( !ft_strcmp( property_name, "sbix-not-scalable" ) )
|
|
138 | + {
|
|
139 | + FT_Bool sbix_not_scalable = driver->sbix_not_scalable;
|
|
140 | + FT_Bool* val = (FT_Bool*)value;
|
|
141 | + |
|
142 | + |
|
143 | + *val = sbix_not_scalable;
|
|
144 | + }
|
|
145 | + else
|
|
146 | + error = FT_THROW( Missing_Property );
|
|
147 | + |
|
148 | + return error;
|
|
149 | + |
|
150 | +#else /* !TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
|
|
151 | + |
|
152 | + FT_UNUSED( module );
|
|
153 | + FT_UNUSED( property_name );
|
|
154 | + FT_UNUSED( value );
|
|
155 | + |
|
156 | + return FT_THROW( Missing_Property );
|
|
157 | + |
|
158 | +#endif /* !TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
|
|
159 | + }
|
|
160 | + |
|
161 | + |
|
162 | + FT_DEFINE_SERVICE_PROPERTIESREC(
|
|
163 | + sfnt_service_properties,
|
|
164 | + |
|
165 | + (FT_Properties_SetFunc)sfnt_property_set, /* set_property */
|
|
166 | + (FT_Properties_GetFunc)sfnt_property_get /* get_property */
|
|
167 | + )
|
|
168 | + |
|
169 | + |
|
77 | 170 | /*
|
78 | 171 | * SFNT TABLE SERVICE
|
79 | 172 | *
|
... | ... | @@ -1158,37 +1251,41 @@ |
1158 | 1251 | */
|
1159 | 1252 | |
1160 | 1253 | #if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF
|
1161 | - FT_DEFINE_SERVICEDESCREC5(
|
|
1254 | + FT_DEFINE_SERVICEDESCREC6(
|
|
1162 | 1255 | sfnt_services,
|
1163 | 1256 | |
1164 | 1257 | FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table,
|
1165 | 1258 | FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name,
|
1166 | 1259 | FT_SERVICE_ID_GLYPH_DICT, &sfnt_service_glyph_dict,
|
1167 | 1260 | FT_SERVICE_ID_BDF, &sfnt_service_bdf,
|
1168 | - FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info )
|
|
1261 | + FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info,
|
|
1262 | + FT_SERVICE_ID_PROPERTIES, &sfnt_service_properties )
|
|
1169 | 1263 | #elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES
|
1170 | - FT_DEFINE_SERVICEDESCREC4(
|
|
1264 | + FT_DEFINE_SERVICEDESCREC5(
|
|
1171 | 1265 | sfnt_services,
|
1172 | 1266 | |
1173 | 1267 | FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table,
|
1174 | 1268 | FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name,
|
1175 | 1269 | FT_SERVICE_ID_GLYPH_DICT, &sfnt_service_glyph_dict,
|
1176 | - FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info )
|
|
1270 | + FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info,
|
|
1271 | + FT_SERVICE_ID_PROPERTIES, &sfnt_service_properties )
|
|
1177 | 1272 | #elif defined TT_CONFIG_OPTION_BDF
|
1178 | - FT_DEFINE_SERVICEDESCREC4(
|
|
1273 | + FT_DEFINE_SERVICEDESCREC5(
|
|
1179 | 1274 | sfnt_services,
|
1180 | 1275 | |
1181 | 1276 | FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table,
|
1182 | 1277 | FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name,
|
1183 | 1278 | FT_SERVICE_ID_BDF, &sfnt_service_bdf,
|
1184 | - FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info )
|
|
1279 | + FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info,
|
|
1280 | + FT_SERVICE_ID_PROPERTIES, &sfnt_service_properties )
|
|
1185 | 1281 | #else
|
1186 | - FT_DEFINE_SERVICEDESCREC3(
|
|
1282 | + FT_DEFINE_SERVICEDESCREC4(
|
|
1187 | 1283 | sfnt_services,
|
1188 | 1284 | |
1189 | 1285 | FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table,
|
1190 | 1286 | FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name,
|
1191 | - FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info )
|
|
1287 | + FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info,
|
|
1288 | + FT_SERVICE_ID_PROPERTIES, &sfnt_service_properties )
|
|
1192 | 1289 | #endif
|
1193 | 1290 | |
1194 | 1291 | |
... | ... | @@ -1329,7 +1426,7 @@ |
1329 | 1426 | sfnt_module_class,
|
1330 | 1427 | |
1331 | 1428 | 0, /* not a font driver or renderer */
|
1332 | - sizeof ( FT_ModuleRec ),
|
|
1429 | + sizeof ( SFNT_DriverRec ),
|
|
1333 | 1430 | |
1334 | 1431 | "sfnt", /* driver name */
|
1335 | 1432 | 0x10000L, /* driver version 1.0 */
|
... | ... | @@ -851,11 +851,13 @@ |
851 | 851 | is_apple_sbit = 0;
|
852 | 852 | is_apple_sbix = !face->goto_table( face, TTAG_sbix, stream, 0 );
|
853 | 853 | |
854 | - /* Apple 'sbix' color bitmaps are rendered scaled and then the 'glyf'
|
|
855 | - * outline rendered on top. We don't support that yet, so just ignore
|
|
856 | - * the 'glyf' outline and advertise it as a bitmap-only font. */
|
|
857 | - if ( is_apple_sbix )
|
|
854 | +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
|
|
855 | + /* This is for backwards compatibility, also making FreeType */
|
|
856 | + /* ignore outline glyph bounding boxes to adjust the positions */
|
|
857 | + /* of 'sbix' bitmaps. */
|
|
858 | + if ( ((SFNT_Driver)FT_FACE_DRIVER( face ))->sbix_not_scalable )
|
|
858 | 859 | has_outline = FALSE;
|
860 | +#endif
|
|
859 | 861 | |
860 | 862 | /* if this font doesn't contain outlines, we try to load */
|
861 | 863 | /* a `bhed' table */
|
... | ... | @@ -1057,6 +1059,9 @@ |
1057 | 1059 | face->colr )
|
1058 | 1060 | flags |= FT_FACE_FLAG_COLOR; /* color glyphs */
|
1059 | 1061 | |
1062 | + if ( face->sbit_table_type == TT_SBIT_TABLE_TYPE_SBIX )
|
|
1063 | + flags |= FT_FACE_FLAG_SBIX; /* has 'sbix' embedded bitmaps */
|
|
1064 | + |
|
1060 | 1065 | if ( has_outline == TRUE )
|
1061 | 1066 | flags |= FT_FACE_FLAG_SCALABLE; /* scalable outlines */
|
1062 | 1067 |
... | ... | @@ -27,6 +27,19 @@ |
27 | 27 | FT_BEGIN_HEADER
|
28 | 28 | |
29 | 29 | |
30 | + typedef struct SFNT_DriverRec_
|
|
31 | + {
|
|
32 | + FT_DriverRec root;
|
|
33 | + |
|
34 | +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
|
|
35 | + FT_Bool sbix_not_scalable; /* for backward compatibility */
|
|
36 | +#endif
|
|
37 | + |
|
38 | + } SFNT_DriverRec;
|
|
39 | + |
|
40 | + typedef struct SFNT_DriverRec_* SFNT_Driver;
|
|
41 | + |
|
42 | + |
|
30 | 43 | FT_LOCAL( FT_Error )
|
31 | 44 | sfnt_init_face( FT_Stream stream,
|
32 | 45 | TT_Face face,
|
... | ... | @@ -172,17 +172,8 @@ |
172 | 172 | goto Exit;
|
173 | 173 | }
|
174 | 174 | |
175 | -#ifdef FT_DEBUG_LEVEL_TRACE
|
|
176 | - /* we currently don't support bit 1; however, it is better to */
|
|
177 | - /* draw at least something... */
|
|
178 | 175 | if ( flags == 3 )
|
179 | - {
|
|
180 | - FT_TRACE1(( "tt_face_load_sbit_strikes:"
|
|
181 | - " sbix overlay not supported yet\n" ));
|
|
182 | - FT_TRACE1(( " "
|
|
183 | - " expect bad rendering results\n" ));
|
|
184 | - }
|
|
185 | -#endif
|
|
176 | + face->root.face_flags |= FT_FACE_FLAG_SBIX_OVERLAY;
|
|
186 | 177 | |
187 | 178 | /*
|
188 | 179 | * Count the number of strikes available in the table. We are a bit
|
... | ... | @@ -1580,17 +1571,34 @@ |
1580 | 1571 | |
1581 | 1572 | if ( !error )
|
1582 | 1573 | {
|
1583 | - FT_Short abearing;
|
|
1574 | + FT_Short abearing; /* not used here */
|
|
1584 | 1575 | FT_UShort aadvance;
|
1585 | 1576 | |
1586 | 1577 | |
1587 | 1578 | tt_face_get_metrics( face, FALSE, glyph_index, &abearing, &aadvance );
|
1588 | 1579 | |
1589 | 1580 | metrics->horiBearingX = (FT_Short)originOffsetX;
|
1590 | - metrics->horiBearingY = (FT_Short)( -originOffsetY + metrics->height );
|
|
1581 | + metrics->vertBearingX = (FT_Short)originOffsetX;
|
|
1582 | + |
|
1583 | + metrics->horiBearingY = (FT_Short)( originOffsetY + metrics->height );
|
|
1584 | + metrics->vertBearingY = (FT_Short)originOffsetY;
|
|
1585 | + |
|
1591 | 1586 | metrics->horiAdvance = (FT_UShort)( aadvance *
|
1592 | 1587 | face->root.size->metrics.x_ppem /
|
1593 | 1588 | face->header.Units_Per_EM );
|
1589 | + |
|
1590 | + if ( face->vertical_info )
|
|
1591 | + tt_face_get_metrics( face, TRUE, glyph_index, &abearing, &aadvance );
|
|
1592 | + else if ( face->os2.version != 0xFFFFU )
|
|
1593 | + aadvance = (FT_UShort)FT_ABS( face->os2.sTypoAscender -
|
|
1594 | + face->os2.sTypoDescender );
|
|
1595 | + else
|
|
1596 | + aadvance = (FT_UShort)FT_ABS( face->horizontal.Ascender -
|
|
1597 | + face->horizontal.Descender );
|
|
1598 | + |
|
1599 | + metrics->vertAdvance = (FT_UShort)( aadvance *
|
|
1600 | + face->root.size->metrics.x_ppem /
|
|
1601 | + face->header.Units_Per_EM );
|
|
1594 | 1602 | }
|
1595 | 1603 | |
1596 | 1604 | return error;
|
... | ... | @@ -2899,6 +2899,9 @@ |
2899 | 2899 | {
|
2900 | 2900 | if ( FT_IS_SCALABLE( glyph->face ) )
|
2901 | 2901 | {
|
2902 | + TT_Face face = (TT_Face)glyph->face;
|
|
2903 | + |
|
2904 | + |
|
2902 | 2905 | /* for the bbox we need the header only */
|
2903 | 2906 | (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE );
|
2904 | 2907 | (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE );
|
... | ... | @@ -2906,6 +2909,35 @@ |
2906 | 2909 | glyph->linearHoriAdvance = loader.linear;
|
2907 | 2910 | glyph->linearVertAdvance = loader.vadvance;
|
2908 | 2911 | |
2912 | + /* bitmaps from the `sbix' table need special treatment: */
|
|
2913 | + /* if there is a glyph contour, the bitmap origin must be */
|
|
2914 | + /* shifted to be relative to the lower left corner of the */
|
|
2915 | + /* glyph bounding box, also taking the left-side bearing */
|
|
2916 | + /* (or top bearing) into account */
|
|
2917 | + if ( face->sbit_table_type == TT_SBIT_TABLE_TYPE_SBIX &&
|
|
2918 | + loader.n_contours > 0 )
|
|
2919 | + {
|
|
2920 | + FT_Int bitmap_left;
|
|
2921 | + FT_Int bitmap_top;
|
|
2922 | + |
|
2923 | + |
|
2924 | + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
|
|
2925 | + {
|
|
2926 | + /* This is a guess, since Apple's CoreText engine doesn't */
|
|
2927 | + /* really do vertical typesetting. */
|
|
2928 | + bitmap_left = loader.bbox.xMin;
|
|
2929 | + bitmap_top = loader.top_bearing;
|
|
2930 | + }
|
|
2931 | + else
|
|
2932 | + {
|
|
2933 | + bitmap_left = loader.left_bearing;
|
|
2934 | + bitmap_top = loader.bbox.yMin;
|
|
2935 | + }
|
|
2936 | + |
|
2937 | + glyph->bitmap_left += FT_MulFix( bitmap_left, x_scale ) >> 6;
|
|
2938 | + glyph->bitmap_top += FT_MulFix( bitmap_top, y_scale ) >> 6;
|
|
2939 | + }
|
|
2940 | + |
|
2909 | 2941 | /* sanity checks: if `xxxAdvance' in the sbit metric */
|
2910 | 2942 | /* structure isn't set, use `linearXXXAdvance' */
|
2911 | 2943 | if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance )
|