zenilib: zenilib/jni/external/freetype2/src/truetype/ttpload.c Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ttpload.c
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* ttpload.c */
4 /* */
5 /* TrueType-specific tables loader (body). */
6 /* */
7 /* Copyright 1996-2002, 2004-2012 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 <ft2build.h>
20 #include FT_INTERNAL_DEBUG_H
21 #include FT_INTERNAL_OBJECTS_H
22 #include FT_INTERNAL_STREAM_H
23 #include FT_TRUETYPE_TAGS_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 ( error == TT_Err_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 = TT_Err_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 = TT_Err_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 = TT_Err_Invalid_Table;
108 goto Exit;
109 }
110 face->num_locations = table_len >> shift;
111 }
112
113 if ( face->num_locations != (FT_ULong)face->root.num_glyphs + 1 )
114 {
115 FT_TRACE2(( "glyph count mismatch! loca: %d, maxp: %d\n",
116 face->num_locations - 1, face->root.num_glyphs ));
117
118 /* we only handle the case where `maxp' gives a larger value */
119 if ( face->num_locations <= (FT_ULong)face->root.num_glyphs )
120 {
121 FT_Long new_loca_len =
122 ( (FT_Long)( face->root.num_glyphs ) + 1 ) << shift;
123
124 TT_Table entry = face->dir_tables;
125 TT_Table limit = entry + face->num_tables;
126
127 FT_Long pos = FT_Stream_Pos( stream );
128 FT_Long dist = 0x7FFFFFFFL;
129
130
131 /* compute the distance to next table in font file */
132 for ( ; entry < limit; entry++ )
133 {
134 FT_Long diff = entry->Offset - pos;
135
136
137 if ( diff > 0 && diff < dist )
138 dist = diff;
139 }
140
141 if ( entry == limit )
142 {
143 /* `loca' is the last table */
144 dist = stream->size - pos;
145 }
146
147 if ( new_loca_len <= dist )
148 {
149 face->num_locations = face->root.num_glyphs + 1;
150 table_len = new_loca_len;
151
152 FT_TRACE2(( "adjusting num_locations to %d\n",
153 face->num_locations ));
154 }
155 }
156 }
157
158 /*
159 * Extract the frame. We don't need to decompress it since
160 * we are able to parse it directly.
161 */
162 if ( FT_FRAME_EXTRACT( table_len, face->glyph_locations ) )
163 goto Exit;
164
165 FT_TRACE2(( "loaded\n" ));
166
167 Exit:
168 return error;
169 }
170
171
172 FT_LOCAL_DEF( FT_ULong )
173 tt_face_get_location( TT_Face face,
174 FT_UInt gindex,
175 FT_UInt *asize )
176 {
177 FT_ULong pos1, pos2;
178 FT_Byte* p;
179 FT_Byte* p_limit;
180
181
182 pos1 = pos2 = 0;
183
184 if ( gindex < face->num_locations )
185 {
186 if ( face->header.Index_To_Loc_Format != 0 )
187 {
188 p = face->glyph_locations + gindex * 4;
189 p_limit = face->glyph_locations + face->num_locations * 4;
190
191 pos1 = FT_NEXT_ULONG( p );
192 pos2 = pos1;
193
194 if ( p + 4 <= p_limit )
195 pos2 = FT_NEXT_ULONG( p );
196 }
197 else
198 {
199 p = face->glyph_locations + gindex * 2;
200 p_limit = face->glyph_locations + face->num_locations * 2;
201
202 pos1 = FT_NEXT_USHORT( p );
203 pos2 = pos1;
204
205 if ( p + 2 <= p_limit )
206 pos2 = FT_NEXT_USHORT( p );
207
208 pos1 <<= 1;
209 pos2 <<= 1;
210 }
211 }
212
213 /* Check broken location data */
214 if ( pos1 > face->glyf_len )
215 {
216 FT_TRACE1(( "tt_face_get_location:"
217 " too large offset=0x%08lx found for gid=0x%04lx,"
218 " exceeding the end of glyf table (0x%08lx)\n",
219 pos1, gindex, face->glyf_len ));
220 *asize = 0;
221 return 0;
222 }
223
224 if ( pos2 > face->glyf_len )
225 {
226 FT_TRACE1(( "tt_face_get_location:"
227 " too large offset=0x%08lx found for gid=0x%04lx,"
228 " truncate at the end of glyf table (0x%08lx)\n",
229 pos2, gindex + 1, face->glyf_len ));
230 pos2 = face->glyf_len;
231 }
232
233 /* The `loca' table must be ordered; it refers to the length of */
234 /* an entry as the difference between the current and the next */
235 /* position. However, there do exist (malformed) fonts which */
236 /* don't obey this rule, so we are only able to provide an */
237 /* upper bound for the size. */
238 /* */
239 /* We get (intentionally) a wrong, non-zero result in case the */
240 /* `glyf' table is missing. */
241 if ( pos2 >= pos1 )
242 *asize = (FT_UInt)( pos2 - pos1 );
243 else
244 *asize = (FT_UInt)( face->glyf_len - pos1 );
245
246 return pos1;
247 }
248
249
250 FT_LOCAL_DEF( void )
251 tt_face_done_loca( TT_Face face )
252 {
253 FT_Stream stream = face->root.stream;
254
255
256 FT_FRAME_RELEASE( face->glyph_locations );
257 face->num_locations = 0;
258 }
259
260
261
262 /*************************************************************************/
263 /* */
264 /* <Function> */
265 /* tt_face_load_cvt */
266 /* */
267 /* <Description> */
268 /* Load the control value table into a face object. */
269 /* */
270 /* <InOut> */
271 /* face :: A handle to the target face object. */
272 /* */
273 /* <Input> */
274 /* stream :: A handle to the input stream. */
275 /* */
276 /* <Return> */
277 /* FreeType error code. 0 means success. */
278 /* */
279 FT_LOCAL_DEF( FT_Error )
280 tt_face_load_cvt( TT_Face face,
281 FT_Stream stream )
282 {
283 #ifdef TT_USE_BYTECODE_INTERPRETER
284
285 FT_Error error;
286 FT_Memory memory = stream->memory;
287 FT_ULong table_len;
288
289
290 FT_TRACE2(( "CVT " ));
291
292 error = face->goto_table( face, TTAG_cvt, stream, &table_len );
293 if ( error )
294 {
295 FT_TRACE2(( "is missing\n" ));
296
297 face->cvt_size = 0;
298 face->cvt = NULL;
299 error = TT_Err_Ok;
300
301 goto Exit;
302 }
303
304 face->cvt_size = table_len / 2;
305
306 if ( FT_NEW_ARRAY( face->cvt, face->cvt_size ) )
307 goto Exit;
308
309 if ( FT_FRAME_ENTER( face->cvt_size * 2L ) )
310 goto Exit;
311
312 {
313 FT_Short* cur = face->cvt;
314 FT_Short* limit = cur + face->cvt_size;
315
316
317 for ( ; cur < limit; cur++ )
318 *cur = FT_GET_SHORT();
319 }
320
321 FT_FRAME_EXIT();
322 FT_TRACE2(( "loaded\n" ));
323
324 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
325 if ( face->doblend )
326 error = tt_face_vary_cvt( face, stream );
327 #endif
328
329 Exit:
330 return error;
331
332 #else /* !TT_USE_BYTECODE_INTERPRETER */
333
334 FT_UNUSED( face );
335 FT_UNUSED( stream );
336
337 return TT_Err_Ok;
338
339 #endif
340 }
341
342
343 /*************************************************************************/
344 /* */
345 /* <Function> */
346 /* tt_face_load_fpgm */
347 /* */
348 /* <Description> */
349 /* Load the font program. */
350 /* */
351 /* <InOut> */
352 /* face :: A handle to the target face object. */
353 /* */
354 /* <Input> */
355 /* stream :: A handle to the input stream. */
356 /* */
357 /* <Return> */
358 /* FreeType error code. 0 means success. */
359 /* */
360 FT_LOCAL_DEF( FT_Error )
361 tt_face_load_fpgm( TT_Face face,
362 FT_Stream stream )
363 {
364 #ifdef TT_USE_BYTECODE_INTERPRETER
365
366 FT_Error error;
367 FT_ULong table_len;
368
369
370 FT_TRACE2(( "Font program " ));
371
372 /* The font program is optional */
373 error = face->goto_table( face, TTAG_fpgm, stream, &table_len );
374 if ( error )
375 {
376 face->font_program = NULL;
377 face->font_program_size = 0;
378 error = TT_Err_Ok;
379
380 FT_TRACE2(( "is missing\n" ));
381 }
382 else
383 {
384 face->font_program_size = table_len;
385 if ( FT_FRAME_EXTRACT( table_len, face->font_program ) )
386 goto Exit;
387
388 FT_TRACE2(( "loaded, %12d bytes\n", face->font_program_size ));
389 }
390
391 Exit:
392 return error;
393
394 #else /* !TT_USE_BYTECODE_INTERPRETER */
395
396 FT_UNUSED( face );
397 FT_UNUSED( stream );
398
399 return TT_Err_Ok;
400
401 #endif
402 }
403
404
405 /*************************************************************************/
406 /* */
407 /* <Function> */
408 /* tt_face_load_prep */
409 /* */
410 /* <Description> */
411 /* Load the cvt program. */
412 /* */
413 /* <InOut> */
414 /* face :: A handle to the target face object. */
415 /* */
416 /* <Input> */
417 /* stream :: A handle to the input stream. */
418 /* */
419 /* <Return> */
420 /* FreeType error code. 0 means success. */
421 /* */
422 FT_LOCAL_DEF( FT_Error )
423 tt_face_load_prep( TT_Face face,
424 FT_Stream stream )
425 {
426 #ifdef TT_USE_BYTECODE_INTERPRETER
427
428 FT_Error error;
429 FT_ULong table_len;
430
431
432 FT_TRACE2(( "Prep program " ));
433
434 error = face->goto_table( face, TTAG_prep, stream, &table_len );
435 if ( error )
436 {
437 face->cvt_program = NULL;
438 face->cvt_program_size = 0;
439 error = TT_Err_Ok;
440
441 FT_TRACE2(( "is missing\n" ));
442 }
443 else
444 {
445 face->cvt_program_size = table_len;
446 if ( FT_FRAME_EXTRACT( table_len, face->cvt_program ) )
447 goto Exit;
448
449 FT_TRACE2(( "loaded, %12d bytes\n", face->cvt_program_size ));
450 }
451
452 Exit:
453 return error;
454
455 #else /* !TT_USE_BYTECODE_INTERPRETER */
456
457 FT_UNUSED( face );
458 FT_UNUSED( stream );
459
460 return TT_Err_Ok;
461
462 #endif
463 }
464
465
466 /*************************************************************************/
467 /* */
468 /* <Function> */
469 /* tt_face_load_hdmx */
470 /* */
471 /* <Description> */
472 /* Load the `hdmx' table into the face object. */
473 /* */
474 /* <Input> */
475 /* face :: A handle to the target face object. */
476 /* */
477 /* stream :: A handle to the input stream. */
478 /* */
479 /* <Return> */
480 /* FreeType error code. 0 means success. */
481 /* */
482
483 FT_LOCAL_DEF( FT_Error )
484 tt_face_load_hdmx( TT_Face face,
485 FT_Stream stream )
486 {
487 FT_Error error;
488 FT_Memory memory = stream->memory;
489 FT_UInt version, nn, num_records;
490 FT_ULong table_size, record_size;
491 FT_Byte* p;
492 FT_Byte* limit;
493
494
495 /* this table is optional */
496 error = face->goto_table( face, TTAG_hdmx, stream, &table_size );
497 if ( error || table_size < 8 )
498 return TT_Err_Ok;
499
500 if ( FT_FRAME_EXTRACT( table_size, face->hdmx_table ) )
501 goto Exit;
502
503 p = face->hdmx_table;
504 limit = p + table_size;
505
506 version = FT_NEXT_USHORT( p );
507 num_records = FT_NEXT_USHORT( p );
508 record_size = FT_NEXT_ULONG( p );
509
510 /* The maximum number of bytes in an hdmx device record is the */
511 /* maximum number of glyphs + 2; this is 0xFFFF + 2; this is */
512 /* the reason why `record_size' is a long (which we read as */
513 /* unsigned long for convenience). In practice, two bytes */
514 /* sufficient to hold the size value. */
515 /* */
516 /* There are at least two fonts, HANNOM-A and HANNOM-B version */
517 /* 2.0 (2005), which get this wrong: The upper two bytes of */
518 /* the size value are set to 0xFF instead of 0x00. We catch */
519 /* and fix this. */
520
521 if ( record_size >= 0xFFFF0000UL )
522 record_size &= 0xFFFFU;
523
524 /* The limit for `num_records' is a heuristic value. */
525
526 if ( version != 0 || num_records > 255 || record_size > 0x10001L )
527 {
528 error = TT_Err_Invalid_File_Format;
529 goto Fail;
530 }
531
532 if ( FT_NEW_ARRAY( face->hdmx_record_sizes, num_records ) )
533 goto Fail;
534
535 for ( nn = 0; nn < num_records; nn++ )
536 {
537 if ( p + record_size > limit )
538 break;
539
540 face->hdmx_record_sizes[nn] = p[0];
541 p += record_size;
542 }
543
544 face->hdmx_record_count = nn;
545 face->hdmx_table_size = table_size;
546 face->hdmx_record_size = record_size;
547
548 Exit:
549 return error;
550
551 Fail:
552 FT_FRAME_RELEASE( face->hdmx_table );
553 face->hdmx_table_size = 0;
554 goto Exit;
555 }
556
557
558 FT_LOCAL_DEF( void )
559 tt_face_free_hdmx( TT_Face face )
560 {
561 FT_Stream stream = face->root.stream;
562 FT_Memory memory = stream->memory;
563
564
565 FT_FREE( face->hdmx_record_sizes );
566 FT_FRAME_RELEASE( face->hdmx_table );
567 }
568
569
570 /*************************************************************************/
571 /* */
572 /* Return the advance width table for a given pixel size if it is found */
573 /* in the font's `hdmx' table (if any). */
574 /* */
575 FT_LOCAL_DEF( FT_Byte* )
576 tt_face_get_device_metrics( TT_Face face,
577 FT_UInt ppem,
578 FT_UInt gindex )
579 {
580 FT_UInt nn;
581 FT_Byte* result = NULL;
582 FT_ULong record_size = face->hdmx_record_size;
583 FT_Byte* record = face->hdmx_table + 8;
584
585
586 for ( nn = 0; nn < face->hdmx_record_count; nn++ )
587 if ( face->hdmx_record_sizes[nn] == ppem )
588 {
589 gindex += 2;
590 if ( gindex < record_size )
591 result = record + nn * record_size + gindex;
592 break;
593 }
594
595 return result;
596 }
597
598
599 /* END */
FT_Error
int FT_Error
Definition: fttypes.h:296
TTAG_hdmx
#define TTAG_hdmx
Definition: tttags.h:62
FT_Long
signed long FT_Long
Definition: fttypes.h:238
FT_ULong
unsigned long FT_ULong
Definition: fttypes.h:249
TTAG_glyf
#define TTAG_glyf
Definition: tttags.h:58
ttpload.h
NULL
#define NULL
Definition: ftobjs.h:61
FT_Int
signed int FT_Int
Definition: fttypes.h:216
stream
GLuint GLuint stream
Definition: glew.h:6573
TT_TableRec_::Offset
FT_ULong Offset
Definition: tttypes.h:134
tt_face_load_loca
tt_face_load_loca(TT_Face face, FT_Stream stream)
Definition: ttpload.c:62
FT_Stream_Pos
FT_Stream_Pos(FT_Stream stream)
Definition: ftstream.c:103
version
int const char * version
Definition: zlib.h:813
tt_face_get_device_metrics
tt_face_get_device_metrics(TT_Face face, FT_UInt ppem, FT_UInt gindex)
Definition: ttpload.c:576
tt_face_load_cvt
tt_face_load_cvt(TT_Face face, FT_Stream stream)
Definition: ttpload.c:280
FT_TRACE1
#define FT_TRACE1(varformat)
Definition: ftdebug.h:158
tt_face_free_hdmx
tt_face_free_hdmx(TT_Face face)
Definition: ttpload.c:559
FT_Byte
unsigned char FT_Byte
Definition: fttypes.h:150
FT_StreamRec_::memory
FT_Memory memory
Definition: ftsystem.h:332
FT_FREE
#define FT_FREE(ptr)
Definition: ftmemory.h:286
result
GLuint64EXT * result
Definition: glew.h:12708
tt_face_load_hdmx
tt_face_load_hdmx(TT_Face face, FT_Stream stream)
Definition: ttpload.c:484
FT_LOCAL_DEF
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:467
TTAG_fpgm
#define TTAG_fpgm
Definition: tttags.h:54
error
FT_Error error
Definition: cffdrivr.c:407
ttgxvar.h
face
GLenum face
Definition: gl2ext.h:1490
p
GLfloat GLfloat p
Definition: glew.h:14938
FT_TRACE2
#define FT_TRACE2(varformat)
Definition: ftdebug.h:159
tterrors.h
TT_TableRec_
Definition: tttypes.h:130
limit
GLint limit
Definition: glew.h:11829
TTAG_loca
#define TTAG_loca
Definition: tttags.h:70
tt_face_vary_cvt
tt_face_vary_cvt(TT_Face face, FT_Stream stream)
FT_Short
signed short FT_Short
Definition: fttypes.h:194
FT_Memory
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
FT_FRAME_EXIT
#define FT_FRAME_EXIT()
Definition: ftstream.h:521
FT_NEW_ARRAY
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:290
FT_NEXT_USHORT
#define FT_NEXT_USHORT(buffer)
Definition: ftstream.h:233
FT_FRAME_RELEASE
#define FT_FRAME_RELEASE(bytes)
Definition: ftstream.h:529
ft2build.h
TTAG_cvt
#define TTAG_cvt
Definition: tttags.h:47
FT_UInt
unsigned int FT_UInt
Definition: fttypes.h:227
tt_face_load_prep
tt_face_load_prep(TT_Face face, FT_Stream stream)
Definition: ttpload.c:423
FT_NEXT_ULONG
#define FT_NEXT_ULONG(buffer)
Definition: ftstream.h:245
FT_FRAME_EXTRACT
#define FT_FRAME_EXTRACT(size, bytes)
Definition: ftstream.h:524
FT_GET_SHORT
#define FT_GET_SHORT()
Definition: ftstream.h:295
FT_FRAME_ENTER
#define FT_FRAME_ENTER(size)
Definition: ftstream.h:517
tt_face_load_fpgm
tt_face_load_fpgm(TT_Face face, FT_Stream stream)
Definition: ttpload.c:361
FT_StreamRec_
Definition: ftsystem.h:321
TT_FaceRec_
Definition: tttypes.h:1258
FT_UNUSED
#define FT_UNUSED(arg)
Definition: ftconfig.h:101
tt_face_get_location
tt_face_get_location(TT_Face face, FT_UInt gindex, FT_UInt *asize)
Definition: ttpload.c:173
tt_face_done_loca
tt_face_done_loca(TT_Face face)
Definition: ttpload.c:251
TTAG_prep
#define TTAG_prep
Definition: tttags.h:87