Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(448)

Side by Side Diff: core/src/fxge/fx_freetype/fxft2.5.01/src/truetype/ttpload.c

Issue 815103002: Update freetype to 2.5.4. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Adjust GYP and GN Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /***************************************************************************/
2 /* */
3 /* ttpload.c */
4 /* */
5 /* TrueType-specific tables loader (body). */
6 /* */
7 /* Copyright 1996-2002, 2004-2013 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
9 /* */
10 /* This file is part of the FreeType project, and may only be used, */
11 /* modified, and distributed under the terms of the FreeType project */
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13 /* this file you indicate that you have read the license and */
14 /* understand and accept it fully. */
15 /* */
16 /***************************************************************************/
17
18
19 #include "../../include/ft2build.h"
20 #include "../../include/freetype/internal/ftdebug.h"
21 #include "../../include/freetype/internal/ftobjs.h"
22 #include "../../include/freetype/internal/ftstream.h"
23 #include "../../include/freetype/tttags.h"
24
25 #include "ttpload.h"
26
27 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
28 #include "ttgxvar.h"
29 #endif
30
31 #include "tterrors.h"
32
33
34 /*************************************************************************/
35 /* */
36 /* 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 /* messages during execution. */
39 /* */
40 #undef FT_COMPONENT
41 #define FT_COMPONENT trace_ttpload
42
43
44 /*************************************************************************/
45 /* */
46 /* <Function> */
47 /* tt_face_load_loca */
48 /* */
49 /* <Description> */
50 /* Load the locations table. */
51 /* */
52 /* <InOut> */
53 /* face :: A handle to the target face object. */
54 /* */
55 /* <Input> */
56 /* stream :: The input stream. */
57 /* */
58 /* <Return> */
59 /* FreeType error code. 0 means success. */
60 /* */
61 FT_LOCAL_DEF( FT_Error )
62 tt_face_load_loca( TT_Face face,
63 FT_Stream stream )
64 {
65 FT_Error error;
66 FT_ULong table_len;
67 FT_Int shift;
68
69
70 /* we need the size of the `glyf' table for malformed `loca' tables */
71 error = face->goto_table( face, TTAG_glyf, stream, &face->glyf_len );
72
73 /* it is possible that a font doesn't have a glyf table at all */
74 /* or its size is zero */
75 if ( FT_ERR_EQ( error, Table_Missing ) )
76 face->glyf_len = 0;
77 else if ( error )
78 goto Exit;
79
80 FT_TRACE2(( "Locations " ));
81 error = face->goto_table( face, TTAG_loca, stream, &table_len );
82 if ( error )
83 {
84 error = FT_THROW( Locations_Missing );
85 goto Exit;
86 }
87
88 if ( face->header.Index_To_Loc_Format != 0 )
89 {
90 shift = 2;
91
92 if ( table_len >= 0x40000L )
93 {
94 FT_TRACE2(( "table too large\n" ));
95 error = FT_THROW( Invalid_Table );
96 goto Exit;
97 }
98 face->num_locations = table_len >> shift;
99 }
100 else
101 {
102 shift = 1;
103
104 if ( table_len >= 0x20000L )
105 {
106 FT_TRACE2(( "table too large\n" ));
107 error = FT_THROW( Invalid_Table );
108 goto Exit;
109 }
110 face->num_locations = table_len >> shift;
111 }
112 /*
113 * Extract the frame. We don't need to decompress it since
114 * we are able to parse it directly.
115 */
116 if ( FT_FRAME_EXTRACT( table_len, face->glyph_locations ) )
117 goto Exit;
118
119 FT_TRACE2(( "loaded\n" ));
120
121 Exit:
122 return error;
123 }
124
125
126 FT_LOCAL_DEF( FT_ULong )
127 tt_face_get_location( TT_Face face,
128 FT_UInt gindex,
129 FT_UInt *asize )
130 {
131 FT_ULong pos1 = 0, pos2 = 0;
132 FT_Byte* p = NULL;
133
134 if (!face || gindex >= face->num_locations)
135 {
136 if (asize)
137 *asize = 0;
138
139 return 0;
140 }
141
142 if ( face->header.Index_To_Loc_Format != 0 )
143 {
144 p = face->glyph_locations + gindex * 4;
145 pos1 = FT_NEXT_ULONG(p);
146 pos2 = pos1;
147 //p has been moved to next location in the previous FT_NEXT_ULONG.
148 if ( gindex < face->num_locations - 1 )
149 pos2 = FT_NEXT_ULONG(p);
150 }
151 else
152 {
153 p = face->glyph_locations + gindex * 2;
154 pos1 = FT_NEXT_USHORT(p);
155 pos2 = pos1;
156 //p has been moved to next location in the previous FT_NEXT_USHORT.
157 if ( gindex < face->num_locations - 1 )
158 pos2 = FT_NEXT_USHORT( p );
159
160 pos1 <<= 1;
161 pos2 <<= 1;
162 }
163
164 /* Check broken location data */
165 if ( pos1 > face->glyf_len )
166 {
167 FT_TRACE1(( "tt_face_get_location:"
168 " too large offset=0x%08lx found for gid=0x%04lx,"
169 " exceeding the end of glyf table (0x%08lx)\n",
170 pos1, gindex, face->glyf_len ));
171 *asize = 0;
172 return 0;
173 }
174
175 if ( pos2 > face->glyf_len )
176 {
177 FT_TRACE1(( "tt_face_get_location:"
178 " too large offset=0x%08lx found for gid=0x%04lx,"
179 " truncate at the end of glyf table (0x%08lx)\n",
180 pos2, gindex + 1, face->glyf_len ));
181 pos2 = face->glyf_len;
182 }
183
184 /* The `loca' table must be ordered; it refers to the length of */
185 /* an entry as the difference between the current and the next */
186 /* position. However, there do exist (malformed) fonts which */
187 /* don't obey this rule, so we are only able to provide an */
188 /* upper bound for the size. */
189 /* */
190 /* We get (intentionally) a wrong, non-zero result in case the */
191 /* `glyf' table is missing. */
192 if ( pos2 >= pos1 )
193 *asize = (FT_UInt)( pos2 - pos1 );
194 else
195 *asize = (FT_UInt)( face->glyf_len - pos1 );
196
197 return pos1;
198 }
199
200
201 FT_LOCAL_DEF( void )
202 tt_face_done_loca( TT_Face face )
203 {
204 FT_Stream stream = face->root.stream;
205
206
207 FT_FRAME_RELEASE( face->glyph_locations );
208 face->num_locations = 0;
209 }
210
211
212
213 /*************************************************************************/
214 /* */
215 /* <Function> */
216 /* tt_face_load_cvt */
217 /* */
218 /* <Description> */
219 /* Load the control value table into a face object. */
220 /* */
221 /* <InOut> */
222 /* face :: A handle to the target face object. */
223 /* */
224 /* <Input> */
225 /* stream :: A handle to the input stream. */
226 /* */
227 /* <Return> */
228 /* FreeType error code. 0 means success. */
229 /* */
230 FT_LOCAL_DEF( FT_Error )
231 tt_face_load_cvt( TT_Face face,
232 FT_Stream stream )
233 {
234 #ifdef TT_USE_BYTECODE_INTERPRETER
235
236 FT_Error error;
237 FT_Memory memory = stream->memory;
238 FT_ULong table_len;
239
240
241 FT_TRACE2(( "CVT " ));
242
243 error = face->goto_table( face, TTAG_cvt, stream, &table_len );
244 if ( error )
245 {
246 FT_TRACE2(( "is missing\n" ));
247
248 face->cvt_size = 0;
249 face->cvt = NULL;
250 error = FT_Err_Ok;
251
252 goto Exit;
253 }
254
255 face->cvt_size = table_len / 2;
256
257 if ( FT_NEW_ARRAY( face->cvt, face->cvt_size ) )
258 goto Exit;
259
260 if ( FT_FRAME_ENTER( face->cvt_size * 2L ) )
261 goto Exit;
262
263 {
264 FT_Short* cur = face->cvt;
265 FT_Short* limit = cur + face->cvt_size;
266
267
268 for ( ; cur < limit; cur++ )
269 *cur = FT_GET_SHORT();
270 }
271
272 FT_FRAME_EXIT();
273 FT_TRACE2(( "loaded\n" ));
274
275 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
276 if ( face->doblend )
277 error = tt_face_vary_cvt( face, stream );
278 #endif
279
280 Exit:
281 return error;
282
283 #else /* !TT_USE_BYTECODE_INTERPRETER */
284
285 FT_UNUSED( face );
286 FT_UNUSED( stream );
287
288 return FT_Err_Ok;
289
290 #endif
291 }
292
293
294 /*************************************************************************/
295 /* */
296 /* <Function> */
297 /* tt_face_load_fpgm */
298 /* */
299 /* <Description> */
300 /* Load the font program. */
301 /* */
302 /* <InOut> */
303 /* face :: A handle to the target face object. */
304 /* */
305 /* <Input> */
306 /* stream :: A handle to the input stream. */
307 /* */
308 /* <Return> */
309 /* FreeType error code. 0 means success. */
310 /* */
311 FT_LOCAL_DEF( FT_Error )
312 tt_face_load_fpgm( TT_Face face,
313 FT_Stream stream )
314 {
315 #ifdef TT_USE_BYTECODE_INTERPRETER
316
317 FT_Error error;
318 FT_ULong table_len;
319
320
321 FT_TRACE2(( "Font program " ));
322
323 /* The font program is optional */
324 error = face->goto_table( face, TTAG_fpgm, stream, &table_len );
325 if ( error )
326 {
327 face->font_program = NULL;
328 face->font_program_size = 0;
329 error = FT_Err_Ok;
330
331 FT_TRACE2(( "is missing\n" ));
332 }
333 else
334 {
335 face->font_program_size = table_len;
336 if ( FT_FRAME_EXTRACT( table_len, face->font_program ) )
337 goto Exit;
338
339 FT_TRACE2(( "loaded, %12d bytes\n", face->font_program_size ));
340 }
341
342 Exit:
343 return error;
344
345 #else /* !TT_USE_BYTECODE_INTERPRETER */
346
347 FT_UNUSED( face );
348 FT_UNUSED( stream );
349
350 return FT_Err_Ok;
351
352 #endif
353 }
354
355
356 /*************************************************************************/
357 /* */
358 /* <Function> */
359 /* tt_face_load_prep */
360 /* */
361 /* <Description> */
362 /* Load the cvt program. */
363 /* */
364 /* <InOut> */
365 /* face :: A handle to the target face object. */
366 /* */
367 /* <Input> */
368 /* stream :: A handle to the input stream. */
369 /* */
370 /* <Return> */
371 /* FreeType error code. 0 means success. */
372 /* */
373 FT_LOCAL_DEF( FT_Error )
374 tt_face_load_prep( TT_Face face,
375 FT_Stream stream )
376 {
377 #ifdef TT_USE_BYTECODE_INTERPRETER
378
379 FT_Error error;
380 FT_ULong table_len;
381
382
383 FT_TRACE2(( "Prep program " ));
384
385 error = face->goto_table( face, TTAG_prep, stream, &table_len );
386 if ( error )
387 {
388 face->cvt_program = NULL;
389 face->cvt_program_size = 0;
390 error = FT_Err_Ok;
391
392 FT_TRACE2(( "is missing\n" ));
393 }
394 else
395 {
396 face->cvt_program_size = table_len;
397 if ( FT_FRAME_EXTRACT( table_len, face->cvt_program ) )
398 goto Exit;
399
400 FT_TRACE2(( "loaded, %12d bytes\n", face->cvt_program_size ));
401 }
402
403 Exit:
404 return error;
405
406 #else /* !TT_USE_BYTECODE_INTERPRETER */
407
408 FT_UNUSED( face );
409 FT_UNUSED( stream );
410
411 return FT_Err_Ok;
412
413 #endif
414 }
415
416
417 /*************************************************************************/
418 /* */
419 /* <Function> */
420 /* tt_face_load_hdmx */
421 /* */
422 /* <Description> */
423 /* Load the `hdmx' table into the face object. */
424 /* */
425 /* <Input> */
426 /* face :: A handle to the target face object. */
427 /* */
428 /* stream :: A handle to the input stream. */
429 /* */
430 /* <Return> */
431 /* FreeType error code. 0 means success. */
432 /* */
433
434 FT_LOCAL_DEF( FT_Error )
435 tt_face_load_hdmx( TT_Face face,
436 FT_Stream stream )
437 {
438 FT_Error error;
439 FT_Memory memory = stream->memory;
440 FT_UInt version, nn, num_records;
441 FT_ULong table_size, record_size;
442 FT_Byte* p;
443 FT_Byte* limit;
444
445
446 /* this table is optional */
447 error = face->goto_table( face, TTAG_hdmx, stream, &table_size );
448 if ( error || table_size < 8 )
449 return FT_Err_Ok;
450
451 if ( FT_FRAME_EXTRACT( table_size, face->hdmx_table ) )
452 goto Exit;
453
454 p = face->hdmx_table;
455 limit = p + table_size;
456
457 version = FT_NEXT_USHORT( p );
458 num_records = FT_NEXT_USHORT( p );
459 record_size = FT_NEXT_ULONG( p );
460
461 /* The maximum number of bytes in an hdmx device record is the */
462 /* maximum number of glyphs + 2; this is 0xFFFF + 2; this is */
463 /* the reason why `record_size' is a long (which we read as */
464 /* unsigned long for convenience). In practice, two bytes */
465 /* sufficient to hold the size value. */
466 /* */
467 /* There are at least two fonts, HANNOM-A and HANNOM-B version */
468 /* 2.0 (2005), which get this wrong: The upper two bytes of */
469 /* the size value are set to 0xFF instead of 0x00. We catch */
470 /* and fix this. */
471
472 if ( record_size >= 0xFFFF0000UL )
473 record_size &= 0xFFFFU;
474
475 /* The limit for `num_records' is a heuristic value. */
476
477 if ( version != 0 || num_records > 255 || record_size > 0x10001L )
478 {
479 error = FT_THROW( Invalid_File_Format );
480 goto Fail;
481 }
482
483 if ( FT_NEW_ARRAY( face->hdmx_record_sizes, num_records ) )
484 goto Fail;
485
486 for ( nn = 0; nn < num_records; nn++ )
487 {
488 if ( p + record_size > limit )
489 break;
490
491 face->hdmx_record_sizes[nn] = p[0];
492 p += record_size;
493 }
494
495 face->hdmx_record_count = nn;
496 face->hdmx_table_size = table_size;
497 face->hdmx_record_size = record_size;
498
499 Exit:
500 return error;
501
502 Fail:
503 FT_FRAME_RELEASE( face->hdmx_table );
504 face->hdmx_table_size = 0;
505 goto Exit;
506 }
507
508
509 FT_LOCAL_DEF( void )
510 tt_face_free_hdmx( TT_Face face )
511 {
512 FT_Stream stream = face->root.stream;
513 FT_Memory memory = stream->memory;
514
515
516 FT_FREE( face->hdmx_record_sizes );
517 FT_FRAME_RELEASE( face->hdmx_table );
518 }
519
520
521 /*************************************************************************/
522 /* */
523 /* Return the advance width table for a given pixel size if it is found */
524 /* in the font's `hdmx' table (if any). */
525 /* */
526 FT_LOCAL_DEF( FT_Byte* )
527 tt_face_get_device_metrics( TT_Face face,
528 FT_UInt ppem,
529 FT_UInt gindex )
530 {
531 FT_UInt nn;
532 FT_Byte* result = NULL;
533 FT_ULong record_size = face->hdmx_record_size;
534 FT_Byte* record = face->hdmx_table + 8;
535
536
537 for ( nn = 0; nn < face->hdmx_record_count; nn++ )
538 if ( face->hdmx_record_sizes[nn] == ppem )
539 {
540 gindex += 2;
541 if ( gindex < record_size )
542 result = record + nn * record_size + gindex;
543 break;
544 }
545
546 return result;
547 }
548
549
550 /* END */
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698