OLD | NEW |
1 /***************************************************************************/ | 1 /***************************************************************************/ |
2 /* */ | 2 /* */ |
3 /* ttsbit.c */ | 3 /* ttsbit.c */ |
4 /* */ | 4 /* */ |
5 /* TrueType and OpenType embedded bitmap support (body). */ | 5 /* TrueType and OpenType embedded bitmap support (body). */ |
6 /* */ | 6 /* */ |
7 /* Copyright 2005-2009, 2013 by */ | 7 /* Copyright 2005-2009, 2013, 2014 by */ |
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ | 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
9 /* */ | 9 /* */ |
10 /* Copyright 2013 by Google, Inc. */ | 10 /* Copyright 2013 by Google, Inc. */ |
11 /* Google Author(s): Behdad Esfahbod. */ | 11 /* Google Author(s): Behdad Esfahbod. */ |
12 /* */ | 12 /* */ |
13 /* This file is part of the FreeType project, and may only be used, */ | 13 /* This file is part of the FreeType project, and may only be used, */ |
14 /* modified, and distributed under the terms of the FreeType project */ | 14 /* modified, and distributed under the terms of the FreeType project */ |
15 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ | 15 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
16 /* this file you indicate that you have read the license and */ | 16 /* this file you indicate that you have read the license and */ |
17 /* understand and accept it fully. */ | 17 /* understand and accept it fully. */ |
18 /* */ | 18 /* */ |
19 /***************************************************************************/ | 19 /***************************************************************************/ |
20 | 20 |
21 | 21 |
22 #include "../../include/ft2build.h" | 22 #include <ft2build.h> |
23 #include "../../include/freetype/internal/ftdebug.h" | 23 #include FT_INTERNAL_DEBUG_H |
24 #include "../../include/freetype/internal/ftstream.h" | 24 #include FT_INTERNAL_STREAM_H |
25 #include "../../include/freetype/tttags.h" | 25 #include FT_TRUETYPE_TAGS_H |
26 #include "../../include/freetype/ftbitmap.h" | 26 #include FT_BITMAP_H |
27 #include "ttsbit.h" | 27 #include "ttsbit.h" |
28 | 28 |
29 #include "sferrors.h" | 29 #include "sferrors.h" |
30 | 30 |
| 31 #include "ttmtx.h" |
31 #include "pngshim.h" | 32 #include "pngshim.h" |
32 | 33 |
33 | 34 |
34 /*************************************************************************/ | 35 /*************************************************************************/ |
35 /* */ | 36 /* */ |
36 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ | 37 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
37 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ | 38 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ |
38 /* messages during execution. */ | 39 /* messages during execution. */ |
39 /* */ | 40 /* */ |
40 #undef FT_COMPONENT | 41 #undef FT_COMPONENT |
41 #define FT_COMPONENT trace_ttsbit | 42 #define FT_COMPONENT trace_ttsbit |
42 | 43 |
43 | 44 |
44 FT_LOCAL_DEF( FT_Error ) | 45 FT_LOCAL_DEF( FT_Error ) |
45 tt_face_load_eblc( TT_Face face, | 46 tt_face_load_sbit( TT_Face face, |
46 FT_Stream stream ) | 47 FT_Stream stream ) |
47 { | 48 { |
48 FT_Error error = FT_Err_Ok; | 49 FT_Error error; |
49 FT_Fixed version; | 50 FT_ULong table_size; |
50 FT_ULong num_strikes, table_size; | |
51 FT_Byte* p; | |
52 FT_Byte* p_limit; | |
53 FT_UInt count; | |
54 | 51 |
55 | 52 |
| 53 face->sbit_table = NULL; |
| 54 face->sbit_table_size = 0; |
| 55 face->sbit_table_type = TT_SBIT_TABLE_TYPE_NONE; |
56 face->sbit_num_strikes = 0; | 56 face->sbit_num_strikes = 0; |
57 | 57 |
58 /* this table is optional */ | |
59 error = face->goto_table( face, TTAG_CBLC, stream, &table_size ); | 58 error = face->goto_table( face, TTAG_CBLC, stream, &table_size ); |
| 59 if ( !error ) |
| 60 face->sbit_table_type = TT_SBIT_TABLE_TYPE_CBLC; |
| 61 else |
| 62 { |
| 63 error = face->goto_table( face, TTAG_EBLC, stream, &table_size ); |
| 64 if ( error ) |
| 65 error = face->goto_table( face, TTAG_bloc, stream, &table_size ); |
| 66 if ( !error ) |
| 67 face->sbit_table_type = TT_SBIT_TABLE_TYPE_EBLC; |
| 68 } |
| 69 |
60 if ( error ) | 70 if ( error ) |
61 error = face->goto_table( face, TTAG_EBLC, stream, &table_size ); | 71 { |
62 if ( error ) | 72 error = face->goto_table( face, TTAG_sbix, stream, &table_size ); |
63 error = face->goto_table( face, TTAG_bloc, stream, &table_size ); | 73 if ( !error ) |
| 74 face->sbit_table_type = TT_SBIT_TABLE_TYPE_SBIX; |
| 75 } |
64 if ( error ) | 76 if ( error ) |
65 goto Exit; | 77 goto Exit; |
66 | 78 |
67 if ( table_size < 8 ) | 79 if ( table_size < 8 ) |
68 { | 80 { |
69 FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" )); | 81 FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" )); |
70 error = FT_THROW( Invalid_File_Format ); | 82 error = FT_THROW( Invalid_File_Format ); |
71 goto Exit; | 83 goto Exit; |
72 } | 84 } |
73 | 85 |
74 if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) ) | 86 switch ( (FT_UInt)face->sbit_table_type ) |
75 goto Exit; | 87 { |
| 88 case TT_SBIT_TABLE_TYPE_EBLC: |
| 89 case TT_SBIT_TABLE_TYPE_CBLC: |
| 90 { |
| 91 FT_Byte* p; |
| 92 FT_Fixed version; |
| 93 FT_ULong num_strikes; |
| 94 FT_UInt count; |
76 | 95 |
77 face->sbit_table_size = table_size; | |
78 | 96 |
79 p = face->sbit_table; | 97 if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) ) |
80 p_limit = p + table_size; | 98 goto Exit; |
81 | 99 |
82 version = FT_NEXT_ULONG( p ); | 100 face->sbit_table_size = table_size; |
83 num_strikes = FT_NEXT_ULONG( p ); | |
84 | 101 |
85 if ( version != 0x00020000UL || num_strikes >= 0x10000UL ) | 102 p = face->sbit_table; |
86 { | 103 |
87 FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" )); | 104 version = FT_NEXT_ULONG( p ); |
88 error = FT_THROW( Invalid_File_Format ); | 105 num_strikes = FT_NEXT_ULONG( p ); |
89 goto Fail; | 106 |
| 107 if ( ( version & 0xFFFF0000UL ) != 0x00020000UL ) |
| 108 { |
| 109 error = FT_THROW( Unknown_File_Format ); |
| 110 goto Exit; |
| 111 } |
| 112 |
| 113 if ( num_strikes >= 0x10000UL ) |
| 114 { |
| 115 error = FT_THROW( Invalid_File_Format ); |
| 116 goto Exit; |
| 117 } |
| 118 |
| 119 /* |
| 120 * Count the number of strikes available in the table. We are a bit |
| 121 * paranoid there and don't trust the data. |
| 122 */ |
| 123 count = (FT_UInt)num_strikes; |
| 124 if ( 8 + 48UL * count > table_size ) |
| 125 count = (FT_UInt)( ( table_size - 8 ) / 48 ); |
| 126 |
| 127 face->sbit_num_strikes = count; |
| 128 } |
| 129 break; |
| 130 |
| 131 case TT_SBIT_TABLE_TYPE_SBIX: |
| 132 { |
| 133 FT_UShort version; |
| 134 FT_UShort flags; |
| 135 FT_ULong num_strikes; |
| 136 FT_UInt count; |
| 137 |
| 138 |
| 139 if ( FT_FRAME_ENTER( 8 ) ) |
| 140 goto Exit; |
| 141 |
| 142 version = FT_GET_USHORT(); |
| 143 flags = FT_GET_USHORT(); |
| 144 num_strikes = FT_GET_ULONG(); |
| 145 |
| 146 FT_FRAME_EXIT(); |
| 147 |
| 148 if ( version < 1 ) |
| 149 { |
| 150 error = FT_THROW( Unknown_File_Format ); |
| 151 goto Exit; |
| 152 } |
| 153 |
| 154 /* Bit 0 must always be `1'. */ |
| 155 /* Bit 1 controls the overlay of bitmaps with outlines. */ |
| 156 /* All other bits should be zero. */ |
| 157 if ( !( flags == 1 || flags == 3 ) || |
| 158 num_strikes >= 0x10000UL ) |
| 159 { |
| 160 error = FT_THROW( Invalid_File_Format ); |
| 161 goto Exit; |
| 162 } |
| 163 |
| 164 /* we currently don't support bit 1; however, it is better to */ |
| 165 /* draw at least something... */ |
| 166 if ( flags == 3 ) |
| 167 FT_TRACE1(( "tt_face_load_sbit_strikes:" |
| 168 " sbix overlay not supported yet\n" |
| 169 " " |
| 170 " expect bad rendering results\n" )); |
| 171 |
| 172 /* |
| 173 * Count the number of strikes available in the table. We are a bit |
| 174 * paranoid there and don't trust the data. |
| 175 */ |
| 176 count = (FT_UInt)num_strikes; |
| 177 if ( 8 + 4UL * count > table_size ) |
| 178 count = (FT_UInt)( ( table_size - 8 ) / 4 ); |
| 179 |
| 180 if ( FT_STREAM_SEEK( FT_STREAM_POS() - 8 ) ) |
| 181 goto Exit; |
| 182 |
| 183 face->sbit_table_size = 8 + count * 4; |
| 184 if ( FT_FRAME_EXTRACT( face->sbit_table_size, face->sbit_table ) ) |
| 185 goto Exit; |
| 186 |
| 187 face->sbit_num_strikes = count; |
| 188 } |
| 189 break; |
| 190 |
| 191 default: |
| 192 error = FT_THROW( Unknown_File_Format ); |
| 193 break; |
90 } | 194 } |
91 | 195 |
92 /* | 196 if ( !error ) |
93 * Count the number of strikes available in the table. We are a bit | 197 FT_TRACE3(( "sbit_num_strikes: %u\n", face->sbit_num_strikes )); |
94 * paranoid there and don't trust the data. | |
95 */ | |
96 count = (FT_UInt)num_strikes; | |
97 if ( 8 + 48UL * count > table_size ) | |
98 count = (FT_UInt)( ( p_limit - p ) / 48 ); | |
99 | 198 |
100 face->sbit_num_strikes = count; | 199 return FT_Err_Ok; |
101 | 200 |
102 FT_TRACE3(( "sbit_num_strikes: %u\n", count )); | |
103 Exit: | 201 Exit: |
| 202 if ( error ) |
| 203 { |
| 204 if ( face->sbit_table ) |
| 205 FT_FRAME_RELEASE( face->sbit_table ); |
| 206 face->sbit_table_size = 0; |
| 207 face->sbit_table_type = TT_SBIT_TABLE_TYPE_NONE; |
| 208 } |
| 209 |
104 return error; | 210 return error; |
105 | |
106 Fail: | |
107 FT_FRAME_RELEASE( face->sbit_table ); | |
108 face->sbit_table_size = 0; | |
109 goto Exit; | |
110 } | 211 } |
111 | 212 |
112 | 213 |
113 FT_LOCAL_DEF( void ) | 214 FT_LOCAL_DEF( void ) |
114 tt_face_free_eblc( TT_Face face ) | 215 tt_face_free_sbit( TT_Face face ) |
115 { | 216 { |
116 FT_Stream stream = face->root.stream; | 217 FT_Stream stream = face->root.stream; |
117 | 218 |
118 | 219 |
119 FT_FRAME_RELEASE( face->sbit_table ); | 220 FT_FRAME_RELEASE( face->sbit_table ); |
120 face->sbit_table_size = 0; | 221 face->sbit_table_size = 0; |
| 222 face->sbit_table_type = TT_SBIT_TABLE_TYPE_NONE; |
121 face->sbit_num_strikes = 0; | 223 face->sbit_num_strikes = 0; |
122 } | 224 } |
123 | 225 |
124 | 226 |
125 FT_LOCAL_DEF( FT_Error ) | 227 FT_LOCAL_DEF( FT_Error ) |
126 tt_face_set_sbit_strike( TT_Face face, | 228 tt_face_set_sbit_strike( TT_Face face, |
127 FT_Size_Request req, | 229 FT_Size_Request req, |
128 FT_ULong* astrike_index ) | 230 FT_ULong* astrike_index ) |
129 { | 231 { |
130 return FT_Match_Size( (FT_Face)face, req, 0, astrike_index ); | 232 return FT_Match_Size( (FT_Face)face, req, 0, astrike_index ); |
131 } | 233 } |
132 | 234 |
133 | 235 |
134 FT_LOCAL_DEF( FT_Error ) | 236 FT_LOCAL_DEF( FT_Error ) |
135 tt_face_load_strike_metrics( TT_Face face, | 237 tt_face_load_strike_metrics( TT_Face face, |
136 FT_ULong strike_index, | 238 FT_ULong strike_index, |
137 FT_Size_Metrics* metrics ) | 239 FT_Size_Metrics* metrics ) |
138 { | 240 { |
139 FT_Byte* strike; | |
140 | |
141 | |
142 if ( strike_index >= (FT_ULong)face->sbit_num_strikes ) | 241 if ( strike_index >= (FT_ULong)face->sbit_num_strikes ) |
143 return FT_THROW( Invalid_Argument ); | 242 return FT_THROW( Invalid_Argument ); |
144 | 243 |
145 strike = face->sbit_table + 8 + strike_index * 48; | 244 switch ( (FT_UInt)face->sbit_table_type ) |
| 245 { |
| 246 case TT_SBIT_TABLE_TYPE_EBLC: |
| 247 case TT_SBIT_TABLE_TYPE_CBLC: |
| 248 { |
| 249 FT_Byte* strike; |
146 | 250 |
147 metrics->x_ppem = (FT_UShort)strike[44]; | |
148 metrics->y_ppem = (FT_UShort)strike[45]; | |
149 | 251 |
150 metrics->ascender = (FT_Char)strike[16] << 6; /* hori.ascender */ | 252 strike = face->sbit_table + 8 + strike_index * 48; |
151 metrics->descender = (FT_Char)strike[17] << 6; /* hori.descender */ | |
152 metrics->height = metrics->ascender - metrics->descender; | |
153 | 253 |
154 /* XXX: Is this correct? */ | 254 metrics->x_ppem = (FT_UShort)strike[44]; |
155 metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */ | 255 metrics->y_ppem = (FT_UShort)strike[45]; |
156 strike[18] + /* max_width */ | |
157 (FT_Char)strike[23] /* min_advance_SB */ | |
158 ) << 6; | |
159 | 256 |
160 return FT_Err_Ok; | 257 metrics->ascender = (FT_Char)strike[16] << 6; /* hori.ascender */ |
| 258 metrics->descender = (FT_Char)strike[17] << 6; /* hori.descender */ |
| 259 metrics->height = metrics->ascender - metrics->descender; |
| 260 |
| 261 /* Is this correct? */ |
| 262 metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */ |
| 263 strike[18] + /* max_width */ |
| 264 (FT_Char)strike[23] /* min_advance_SB */ |
| 265 ) << 6; |
| 266 return FT_Err_Ok; |
| 267 } |
| 268 |
| 269 case TT_SBIT_TABLE_TYPE_SBIX: |
| 270 { |
| 271 FT_Stream stream = face->root.stream; |
| 272 FT_UInt offset, upem; |
| 273 FT_UShort ppem, resolution; |
| 274 TT_HoriHeader *hori; |
| 275 FT_ULong table_size; |
| 276 |
| 277 FT_Error error; |
| 278 FT_Byte* p; |
| 279 |
| 280 |
| 281 p = face->sbit_table + 8 + 4 * strike_index; |
| 282 offset = FT_NEXT_ULONG( p ); |
| 283 |
| 284 error = face->goto_table( face, TTAG_sbix, stream, &table_size ); |
| 285 if ( error ) |
| 286 return error; |
| 287 |
| 288 if ( offset + 4 > table_size ) |
| 289 return FT_THROW( Invalid_File_Format ); |
| 290 |
| 291 if ( FT_STREAM_SEEK( FT_STREAM_POS() + offset ) || |
| 292 FT_FRAME_ENTER( 4 ) ) |
| 293 return error; |
| 294 |
| 295 ppem = FT_GET_USHORT(); |
| 296 resolution = FT_GET_USHORT(); |
| 297 |
| 298 FT_UNUSED( resolution ); /* What to do with this? */ |
| 299 |
| 300 FT_FRAME_EXIT(); |
| 301 |
| 302 upem = face->header.Units_Per_EM; |
| 303 hori = &face->horizontal; |
| 304 |
| 305 metrics->x_ppem = ppem; |
| 306 metrics->y_ppem = ppem; |
| 307 |
| 308 metrics->ascender = ppem * hori->Ascender * 64 / upem; |
| 309 metrics->descender = ppem * hori->Descender * 64 / upem; |
| 310 metrics->height = ppem * ( hori->Ascender - |
| 311 hori->Descender + |
| 312 hori->Line_Gap ) * 64 / upem; |
| 313 metrics->max_advance = ppem * hori->advance_Width_Max * 64 / upem; |
| 314 |
| 315 return error; |
| 316 } |
| 317 |
| 318 default: |
| 319 return FT_THROW( Unknown_File_Format ); |
| 320 } |
161 } | 321 } |
162 | 322 |
163 | 323 |
164 typedef struct TT_SBitDecoderRec_ | 324 typedef struct TT_SBitDecoderRec_ |
165 { | 325 { |
166 TT_Face face; | 326 TT_Face face; |
167 FT_Stream stream; | 327 FT_Stream stream; |
168 FT_Bitmap* bitmap; | 328 FT_Bitmap* bitmap; |
169 TT_SBit_Metrics metrics; | 329 TT_SBit_Metrics metrics; |
170 FT_Bool metrics_loaded; | 330 FT_Bool metrics_loaded; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 } | 387 } |
228 | 388 |
229 p = decoder->eblc_base + 8 + 48 * strike_index; | 389 p = decoder->eblc_base + 8 + 48 * strike_index; |
230 | 390 |
231 decoder->strike_index_array = FT_NEXT_ULONG( p ); | 391 decoder->strike_index_array = FT_NEXT_ULONG( p ); |
232 p += 4; | 392 p += 4; |
233 decoder->strike_index_count = FT_NEXT_ULONG( p ); | 393 decoder->strike_index_count = FT_NEXT_ULONG( p ); |
234 p += 34; | 394 p += 34; |
235 decoder->bit_depth = *p; | 395 decoder->bit_depth = *p; |
236 | 396 |
237 if ( decoder->strike_index_array > face->sbit_table_size || | 397 /* decoder->strike_index_array + */ |
238 decoder->strike_index_array + 8 * decoder->strike_index_count > | 398 /* 8 * decoder->strike_index_count > face->sbit_table_size ? */ |
239 face->sbit_table_size ) | 399 if ( decoder->strike_index_array > face->sbit_table_size || |
| 400 decoder->strike_index_count > |
| 401 ( face->sbit_table_size - decoder->strike_index_array ) / 8 ) |
240 error = FT_THROW( Invalid_File_Format ); | 402 error = FT_THROW( Invalid_File_Format ); |
241 } | 403 } |
242 | 404 |
243 Exit: | 405 Exit: |
244 return error; | 406 return error; |
245 } | 407 } |
246 | 408 |
247 | 409 |
248 static void | 410 static void |
249 tt_sbit_decoder_done( TT_SBitDecoder decoder ) | 411 tt_sbit_decoder_done( TT_SBitDecoder decoder ) |
250 { | 412 { |
251 FT_UNUSED( decoder ); | 413 FT_UNUSED( decoder ); |
252 } | 414 } |
253 | 415 |
254 | 416 |
255 static FT_Error | 417 static FT_Error |
256 tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder, | 418 tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder ) |
257 FT_UInt load_flags ) | |
258 { | 419 { |
259 FT_Error error = FT_Err_Ok; | 420 FT_Error error = FT_Err_Ok; |
260 FT_UInt width, height; | 421 FT_UInt width, height; |
261 FT_Bitmap* map = decoder->bitmap; | 422 FT_Bitmap* map = decoder->bitmap; |
262 FT_Long size; | 423 FT_Long size; |
263 | 424 |
264 | 425 |
265 if ( !decoder->metrics_loaded ) | 426 if ( !decoder->metrics_loaded ) |
266 { | 427 { |
267 error = FT_THROW( Invalid_Argument ); | 428 error = FT_THROW( Invalid_Argument ); |
(...skipping 26 matching lines...) Expand all Loading... |
294 map->num_grays = 16; | 455 map->num_grays = 16; |
295 break; | 456 break; |
296 | 457 |
297 case 8: | 458 case 8: |
298 map->pixel_mode = FT_PIXEL_MODE_GRAY; | 459 map->pixel_mode = FT_PIXEL_MODE_GRAY; |
299 map->pitch = map->width; | 460 map->pitch = map->width; |
300 map->num_grays = 256; | 461 map->num_grays = 256; |
301 break; | 462 break; |
302 | 463 |
303 case 32: | 464 case 32: |
304 if ( load_flags & FT_LOAD_COLOR ) | 465 map->pixel_mode = FT_PIXEL_MODE_BGRA; |
305 { | 466 map->pitch = map->width * 4; |
306 map->pixel_mode = FT_PIXEL_MODE_BGRA; | 467 map->num_grays = 256; |
307 map->pitch = map->width * 4; | |
308 map->num_grays = 256; | |
309 } | |
310 else | |
311 { | |
312 map->pixel_mode = FT_PIXEL_MODE_GRAY; | |
313 map->pitch = map->width; | |
314 map->num_grays = 256; | |
315 } | |
316 break; | 468 break; |
317 | 469 |
318 default: | 470 default: |
319 error = FT_THROW( Invalid_File_Format ); | 471 error = FT_THROW( Invalid_File_Format ); |
320 goto Exit; | 472 goto Exit; |
321 } | 473 } |
322 | 474 |
323 size = map->rows * map->pitch; | 475 size = map->rows * map->pitch; |
324 | 476 |
325 /* check that there is no empty image */ | 477 /* check that there is no empty image */ |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 { | 513 { |
362 if ( p + 3 > limit ) | 514 if ( p + 3 > limit ) |
363 goto Fail; | 515 goto Fail; |
364 | 516 |
365 metrics->vertBearingX = (FT_Char)p[0]; | 517 metrics->vertBearingX = (FT_Char)p[0]; |
366 metrics->vertBearingY = (FT_Char)p[1]; | 518 metrics->vertBearingY = (FT_Char)p[1]; |
367 metrics->vertAdvance = p[2]; | 519 metrics->vertAdvance = p[2]; |
368 | 520 |
369 p += 3; | 521 p += 3; |
370 } | 522 } |
| 523 else |
| 524 { |
| 525 /* avoid uninitialized data in case there is no vertical info -- */ |
| 526 metrics->vertBearingX = 0; |
| 527 metrics->vertBearingY = 0; |
| 528 metrics->vertAdvance = 0; |
| 529 } |
371 | 530 |
372 decoder->metrics_loaded = 1; | 531 decoder->metrics_loaded = 1; |
373 *pp = p; | 532 *pp = p; |
374 return FT_Err_Ok; | 533 return FT_Err_Ok; |
375 | 534 |
376 Fail: | 535 Fail: |
377 FT_TRACE1(( "tt_sbit_decoder_load_metrics: broken table" )); | 536 FT_TRACE1(( "tt_sbit_decoder_load_metrics: broken table\n" )); |
378 return FT_THROW( Invalid_Argument ); | 537 return FT_THROW( Invalid_Argument ); |
379 } | 538 } |
380 | 539 |
381 | 540 |
382 /* forward declaration */ | 541 /* forward declaration */ |
383 static FT_Error | 542 static FT_Error |
384 tt_sbit_decoder_load_image( TT_SBitDecoder decoder, | 543 tt_sbit_decoder_load_image( TT_SBitDecoder decoder, |
385 FT_UInt load_flags, | |
386 FT_UInt glyph_index, | 544 FT_UInt glyph_index, |
387 FT_Int x_pos, | 545 FT_Int x_pos, |
388 FT_Int y_pos ); | 546 FT_Int y_pos ); |
389 | 547 |
390 typedef FT_Error (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder decoder, | 548 typedef FT_Error (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder decoder, |
391 FT_UInt load_flags, | |
392 FT_Byte* p, | 549 FT_Byte* p, |
393 FT_Byte* plimit, | 550 FT_Byte* plimit, |
394 FT_Int x_pos, | 551 FT_Int x_pos, |
395 FT_Int y_pos ); | 552 FT_Int y_pos ); |
396 | 553 |
397 | 554 |
398 static FT_Error | 555 static FT_Error |
399 tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder, | 556 tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder decoder, |
400 FT_UInt load_flags, | |
401 FT_Byte* p, | 557 FT_Byte* p, |
402 FT_Byte* limit, | 558 FT_Byte* limit, |
403 FT_Int x_pos, | 559 FT_Int x_pos, |
404 FT_Int y_pos ) | 560 FT_Int y_pos ) |
405 { | 561 { |
406 FT_Error error = FT_Err_Ok; | 562 FT_Error error = FT_Err_Ok; |
407 FT_Byte* line; | 563 FT_Byte* line; |
408 FT_Int bit_height, bit_width, pitch, width, height, line_bits, h; | 564 FT_Int bit_height, bit_width, pitch, width, height, line_bits, h; |
409 FT_Bitmap* bitmap; | 565 FT_Bitmap* bitmap; |
410 | 566 |
411 FT_UNUSED( load_flags ); | |
412 | |
413 | 567 |
414 /* check that we can write the glyph into the bitmap */ | 568 /* check that we can write the glyph into the bitmap */ |
415 bitmap = decoder->bitmap; | 569 bitmap = decoder->bitmap; |
416 bit_width = bitmap->width; | 570 bit_width = bitmap->width; |
417 bit_height = bitmap->rows; | 571 bit_height = bitmap->rows; |
418 pitch = bitmap->pitch; | 572 pitch = bitmap->pitch; |
419 line = bitmap->buffer; | 573 line = bitmap->buffer; |
420 | 574 |
421 width = decoder->metrics->width; | 575 width = decoder->metrics->width; |
422 height = decoder->metrics->height; | 576 height = decoder->metrics->height; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 * +-------+ | 685 * +-------+ |
532 * | | | 686 * | | |
533 * | 7 6 5 4 3 2 1 0 | | 687 * | 7 6 5 4 3 2 1 0 | |
534 * | | | 688 * | | |
535 * pwrite+2 | 689 * pwrite+2 |
536 * | 690 * |
537 */ | 691 */ |
538 | 692 |
539 static FT_Error | 693 static FT_Error |
540 tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder, | 694 tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder decoder, |
541 FT_UInt load_flags, | |
542 FT_Byte* p, | 695 FT_Byte* p, |
543 FT_Byte* limit, | 696 FT_Byte* limit, |
544 FT_Int x_pos, | 697 FT_Int x_pos, |
545 FT_Int y_pos ) | 698 FT_Int y_pos ) |
546 { | 699 { |
547 FT_Error error = FT_Err_Ok; | 700 FT_Error error = FT_Err_Ok; |
548 FT_Byte* line; | 701 FT_Byte* line; |
549 FT_Int bit_height, bit_width, pitch, width, height, line_bits, h, nbits
; | 702 FT_Int bit_height, bit_width, pitch, width, height, line_bits, h, nbits
; |
550 FT_Bitmap* bitmap; | 703 FT_Bitmap* bitmap; |
551 FT_UShort rval; | 704 FT_UShort rval; |
552 | 705 |
553 FT_UNUSED( load_flags ); | |
554 | |
555 | 706 |
556 /* check that we can write the glyph into the bitmap */ | 707 /* check that we can write the glyph into the bitmap */ |
557 bitmap = decoder->bitmap; | 708 bitmap = decoder->bitmap; |
558 bit_width = bitmap->width; | 709 bit_width = bitmap->width; |
559 bit_height = bitmap->rows; | 710 bit_height = bitmap->rows; |
560 pitch = bitmap->pitch; | 711 pitch = bitmap->pitch; |
561 line = bitmap->buffer; | 712 line = bitmap->buffer; |
562 | 713 |
563 width = decoder->metrics->width; | 714 width = decoder->metrics->width; |
564 height = decoder->metrics->height; | 715 height = decoder->metrics->height; |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
657 | 808 |
658 Exit: | 809 Exit: |
659 if ( !error ) | 810 if ( !error ) |
660 FT_TRACE3(( "tt_sbit_decoder_load_bit_aligned: loaded\n" )); | 811 FT_TRACE3(( "tt_sbit_decoder_load_bit_aligned: loaded\n" )); |
661 return error; | 812 return error; |
662 } | 813 } |
663 | 814 |
664 | 815 |
665 static FT_Error | 816 static FT_Error |
666 tt_sbit_decoder_load_compound( TT_SBitDecoder decoder, | 817 tt_sbit_decoder_load_compound( TT_SBitDecoder decoder, |
667 FT_UInt load_flags, | |
668 FT_Byte* p, | 818 FT_Byte* p, |
669 FT_Byte* limit, | 819 FT_Byte* limit, |
670 FT_Int x_pos, | 820 FT_Int x_pos, |
671 FT_Int y_pos ) | 821 FT_Int y_pos ) |
672 { | 822 { |
673 FT_Error error = FT_Err_Ok; | 823 FT_Error error = FT_Err_Ok; |
674 FT_UInt num_components, nn; | 824 FT_UInt num_components, nn; |
675 | 825 |
676 FT_Char horiBearingX = decoder->metrics->horiBearingX; | 826 FT_Char horiBearingX = (FT_Char)decoder->metrics->horiBearingX; |
677 FT_Char horiBearingY = decoder->metrics->horiBearingY; | 827 FT_Char horiBearingY = (FT_Char)decoder->metrics->horiBearingY; |
678 FT_Byte horiAdvance = decoder->metrics->horiAdvance; | 828 FT_Byte horiAdvance = (FT_Byte)decoder->metrics->horiAdvance; |
679 FT_Char vertBearingX = decoder->metrics->vertBearingX; | 829 FT_Char vertBearingX = (FT_Char)decoder->metrics->vertBearingX; |
680 FT_Char vertBearingY = decoder->metrics->vertBearingY; | 830 FT_Char vertBearingY = (FT_Char)decoder->metrics->vertBearingY; |
681 FT_Byte vertAdvance = decoder->metrics->vertAdvance; | 831 FT_Byte vertAdvance = (FT_Byte)decoder->metrics->vertAdvance; |
682 | 832 |
683 | 833 |
684 if ( p + 2 > limit ) | 834 if ( p + 2 > limit ) |
685 goto Fail; | 835 goto Fail; |
686 | 836 |
687 num_components = FT_NEXT_USHORT( p ); | 837 num_components = FT_NEXT_USHORT( p ); |
688 if ( p + 4 * num_components > limit ) | 838 if ( p + 4 * num_components > limit ) |
689 { | 839 { |
690 FT_TRACE1(( "tt_sbit_decoder_load_compound: broken table\n" )); | 840 FT_TRACE1(( "tt_sbit_decoder_load_compound: broken table\n" )); |
691 goto Fail; | 841 goto Fail; |
692 } | 842 } |
693 | 843 |
694 FT_TRACE3(( "tt_sbit_decoder_load_compound: loading %d components\n", | 844 FT_TRACE3(( "tt_sbit_decoder_load_compound: loading %d components\n", |
695 num_components )); | 845 num_components )); |
696 | 846 |
697 for ( nn = 0; nn < num_components; nn++ ) | 847 for ( nn = 0; nn < num_components; nn++ ) |
698 { | 848 { |
699 FT_UInt gindex = FT_NEXT_USHORT( p ); | 849 FT_UInt gindex = FT_NEXT_USHORT( p ); |
700 FT_Byte dx = FT_NEXT_BYTE( p ); | 850 FT_Byte dx = FT_NEXT_BYTE( p ); |
701 FT_Byte dy = FT_NEXT_BYTE( p ); | 851 FT_Byte dy = FT_NEXT_BYTE( p ); |
702 | 852 |
703 | 853 |
704 /* NB: a recursive call */ | 854 /* NB: a recursive call */ |
705 error = tt_sbit_decoder_load_image( decoder, load_flags, gindex, | 855 error = tt_sbit_decoder_load_image( decoder, gindex, |
706 x_pos + dx, y_pos + dy ); | 856 x_pos + dx, y_pos + dy ); |
707 if ( error ) | 857 if ( error ) |
708 break; | 858 break; |
709 } | 859 } |
710 | 860 |
711 FT_TRACE3(( "tt_sbit_decoder_load_compound: done\n" )); | 861 FT_TRACE3(( "tt_sbit_decoder_load_compound: done\n" )); |
712 | 862 |
713 decoder->metrics->horiBearingX = horiBearingX; | 863 decoder->metrics->horiBearingX = horiBearingX; |
714 decoder->metrics->horiBearingY = horiBearingY; | 864 decoder->metrics->horiBearingY = horiBearingY; |
715 decoder->metrics->horiAdvance = horiAdvance; | 865 decoder->metrics->horiAdvance = horiAdvance; |
716 decoder->metrics->vertBearingX = vertBearingX; | 866 decoder->metrics->vertBearingX = vertBearingX; |
717 decoder->metrics->vertBearingY = vertBearingY; | 867 decoder->metrics->vertBearingY = vertBearingY; |
718 decoder->metrics->vertAdvance = vertAdvance; | 868 decoder->metrics->vertAdvance = vertAdvance; |
719 decoder->metrics->width = (FT_Byte)decoder->bitmap->width; | 869 decoder->metrics->width = (FT_Byte)decoder->bitmap->width; |
720 decoder->metrics->height = (FT_Byte)decoder->bitmap->rows; | 870 decoder->metrics->height = (FT_Byte)decoder->bitmap->rows; |
721 | 871 |
722 Exit: | 872 Exit: |
723 return error; | 873 return error; |
724 | 874 |
725 Fail: | 875 Fail: |
726 error = FT_THROW( Invalid_File_Format ); | 876 error = FT_THROW( Invalid_File_Format ); |
727 goto Exit; | 877 goto Exit; |
728 } | 878 } |
729 | 879 |
730 | 880 |
731 #ifdef FT_CONFIG_OPTION_USE_PNG | 881 #ifdef FT_CONFIG_OPTION_USE_PNG |
732 | 882 |
733 static FT_Error | 883 static FT_Error |
734 tt_sbit_decoder_load_png( TT_SBitDecoder decoder, | 884 tt_sbit_decoder_load_png( TT_SBitDecoder decoder, |
735 FT_UInt load_flags, | |
736 FT_Byte* p, | 885 FT_Byte* p, |
737 FT_Byte* limit, | 886 FT_Byte* limit, |
738 FT_Int x_pos, | 887 FT_Int x_pos, |
739 FT_Int y_pos ) | 888 FT_Int y_pos ) |
740 { | 889 { |
741 FT_Error error = FT_Err_Ok; | 890 FT_Error error = FT_Err_Ok; |
742 FT_ULong png_len; | 891 FT_ULong png_len; |
743 | 892 |
744 FT_UNUSED( load_flags ); | |
745 | |
746 | 893 |
747 if ( limit - p < 4 ) | 894 if ( limit - p < 4 ) |
748 { | 895 { |
749 FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" )); | 896 FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" )); |
750 error = FT_THROW( Invalid_File_Format ); | 897 error = FT_THROW( Invalid_File_Format ); |
751 goto Exit; | 898 goto Exit; |
752 } | 899 } |
753 | 900 |
754 png_len = FT_NEXT_ULONG( p ); | 901 png_len = FT_NEXT_ULONG( p ); |
755 if ( (FT_ULong)( limit - p ) < png_len ) | 902 if ( (FT_ULong)( limit - p ) < png_len ) |
756 { | 903 { |
757 FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" )); | 904 FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" )); |
758 error = FT_THROW( Invalid_File_Format ); | 905 error = FT_THROW( Invalid_File_Format ); |
759 goto Exit; | 906 goto Exit; |
760 } | 907 } |
761 | 908 |
762 error = Load_SBit_Png( decoder->bitmap, | 909 error = Load_SBit_Png( decoder->face->root.glyph, |
763 x_pos, | 910 x_pos, |
764 y_pos, | 911 y_pos, |
765 decoder->bit_depth, | 912 decoder->bit_depth, |
766 decoder->metrics, | 913 decoder->metrics, |
767 decoder->stream->memory, | 914 decoder->stream->memory, |
768 p, | 915 p, |
769 png_len ); | 916 png_len, |
| 917 FALSE ); |
770 | 918 |
771 Exit: | 919 Exit: |
772 if ( !error ) | 920 if ( !error ) |
773 FT_TRACE3(( "tt_sbit_decoder_load_png: loaded\n" )); | 921 FT_TRACE3(( "tt_sbit_decoder_load_png: loaded\n" )); |
774 return error; | 922 return error; |
775 } | 923 } |
776 | 924 |
777 #endif /* FT_CONFIG_OPTION_USE_PNG */ | 925 #endif /* FT_CONFIG_OPTION_USE_PNG */ |
778 | 926 |
779 | 927 |
780 static FT_Error | 928 static FT_Error |
781 tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder, | 929 tt_sbit_decoder_load_bitmap( TT_SBitDecoder decoder, |
782 FT_UInt load_flags, | |
783 FT_UInt glyph_format, | 930 FT_UInt glyph_format, |
784 FT_ULong glyph_start, | 931 FT_ULong glyph_start, |
785 FT_ULong glyph_size, | 932 FT_ULong glyph_size, |
786 FT_Int x_pos, | 933 FT_Int x_pos, |
787 FT_Int y_pos ) | 934 FT_Int y_pos ) |
788 { | 935 { |
789 FT_Error error; | 936 FT_Error error; |
790 FT_Stream stream = decoder->stream; | 937 FT_Stream stream = decoder->stream; |
791 FT_Byte* p; | 938 FT_Byte* p; |
792 FT_Byte* p_limit; | 939 FT_Byte* p_limit; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
836 | 983 |
837 | 984 |
838 switch ( glyph_format ) | 985 switch ( glyph_format ) |
839 { | 986 { |
840 case 1: | 987 case 1: |
841 case 6: | 988 case 6: |
842 loader = tt_sbit_decoder_load_byte_aligned; | 989 loader = tt_sbit_decoder_load_byte_aligned; |
843 break; | 990 break; |
844 | 991 |
845 case 2: | 992 case 2: |
| 993 case 7: |
| 994 { |
| 995 /* Don't trust `glyph_format'. For example, Apple's main Korean */ |
| 996 /* system font, `AppleMyungJo.ttf' (version 7.0d2e6), uses glyph */ |
| 997 /* format 7, but the data is format 6. We check whether we have */ |
| 998 /* an excessive number of bytes in the image: If it is equal to */ |
| 999 /* the value for a byte-aligned glyph, use the other loading */ |
| 1000 /* routine. */ |
| 1001 /* */ |
| 1002 /* Note that for some (width,height) combinations, where the */ |
| 1003 /* width is not a multiple of 8, the sizes for bit- and */ |
| 1004 /* byte-aligned data are equal, for example (7,7) or (15,6). We */ |
| 1005 /* then prefer what `glyph_format' specifies. */ |
| 1006 |
| 1007 FT_UInt width = decoder->metrics->width; |
| 1008 FT_UInt height = decoder->metrics->height; |
| 1009 |
| 1010 FT_UInt bit_size = ( width * height + 7 ) >> 3; |
| 1011 FT_UInt byte_size = height * ( ( width + 7 ) >> 3 ); |
| 1012 |
| 1013 |
| 1014 if ( bit_size < byte_size && |
| 1015 byte_size == (FT_UInt)( p_limit - p ) ) |
| 1016 loader = tt_sbit_decoder_load_byte_aligned; |
| 1017 else |
| 1018 loader = tt_sbit_decoder_load_bit_aligned; |
| 1019 } |
| 1020 break; |
| 1021 |
846 case 5: | 1022 case 5: |
847 case 7: | |
848 loader = tt_sbit_decoder_load_bit_aligned; | 1023 loader = tt_sbit_decoder_load_bit_aligned; |
849 break; | 1024 break; |
850 | 1025 |
851 case 8: | 1026 case 8: |
852 if ( p + 1 > p_limit ) | 1027 if ( p + 1 > p_limit ) |
853 goto Fail; | 1028 goto Fail; |
854 | 1029 |
855 p += 1; /* skip padding */ | 1030 p += 1; /* skip padding */ |
856 /* fall-through */ | 1031 /* fall-through */ |
857 | 1032 |
858 case 9: | 1033 case 9: |
859 loader = tt_sbit_decoder_load_compound; | 1034 loader = tt_sbit_decoder_load_compound; |
860 break; | 1035 break; |
861 | 1036 |
862 #ifdef FT_CONFIG_OPTION_USE_PNG | |
863 case 17: /* small metrics, PNG image data */ | 1037 case 17: /* small metrics, PNG image data */ |
864 case 18: /* big metrics, PNG image data */ | 1038 case 18: /* big metrics, PNG image data */ |
865 case 19: /* metrics in EBLC, PNG image data */ | 1039 case 19: /* metrics in EBLC, PNG image data */ |
| 1040 #ifdef FT_CONFIG_OPTION_USE_PNG |
866 loader = tt_sbit_decoder_load_png; | 1041 loader = tt_sbit_decoder_load_png; |
867 break; | 1042 break; |
| 1043 #else |
| 1044 error = FT_THROW( Unimplemented_Feature ); |
| 1045 goto Fail; |
868 #endif /* FT_CONFIG_OPTION_USE_PNG */ | 1046 #endif /* FT_CONFIG_OPTION_USE_PNG */ |
869 | 1047 |
870 default: | 1048 default: |
871 error = FT_THROW( Invalid_Table ); | 1049 error = FT_THROW( Invalid_Table ); |
872 goto Fail; | 1050 goto Fail; |
873 } | 1051 } |
874 | 1052 |
875 if ( !decoder->bitmap_allocated ) | 1053 if ( !decoder->bitmap_allocated ) |
876 { | 1054 { |
877 error = tt_sbit_decoder_alloc_bitmap( decoder, load_flags ); | 1055 error = tt_sbit_decoder_alloc_bitmap( decoder ); |
878 if ( error ) | 1056 if ( error ) |
879 goto Fail; | 1057 goto Fail; |
880 } | 1058 } |
881 | 1059 |
882 if ( decoder->bit_depth == 32 && | 1060 error = loader( decoder, p, p_limit, x_pos, y_pos ); |
883 decoder->bitmap->pixel_mode != FT_PIXEL_MODE_BGRA ) | |
884 { | |
885 /* Flatten color bitmaps if color was not requested. */ | |
886 | |
887 FT_Library library = decoder->face->root.glyph->library; | |
888 FT_Memory memory = decoder->stream->memory; | |
889 | |
890 FT_Bitmap color, *orig; | |
891 | |
892 | |
893 if ( decoder->bitmap->pixel_mode != FT_PIXEL_MODE_GRAY || | |
894 x_pos != 0 || y_pos != 0 ) | |
895 { | |
896 /* Shouldn't happen. */ | |
897 error = FT_THROW( Invalid_Table ); | |
898 goto Fail; | |
899 } | |
900 | |
901 FT_Bitmap_New( &color ); | |
902 | |
903 color.rows = decoder->bitmap->rows; | |
904 color.width = decoder->bitmap->width; | |
905 color.pitch = color.width * 4; | |
906 color.pixel_mode = FT_PIXEL_MODE_BGRA; | |
907 | |
908 if ( FT_ALLOC( color.buffer, color.rows * color.pitch ) ) | |
909 goto Fail; | |
910 | |
911 orig = decoder->bitmap; | |
912 decoder->bitmap = &color; | |
913 | |
914 error = loader( decoder, load_flags, p, p_limit, x_pos, y_pos ); | |
915 | |
916 decoder->bitmap = orig; | |
917 | |
918 /* explicitly test against FT_Err_Ok to avoid compiler warnings */ | |
919 /* (we do an assignment within a conditional) */ | |
920 if ( error || | |
921 ( error = FT_Bitmap_Convert( library, | |
922 &color, | |
923 decoder->bitmap, | |
924 1 ) ) != FT_Err_Ok ) | |
925 { | |
926 FT_Bitmap_Done( library, &color ); | |
927 goto Fail; | |
928 } | |
929 | |
930 FT_Bitmap_Done( library, &color ); | |
931 } | |
932 | |
933 else | |
934 error = loader( decoder, load_flags, p, p_limit, x_pos, y_pos ); | |
935 } | 1061 } |
936 | 1062 |
937 Fail: | 1063 Fail: |
938 FT_FRAME_RELEASE( data ); | 1064 FT_FRAME_RELEASE( data ); |
939 | 1065 |
940 Exit: | 1066 Exit: |
941 return error; | 1067 return error; |
942 } | 1068 } |
943 | 1069 |
944 | 1070 |
945 static FT_Error | 1071 static FT_Error |
946 tt_sbit_decoder_load_image( TT_SBitDecoder decoder, | 1072 tt_sbit_decoder_load_image( TT_SBitDecoder decoder, |
947 FT_UInt load_flags, | |
948 FT_UInt glyph_index, | 1073 FT_UInt glyph_index, |
949 FT_Int x_pos, | 1074 FT_Int x_pos, |
950 FT_Int y_pos ) | 1075 FT_Int y_pos ) |
951 { | 1076 { |
952 /* | 1077 /* |
953 * First, we find the correct strike range that applies to this | 1078 * First, we find the correct strike range that applies to this |
954 * glyph index. | 1079 * glyph index. |
955 */ | 1080 */ |
956 | 1081 |
957 FT_Byte* p = decoder->eblc_base + decoder->strike_index_array; | 1082 FT_Byte* p = decoder->eblc_base + decoder->strike_index_array; |
(...skipping 28 matching lines...) Expand all Loading... |
986 goto NoBitmap; | 1111 goto NoBitmap; |
987 | 1112 |
988 /* now find the glyph's location and extend within the ebdt table */ | 1113 /* now find the glyph's location and extend within the ebdt table */ |
989 index_format = FT_NEXT_USHORT( p ); | 1114 index_format = FT_NEXT_USHORT( p ); |
990 image_format = FT_NEXT_USHORT( p ); | 1115 image_format = FT_NEXT_USHORT( p ); |
991 image_offset = FT_NEXT_ULONG ( p ); | 1116 image_offset = FT_NEXT_ULONG ( p ); |
992 | 1117 |
993 switch ( index_format ) | 1118 switch ( index_format ) |
994 { | 1119 { |
995 case 1: /* 4-byte offsets relative to `image_offset' */ | 1120 case 1: /* 4-byte offsets relative to `image_offset' */ |
996 { | 1121 p += 4 * ( glyph_index - start ); |
997 p += 4 * ( glyph_index - start ); | 1122 if ( p + 8 > p_limit ) |
998 if ( p + 8 > p_limit ) | 1123 goto NoBitmap; |
999 goto NoBitmap; | |
1000 | 1124 |
1001 image_start = FT_NEXT_ULONG( p ); | 1125 image_start = FT_NEXT_ULONG( p ); |
1002 image_end = FT_NEXT_ULONG( p ); | 1126 image_end = FT_NEXT_ULONG( p ); |
1003 | 1127 |
1004 if ( image_start == image_end ) /* missing glyph */ | 1128 if ( image_start == image_end ) /* missing glyph */ |
1005 goto NoBitmap; | 1129 goto NoBitmap; |
1006 } | |
1007 break; | 1130 break; |
1008 | 1131 |
1009 case 2: /* big metrics, constant image size */ | 1132 case 2: /* big metrics, constant image size */ |
1010 { | 1133 { |
1011 FT_ULong image_size; | 1134 FT_ULong image_size; |
1012 | 1135 |
1013 | 1136 |
1014 if ( p + 12 > p_limit ) | 1137 if ( p + 12 > p_limit ) |
1015 goto NoBitmap; | 1138 goto NoBitmap; |
1016 | 1139 |
1017 image_size = FT_NEXT_ULONG( p ); | 1140 image_size = FT_NEXT_ULONG( p ); |
1018 | 1141 |
1019 if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) ) | 1142 if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) ) |
1020 goto NoBitmap; | 1143 goto NoBitmap; |
1021 | 1144 |
1022 image_start = image_size * ( glyph_index - start ); | 1145 image_start = image_size * ( glyph_index - start ); |
1023 image_end = image_start + image_size; | 1146 image_end = image_start + image_size; |
1024 } | 1147 } |
1025 break; | 1148 break; |
1026 | 1149 |
1027 case 3: /* 2-byte offsets relative to 'image_offset' */ | 1150 case 3: /* 2-byte offsets relative to 'image_offset' */ |
1028 { | 1151 p += 2 * ( glyph_index - start ); |
1029 p += 2 * ( glyph_index - start ); | 1152 if ( p + 4 > p_limit ) |
1030 if ( p + 4 > p_limit ) | 1153 goto NoBitmap; |
1031 goto NoBitmap; | |
1032 | 1154 |
1033 image_start = FT_NEXT_USHORT( p ); | 1155 image_start = FT_NEXT_USHORT( p ); |
1034 image_end = FT_NEXT_USHORT( p ); | 1156 image_end = FT_NEXT_USHORT( p ); |
1035 | 1157 |
1036 if ( image_start == image_end ) /* missing glyph */ | 1158 if ( image_start == image_end ) /* missing glyph */ |
1037 goto NoBitmap; | 1159 goto NoBitmap; |
1038 } | |
1039 break; | 1160 break; |
1040 | 1161 |
1041 case 4: /* sparse glyph array with (glyph,offset) pairs */ | 1162 case 4: /* sparse glyph array with (glyph,offset) pairs */ |
1042 { | 1163 { |
1043 FT_ULong mm, num_glyphs; | 1164 FT_ULong mm, num_glyphs; |
1044 | 1165 |
1045 | 1166 |
1046 if ( p + 4 > p_limit ) | 1167 if ( p + 4 > p_limit ) |
1047 goto NoBitmap; | 1168 goto NoBitmap; |
1048 | 1169 |
1049 num_glyphs = FT_NEXT_ULONG( p ); | 1170 num_glyphs = FT_NEXT_ULONG( p ); |
1050 | 1171 |
1051 /* overflow check for p + ( num_glyphs + 1 ) * 4 */ | 1172 /* overflow check for p + ( num_glyphs + 1 ) * 4 */ |
1052 if ( num_glyphs > (FT_ULong)( ( ( p_limit - p ) >> 2 ) - 1 ) ) | 1173 if ( p + 4 > p_limit || |
| 1174 num_glyphs > (FT_ULong)( ( ( p_limit - p ) >> 2 ) - 1 ) ) |
1053 goto NoBitmap; | 1175 goto NoBitmap; |
1054 | 1176 |
1055 for ( mm = 0; mm < num_glyphs; mm++ ) | 1177 for ( mm = 0; mm < num_glyphs; mm++ ) |
1056 { | 1178 { |
1057 FT_UInt gindex = FT_NEXT_USHORT( p ); | 1179 FT_UInt gindex = FT_NEXT_USHORT( p ); |
1058 | 1180 |
1059 | 1181 |
1060 if ( gindex == glyph_index ) | 1182 if ( gindex == glyph_index ) |
1061 { | 1183 { |
1062 image_start = FT_NEXT_USHORT( p ); | 1184 image_start = FT_NEXT_USHORT( p ); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1117 goto NoBitmap; | 1239 goto NoBitmap; |
1118 | 1240 |
1119 image_end -= image_start; | 1241 image_end -= image_start; |
1120 image_start = image_offset + image_start; | 1242 image_start = image_offset + image_start; |
1121 | 1243 |
1122 FT_TRACE3(( "tt_sbit_decoder_load_image:" | 1244 FT_TRACE3(( "tt_sbit_decoder_load_image:" |
1123 " found sbit (format %d) for glyph index %d\n", | 1245 " found sbit (format %d) for glyph index %d\n", |
1124 image_format, glyph_index )); | 1246 image_format, glyph_index )); |
1125 | 1247 |
1126 return tt_sbit_decoder_load_bitmap( decoder, | 1248 return tt_sbit_decoder_load_bitmap( decoder, |
1127 load_flags, | |
1128 image_format, | 1249 image_format, |
1129 image_start, | 1250 image_start, |
1130 image_end, | 1251 image_end, |
1131 x_pos, | 1252 x_pos, |
1132 y_pos ); | 1253 y_pos ); |
1133 | 1254 |
1134 Failure: | 1255 Failure: |
1135 return FT_THROW( Invalid_Table ); | 1256 return FT_THROW( Invalid_Table ); |
1136 | 1257 |
1137 NoBitmap: | 1258 NoBitmap: |
1138 FT_TRACE4(( "tt_sbit_decoder_load_image:" | 1259 FT_TRACE4(( "tt_sbit_decoder_load_image:" |
1139 " no sbit found for glyph index %d\n", glyph_index )); | 1260 " no sbit found for glyph index %d\n", glyph_index )); |
1140 | 1261 |
1141 return FT_THROW( Invalid_Argument ); | 1262 return FT_THROW( Invalid_Argument ); |
1142 } | 1263 } |
1143 | 1264 |
1144 | 1265 |
| 1266 static FT_Error |
| 1267 tt_face_load_sbix_image( TT_Face face, |
| 1268 FT_ULong strike_index, |
| 1269 FT_UInt glyph_index, |
| 1270 FT_Stream stream, |
| 1271 FT_Bitmap *map, |
| 1272 TT_SBit_MetricsRec *metrics ) |
| 1273 { |
| 1274 FT_UInt sbix_pos, strike_offset, glyph_start, glyph_end; |
| 1275 FT_ULong table_size; |
| 1276 FT_Int originOffsetX, originOffsetY; |
| 1277 FT_Tag graphicType; |
| 1278 FT_Int recurse_depth = 0; |
| 1279 |
| 1280 FT_Error error; |
| 1281 FT_Byte* p; |
| 1282 |
| 1283 FT_UNUSED( map ); |
| 1284 |
| 1285 |
| 1286 metrics->width = 0; |
| 1287 metrics->height = 0; |
| 1288 |
| 1289 p = face->sbit_table + 8 + 4 * strike_index; |
| 1290 strike_offset = FT_NEXT_ULONG( p ); |
| 1291 |
| 1292 error = face->goto_table( face, TTAG_sbix, stream, &table_size ); |
| 1293 if ( error ) |
| 1294 return error; |
| 1295 sbix_pos = FT_STREAM_POS(); |
| 1296 |
| 1297 retry: |
| 1298 if ( glyph_index > (FT_UInt)face->root.num_glyphs ) |
| 1299 return FT_THROW( Invalid_Argument ); |
| 1300 |
| 1301 if ( strike_offset >= table_size || |
| 1302 table_size - strike_offset < 4 + glyph_index * 4 + 8 ) |
| 1303 return FT_THROW( Invalid_File_Format ); |
| 1304 |
| 1305 if ( FT_STREAM_SEEK( sbix_pos + strike_offset + 4 + glyph_index * 4 ) || |
| 1306 FT_FRAME_ENTER( 8 ) ) |
| 1307 return error; |
| 1308 |
| 1309 glyph_start = FT_GET_ULONG(); |
| 1310 glyph_end = FT_GET_ULONG(); |
| 1311 |
| 1312 FT_FRAME_EXIT(); |
| 1313 |
| 1314 if ( glyph_start == glyph_end ) |
| 1315 return FT_THROW( Invalid_Argument ); |
| 1316 if ( glyph_start > glyph_end || |
| 1317 glyph_end - glyph_start < 8 || |
| 1318 table_size - strike_offset < glyph_end ) |
| 1319 return FT_THROW( Invalid_File_Format ); |
| 1320 |
| 1321 if ( FT_STREAM_SEEK( sbix_pos + strike_offset + glyph_start ) || |
| 1322 FT_FRAME_ENTER( glyph_end - glyph_start ) ) |
| 1323 return error; |
| 1324 |
| 1325 originOffsetX = FT_GET_SHORT(); |
| 1326 originOffsetY = FT_GET_SHORT(); |
| 1327 |
| 1328 graphicType = FT_GET_TAG4(); |
| 1329 |
| 1330 switch ( graphicType ) |
| 1331 { |
| 1332 case FT_MAKE_TAG( 'd', 'u', 'p', 'e' ): |
| 1333 if ( recurse_depth < 4 ) |
| 1334 { |
| 1335 glyph_index = FT_GET_USHORT(); |
| 1336 FT_FRAME_EXIT(); |
| 1337 recurse_depth++; |
| 1338 goto retry; |
| 1339 } |
| 1340 error = FT_THROW( Invalid_File_Format ); |
| 1341 break; |
| 1342 |
| 1343 case FT_MAKE_TAG( 'p', 'n', 'g', ' ' ): |
| 1344 #ifdef FT_CONFIG_OPTION_USE_PNG |
| 1345 error = Load_SBit_Png( face->root.glyph, |
| 1346 0, |
| 1347 0, |
| 1348 32, |
| 1349 metrics, |
| 1350 stream->memory, |
| 1351 stream->cursor, |
| 1352 glyph_end - glyph_start - 8, |
| 1353 TRUE ); |
| 1354 #else |
| 1355 error = FT_THROW( Unimplemented_Feature ); |
| 1356 #endif |
| 1357 break; |
| 1358 |
| 1359 case FT_MAKE_TAG( 'j', 'p', 'g', ' ' ): |
| 1360 case FT_MAKE_TAG( 't', 'i', 'f', 'f' ): |
| 1361 case FT_MAKE_TAG( 'r', 'g', 'b', 'l' ): /* used on iOS 7.1 */ |
| 1362 error = FT_THROW( Unknown_File_Format ); |
| 1363 break; |
| 1364 |
| 1365 default: |
| 1366 error = FT_THROW( Unimplemented_Feature ); |
| 1367 break; |
| 1368 } |
| 1369 |
| 1370 FT_FRAME_EXIT(); |
| 1371 |
| 1372 if ( !error ) |
| 1373 { |
| 1374 FT_Short abearing; |
| 1375 FT_UShort aadvance; |
| 1376 |
| 1377 |
| 1378 tt_face_get_metrics( face, FALSE, glyph_index, &abearing, &aadvance ); |
| 1379 |
| 1380 metrics->horiBearingX = (FT_Short)originOffsetX; |
| 1381 metrics->horiBearingY = (FT_Short)( -originOffsetY + metrics->height ); |
| 1382 metrics->horiAdvance = (FT_Short)( aadvance * |
| 1383 face->root.size->metrics.x_ppem / |
| 1384 face->header.Units_Per_EM ); |
| 1385 } |
| 1386 |
| 1387 return error; |
| 1388 } |
| 1389 |
1145 FT_LOCAL( FT_Error ) | 1390 FT_LOCAL( FT_Error ) |
1146 tt_face_load_sbit_image( TT_Face face, | 1391 tt_face_load_sbit_image( TT_Face face, |
1147 FT_ULong strike_index, | 1392 FT_ULong strike_index, |
1148 FT_UInt glyph_index, | 1393 FT_UInt glyph_index, |
1149 FT_UInt load_flags, | 1394 FT_UInt load_flags, |
1150 FT_Stream stream, | 1395 FT_Stream stream, |
1151 FT_Bitmap *map, | 1396 FT_Bitmap *map, |
1152 TT_SBit_MetricsRec *metrics ) | 1397 TT_SBit_MetricsRec *metrics ) |
1153 { | 1398 { |
1154 TT_SBitDecoderRec decoder[1]; | 1399 FT_Error error = FT_Err_Ok; |
1155 FT_Error error; | |
1156 | |
1157 FT_UNUSED( load_flags ); | |
1158 FT_UNUSED( stream ); | |
1159 FT_UNUSED( map ); | |
1160 | 1400 |
1161 | 1401 |
1162 error = tt_sbit_decoder_init( decoder, face, strike_index, metrics ); | 1402 switch ( (FT_UInt)face->sbit_table_type ) |
1163 if ( !error ) | |
1164 { | 1403 { |
1165 error = tt_sbit_decoder_load_image( decoder, | 1404 case TT_SBIT_TABLE_TYPE_EBLC: |
1166 load_flags, | 1405 case TT_SBIT_TABLE_TYPE_CBLC: |
1167 glyph_index, | 1406 { |
1168 0, | 1407 TT_SBitDecoderRec decoder[1]; |
1169 0 ); | 1408 |
1170 tt_sbit_decoder_done( decoder ); | 1409 |
| 1410 error = tt_sbit_decoder_init( decoder, face, strike_index, metrics ); |
| 1411 if ( !error ) |
| 1412 { |
| 1413 error = tt_sbit_decoder_load_image( decoder, |
| 1414 glyph_index, |
| 1415 0, |
| 1416 0 ); |
| 1417 tt_sbit_decoder_done( decoder ); |
| 1418 } |
| 1419 } |
| 1420 break; |
| 1421 |
| 1422 case TT_SBIT_TABLE_TYPE_SBIX: |
| 1423 error = tt_face_load_sbix_image( face, |
| 1424 strike_index, |
| 1425 glyph_index, |
| 1426 stream, |
| 1427 map, |
| 1428 metrics ); |
| 1429 break; |
| 1430 |
| 1431 default: |
| 1432 error = FT_THROW( Unknown_File_Format ); |
| 1433 break; |
| 1434 } |
| 1435 |
| 1436 /* Flatten color bitmaps if color was not requested. */ |
| 1437 if ( !error && |
| 1438 !( load_flags & FT_LOAD_COLOR ) && |
| 1439 map->pixel_mode == FT_PIXEL_MODE_BGRA ) |
| 1440 { |
| 1441 FT_Bitmap new_map; |
| 1442 FT_Library library = face->root.glyph->library; |
| 1443 |
| 1444 |
| 1445 FT_Bitmap_New( &new_map ); |
| 1446 |
| 1447 /* Convert to 8bit grayscale. */ |
| 1448 error = FT_Bitmap_Convert( library, map, &new_map, 1 ); |
| 1449 if ( error ) |
| 1450 FT_Bitmap_Done( library, &new_map ); |
| 1451 else |
| 1452 { |
| 1453 map->pixel_mode = new_map.pixel_mode; |
| 1454 map->pitch = new_map.pitch; |
| 1455 map->num_grays = new_map.num_grays; |
| 1456 |
| 1457 ft_glyphslot_set_bitmap( face->root.glyph, new_map.buffer ); |
| 1458 face->root.glyph->internal->flags |= FT_GLYPH_OWN_BITMAP; |
| 1459 } |
1171 } | 1460 } |
1172 | 1461 |
1173 return error; | 1462 return error; |
1174 } | 1463 } |
1175 | 1464 |
1176 | 1465 |
1177 /* EOF */ | 1466 /* EOF */ |
OLD | NEW |