OLD | NEW |
| (Empty) |
1 /***************************************************************************/ | |
2 /* */ | |
3 /* ttobjs.c */ | |
4 /* */ | |
5 /* Objects manager (body). */ | |
6 /* */ | |
7 /* Copyright 1996-2013 */ | |
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/ftstream.h" | |
22 #include "../../include/freetype/tttags.h" | |
23 #include "../../include/freetype/internal/sfnt.h" | |
24 #include "../../include/freetype/ftttdrv.h" | |
25 | |
26 #include "ttgload.h" | |
27 #include "ttpload.h" | |
28 | |
29 #include "tterrors.h" | |
30 | |
31 #ifdef TT_USE_BYTECODE_INTERPRETER | |
32 #include "ttinterp.h" | |
33 #endif | |
34 | |
35 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING | |
36 #include "../../include/freetype/ttunpat.h" | |
37 #endif | |
38 | |
39 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT | |
40 #include "ttgxvar.h" | |
41 #endif | |
42 | |
43 /*************************************************************************/ | |
44 /* */ | |
45 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ | |
46 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ | |
47 /* messages during execution. */ | |
48 /* */ | |
49 #undef FT_COMPONENT | |
50 #define FT_COMPONENT trace_ttobjs | |
51 | |
52 | |
53 #ifdef TT_USE_BYTECODE_INTERPRETER | |
54 | |
55 /*************************************************************************/ | |
56 /* */ | |
57 /* GLYPH ZONE FUNCTIONS */ | |
58 /* */ | |
59 /*************************************************************************/ | |
60 | |
61 | |
62 /*************************************************************************/ | |
63 /* */ | |
64 /* <Function> */ | |
65 /* tt_glyphzone_done */ | |
66 /* */ | |
67 /* <Description> */ | |
68 /* Deallocate a glyph zone. */ | |
69 /* */ | |
70 /* <Input> */ | |
71 /* zone :: A pointer to the target glyph zone. */ | |
72 /* */ | |
73 FT_LOCAL_DEF( void ) | |
74 tt_glyphzone_done( TT_GlyphZone zone ) | |
75 { | |
76 FT_Memory memory = zone->memory; | |
77 | |
78 | |
79 if ( memory ) | |
80 { | |
81 FT_FREE( zone->contours ); | |
82 FT_FREE( zone->tags ); | |
83 FT_FREE( zone->cur ); | |
84 FT_FREE( zone->org ); | |
85 FT_FREE( zone->orus ); | |
86 | |
87 zone->max_points = zone->n_points = 0; | |
88 zone->max_contours = zone->n_contours = 0; | |
89 zone->memory = NULL; | |
90 } | |
91 } | |
92 | |
93 | |
94 /*************************************************************************/ | |
95 /* */ | |
96 /* <Function> */ | |
97 /* tt_glyphzone_new */ | |
98 /* */ | |
99 /* <Description> */ | |
100 /* Allocate a new glyph zone. */ | |
101 /* */ | |
102 /* <Input> */ | |
103 /* memory :: A handle to the current memory object. */ | |
104 /* */ | |
105 /* maxPoints :: The capacity of glyph zone in points. */ | |
106 /* */ | |
107 /* maxContours :: The capacity of glyph zone in contours. */ | |
108 /* */ | |
109 /* <Output> */ | |
110 /* zone :: A pointer to the target glyph zone record. */ | |
111 /* */ | |
112 /* <Return> */ | |
113 /* FreeType error code. 0 means success. */ | |
114 /* */ | |
115 FT_LOCAL_DEF( FT_Error ) | |
116 tt_glyphzone_new( FT_Memory memory, | |
117 FT_UShort maxPoints, | |
118 FT_Short maxContours, | |
119 TT_GlyphZone zone ) | |
120 { | |
121 FT_Error error; | |
122 | |
123 | |
124 FT_MEM_ZERO( zone, sizeof ( *zone ) ); | |
125 zone->memory = memory; | |
126 | |
127 if ( FT_NEW_ARRAY( zone->org, maxPoints ) || | |
128 FT_NEW_ARRAY( zone->cur, maxPoints ) || | |
129 FT_NEW_ARRAY( zone->orus, maxPoints ) || | |
130 FT_NEW_ARRAY( zone->tags, maxPoints ) || | |
131 FT_NEW_ARRAY( zone->contours, maxContours ) ) | |
132 { | |
133 tt_glyphzone_done( zone ); | |
134 } | |
135 else | |
136 { | |
137 zone->max_points = maxPoints; | |
138 zone->max_contours = maxContours; | |
139 } | |
140 | |
141 return error; | |
142 } | |
143 #endif /* TT_USE_BYTECODE_INTERPRETER */ | |
144 | |
145 | |
146 /* Compare the face with a list of well-known `tricky' fonts. */ | |
147 /* This list shall be expanded as we find more of them. */ | |
148 | |
149 static FT_Bool | |
150 tt_check_trickyness_family( FT_String* name ) | |
151 { | |
152 | |
153 #define TRICK_NAMES_MAX_CHARACTERS 16 | |
154 #define TRICK_NAMES_COUNT 8 | |
155 | |
156 static const char trick_names[TRICK_NAMES_COUNT] | |
157 [TRICK_NAMES_MAX_CHARACTERS + 1] = | |
158 { | |
159 "DFKaiSho-SB", /* dfkaisb.ttf */ | |
160 "DFKaiShu", | |
161 "DFKai-SB", /* kaiu.ttf */ | |
162 "HuaTianKaiTi?", /* htkt2.ttf */ | |
163 "HuaTianSongTi?", /* htst3.ttf */ | |
164 "MingLiU", /* mingliu.ttf & mingliu.ttc */ | |
165 "PMingLiU", /* mingliu.ttc */ | |
166 "MingLi43", /* mingli.ttf */ | |
167 }; | |
168 | |
169 int nn; | |
170 | |
171 | |
172 for ( nn = 0; nn < TRICK_NAMES_COUNT; nn++ ) | |
173 if ( ft_strstr( name, trick_names[nn] ) ) | |
174 return TRUE; | |
175 | |
176 return FALSE; | |
177 } | |
178 | |
179 | |
180 /* XXX: This function should be in the `sfnt' module. */ | |
181 | |
182 /* Some PDF generators clear the checksums in the TrueType header table. */ | |
183 /* For example, Quartz ContextPDF clears all entries, or Bullzip PDF */ | |
184 /* Printer clears the entries for subsetted subtables. We thus have to */ | |
185 /* recalculate the checksums where necessary. */ | |
186 | |
187 static FT_UInt32 | |
188 tt_synth_sfnt_checksum( FT_Stream stream, | |
189 FT_ULong length ) | |
190 { | |
191 FT_Error error; | |
192 FT_UInt32 checksum = 0; | |
193 int i; | |
194 | |
195 | |
196 if ( FT_FRAME_ENTER( length ) ) | |
197 return 0; | |
198 | |
199 for ( ; length > 3; length -= 4 ) | |
200 checksum += (FT_UInt32)FT_GET_ULONG(); | |
201 | |
202 for ( i = 3; length > 0; length --, i-- ) | |
203 checksum += (FT_UInt32)( FT_GET_BYTE() << ( i * 8 ) ); | |
204 | |
205 FT_FRAME_EXIT(); | |
206 | |
207 return checksum; | |
208 } | |
209 | |
210 | |
211 /* XXX: This function should be in the `sfnt' module. */ | |
212 | |
213 static FT_ULong | |
214 tt_get_sfnt_checksum( TT_Face face, | |
215 FT_UShort i ) | |
216 { | |
217 #if 0 /* if we believe the written value, use following part. */ | |
218 if ( face->dir_tables[i].CheckSum ) | |
219 return face->dir_tables[i].CheckSum; | |
220 #endif | |
221 | |
222 if ( !face->goto_table ) | |
223 return 0; | |
224 | |
225 if ( face->goto_table( face, | |
226 face->dir_tables[i].Tag, | |
227 face->root.stream, | |
228 NULL ) ) | |
229 return 0; | |
230 | |
231 return (FT_ULong)tt_synth_sfnt_checksum( face->root.stream, | |
232 face->dir_tables[i].Length ); | |
233 } | |
234 | |
235 | |
236 typedef struct tt_sfnt_id_rec_ | |
237 { | |
238 FT_ULong CheckSum; | |
239 FT_ULong Length; | |
240 | |
241 } tt_sfnt_id_rec; | |
242 | |
243 | |
244 static FT_Bool | |
245 tt_check_trickyness_sfnt_ids( TT_Face face ) | |
246 { | |
247 #define TRICK_SFNT_IDS_PER_FACE 3 | |
248 #define TRICK_SFNT_IDS_NUM_FACES 17 | |
249 | |
250 static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES] | |
251 [TRICK_SFNT_IDS_PER_FACE] = { | |
252 | |
253 #define TRICK_SFNT_ID_cvt 0 | |
254 #define TRICK_SFNT_ID_fpgm 1 | |
255 #define TRICK_SFNT_ID_prep 2 | |
256 | |
257 { /* MingLiU 1995 */ | |
258 { 0x05bcf058, 0x000002e4 }, /* cvt */ | |
259 { 0x28233bf1, 0x000087c4 }, /* fpgm */ | |
260 { 0xa344a1ea, 0x000001e1 } /* prep */ | |
261 }, | |
262 { /* MingLiU 1996- */ | |
263 { 0x05bcf058, 0x000002e4 }, /* cvt */ | |
264 { 0x28233bf1, 0x000087c4 }, /* fpgm */ | |
265 { 0xa344a1eb, 0x000001e1 } /* prep */ | |
266 }, | |
267 { /* DFKaiShu */ | |
268 { 0x11e5ead4, 0x00000350 }, /* cvt */ | |
269 { 0x5a30ca3b, 0x00009063 }, /* fpgm */ | |
270 { 0x13a42602, 0x0000007e } /* prep */ | |
271 }, | |
272 { /* HuaTianKaiTi */ | |
273 { 0xfffbfffc, 0x00000008 }, /* cvt */ | |
274 { 0x9c9e48b8, 0x0000bea2 }, /* fpgm */ | |
275 { 0x70020112, 0x00000008 } /* prep */ | |
276 }, | |
277 { /* HuaTianSongTi */ | |
278 { 0xfffbfffc, 0x00000008 }, /* cvt */ | |
279 { 0x0a5a0483, 0x00017c39 }, /* fpgm */ | |
280 { 0x70020112, 0x00000008 } /* prep */ | |
281 }, | |
282 { /* NEC fadpop7.ttf */ | |
283 { 0x00000000, 0x00000000 }, /* cvt */ | |
284 { 0x40c92555, 0x000000e5 }, /* fpgm */ | |
285 { 0xa39b58e3, 0x0000117c } /* prep */ | |
286 }, | |
287 { /* NEC fadrei5.ttf */ | |
288 { 0x00000000, 0x00000000 }, /* cvt */ | |
289 { 0x33c41652, 0x000000e5 }, /* fpgm */ | |
290 { 0x26d6c52a, 0x00000f6a } /* prep */ | |
291 }, | |
292 { /* NEC fangot7.ttf */ | |
293 { 0x00000000, 0x00000000 }, /* cvt */ | |
294 { 0x6db1651d, 0x0000019d }, /* fpgm */ | |
295 { 0x6c6e4b03, 0x00002492 } /* prep */ | |
296 }, | |
297 { /* NEC fangyo5.ttf */ | |
298 { 0x00000000, 0x00000000 }, /* cvt */ | |
299 { 0x40c92555, 0x000000e5 }, /* fpgm */ | |
300 { 0xde51fad0, 0x0000117c } /* prep */ | |
301 }, | |
302 { /* NEC fankyo5.ttf */ | |
303 { 0x00000000, 0x00000000 }, /* cvt */ | |
304 { 0x85e47664, 0x000000e5 }, /* fpgm */ | |
305 { 0xa6c62831, 0x00001caa } /* prep */ | |
306 }, | |
307 { /* NEC fanrgo5.ttf */ | |
308 { 0x00000000, 0x00000000 }, /* cvt */ | |
309 { 0x2d891cfd, 0x0000019d }, /* fpgm */ | |
310 { 0xa0604633, 0x00001de8 } /* prep */ | |
311 }, | |
312 { /* NEC fangot5.ttc */ | |
313 { 0x00000000, 0x00000000 }, /* cvt */ | |
314 { 0x40aa774c, 0x000001cb }, /* fpgm */ | |
315 { 0x9b5caa96, 0x00001f9a } /* prep */ | |
316 }, | |
317 { /* NEC fanmin3.ttc */ | |
318 { 0x00000000, 0x00000000 }, /* cvt */ | |
319 { 0x0d3de9cb, 0x00000141 }, /* fpgm */ | |
320 { 0xd4127766, 0x00002280 } /* prep */ | |
321 }, | |
322 { /* NEC FA-Gothic, 1996 */ | |
323 { 0x00000000, 0x00000000 }, /* cvt */ | |
324 { 0x4a692698, 0x000001f0 }, /* fpgm */ | |
325 { 0x340d4346, 0x00001fca } /* prep */ | |
326 }, | |
327 { /* NEC FA-Minchou, 1996 */ | |
328 { 0x00000000, 0x00000000 }, /* cvt */ | |
329 { 0xcd34c604, 0x00000166 }, /* fpgm */ | |
330 { 0x6cf31046, 0x000022b0 } /* prep */ | |
331 }, | |
332 { /* NEC FA-RoundGothicB, 1996 */ | |
333 { 0x00000000, 0x00000000 }, /* cvt */ | |
334 { 0x5da75315, 0x0000019d }, /* fpgm */ | |
335 { 0x40745a5f, 0x000022e0 } /* prep */ | |
336 }, | |
337 { /* NEC FA-RoundGothicM, 1996 */ | |
338 { 0x00000000, 0x00000000 }, /* cvt */ | |
339 { 0xf055fc48, 0x000001c2 }, /* fpgm */ | |
340 { 0x3900ded3, 0x00001e18 } /* prep */ | |
341 } | |
342 }; | |
343 | |
344 FT_ULong checksum; | |
345 int num_matched_ids[TRICK_SFNT_IDS_NUM_FACES]; | |
346 FT_Bool has_cvt, has_fpgm, has_prep; | |
347 FT_UShort i; | |
348 int j, k; | |
349 | |
350 | |
351 FT_MEM_SET( num_matched_ids, 0, | |
352 sizeof ( int ) * TRICK_SFNT_IDS_NUM_FACES ); | |
353 has_cvt = FALSE; | |
354 has_fpgm = FALSE; | |
355 has_prep = FALSE; | |
356 | |
357 for ( i = 0; i < face->num_tables; i++ ) | |
358 { | |
359 checksum = 0; | |
360 | |
361 switch( face->dir_tables[i].Tag ) | |
362 { | |
363 case TTAG_cvt: | |
364 k = TRICK_SFNT_ID_cvt; | |
365 has_cvt = TRUE; | |
366 break; | |
367 | |
368 case TTAG_fpgm: | |
369 k = TRICK_SFNT_ID_fpgm; | |
370 has_fpgm = TRUE; | |
371 break; | |
372 | |
373 case TTAG_prep: | |
374 k = TRICK_SFNT_ID_prep; | |
375 has_prep = TRUE; | |
376 break; | |
377 | |
378 default: | |
379 continue; | |
380 } | |
381 | |
382 for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ ) | |
383 if ( face->dir_tables[i].Length == sfnt_id[j][k].Length ) | |
384 { | |
385 if ( !checksum ) | |
386 checksum = tt_get_sfnt_checksum( face, i ); | |
387 | |
388 if ( sfnt_id[j][k].CheckSum == checksum ) | |
389 num_matched_ids[j]++; | |
390 | |
391 if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE ) | |
392 return TRUE; | |
393 } | |
394 } | |
395 | |
396 for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ ) | |
397 { | |
398 if ( !has_cvt && !sfnt_id[j][TRICK_SFNT_ID_cvt].Length ) | |
399 num_matched_ids[j] ++; | |
400 if ( !has_fpgm && !sfnt_id[j][TRICK_SFNT_ID_fpgm].Length ) | |
401 num_matched_ids[j] ++; | |
402 if ( !has_prep && !sfnt_id[j][TRICK_SFNT_ID_prep].Length ) | |
403 num_matched_ids[j] ++; | |
404 if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE ) | |
405 return TRUE; | |
406 } | |
407 | |
408 return FALSE; | |
409 } | |
410 | |
411 | |
412 static FT_Bool | |
413 tt_check_trickyness( FT_Face face ) | |
414 { | |
415 if ( !face ) | |
416 return FALSE; | |
417 | |
418 /* For first, check the face name for quick check. */ | |
419 if ( face->family_name && | |
420 tt_check_trickyness_family( face->family_name ) ) | |
421 return TRUE; | |
422 | |
423 /* Type42 fonts may lack `name' tables, we thus try to identify */ | |
424 /* tricky fonts by checking the checksums of Type42-persistent */ | |
425 /* sfnt tables (`cvt', `fpgm', and `prep'). */ | |
426 if ( tt_check_trickyness_sfnt_ids( (TT_Face)face ) ) | |
427 return TRUE; | |
428 | |
429 return FALSE; | |
430 } | |
431 | |
432 | |
433 /* Check whether `.notdef' is the only glyph in the `loca' table. */ | |
434 static FT_Bool | |
435 tt_check_single_notdef( FT_Face ttface ) | |
436 { | |
437 FT_Bool result = FALSE; | |
438 | |
439 TT_Face face = (TT_Face)ttface; | |
440 FT_UInt asize; | |
441 FT_ULong i; | |
442 FT_ULong glyph_index = 0; | |
443 FT_UInt count = 0; | |
444 | |
445 | |
446 for( i = 0; i < face->num_locations; i++ ) | |
447 { | |
448 tt_face_get_location( face, i, &asize ); | |
449 if ( asize > 0 ) | |
450 { | |
451 count += 1; | |
452 if ( count > 1 ) | |
453 break; | |
454 glyph_index = i; | |
455 } | |
456 } | |
457 | |
458 /* Only have a single outline. */ | |
459 if ( count == 1 ) | |
460 { | |
461 if ( glyph_index == 0 ) | |
462 result = TRUE; | |
463 else | |
464 { | |
465 /* FIXME: Need to test glyphname == .notdef ? */ | |
466 FT_Error error; | |
467 char buf[8]; | |
468 | |
469 | |
470 error = FT_Get_Glyph_Name( ttface, glyph_index, buf, 8 ); | |
471 if ( !error && | |
472 buf[0] == '.' && !ft_strncmp( buf, ".notdef", 8 ) ) | |
473 result = TRUE; | |
474 } | |
475 } | |
476 | |
477 return result; | |
478 } | |
479 | |
480 | |
481 /*************************************************************************/ | |
482 /* */ | |
483 /* <Function> */ | |
484 /* tt_face_init */ | |
485 /* */ | |
486 /* <Description> */ | |
487 /* Initialize a given TrueType face object. */ | |
488 /* */ | |
489 /* <Input> */ | |
490 /* stream :: The source font stream. */ | |
491 /* */ | |
492 /* face_index :: The index of the font face in the resource. */ | |
493 /* */ | |
494 /* num_params :: Number of additional generic parameters. Ignored. */ | |
495 /* */ | |
496 /* params :: Additional generic parameters. Ignored. */ | |
497 /* */ | |
498 /* <InOut> */ | |
499 /* face :: The newly built face object. */ | |
500 /* */ | |
501 /* <Return> */ | |
502 /* FreeType error code. 0 means success. */ | |
503 /* */ | |
504 FT_LOCAL_DEF( FT_Error ) | |
505 tt_face_init( FT_Stream stream, | |
506 FT_Face ttface, /* TT_Face */ | |
507 FT_Int face_index, | |
508 FT_Int num_params, | |
509 FT_Parameter* params ) | |
510 { | |
511 FT_Error error; | |
512 FT_Library library; | |
513 SFNT_Service sfnt; | |
514 TT_Face face = (TT_Face)ttface; | |
515 | |
516 | |
517 FT_TRACE2(( "TTF driver\n" )); | |
518 | |
519 library = ttface->driver->root.library; | |
520 | |
521 sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" ); | |
522 if ( !sfnt ) | |
523 { | |
524 FT_ERROR(( "tt_face_init: cannot access `sfnt' module\n" )); | |
525 error = FT_THROW( Missing_Module ); | |
526 goto Exit; | |
527 } | |
528 | |
529 /* create input stream from resource */ | |
530 if ( FT_STREAM_SEEK( 0 ) ) | |
531 goto Exit; | |
532 | |
533 /* check that we have a valid TrueType file */ | |
534 error = sfnt->init_face( stream, face, face_index, num_params, params ); | |
535 if ( error ) | |
536 goto Exit; | |
537 | |
538 /* We must also be able to accept Mac/GX fonts, as well as OT ones. */ | |
539 /* The 0x00020000 tag is completely undocumented; some fonts from */ | |
540 /* Arphic made for Chinese Windows 3.1 have this. */ | |
541 if ( face->format_tag != 0x00010000L && /* MS fonts */ | |
542 face->format_tag != 0x00020000L && /* CJK fonts for Win 3.1 */ | |
543 face->format_tag != TTAG_true ) /* Mac fonts */ | |
544 { | |
545 FT_TRACE2(( " not a TTF font\n" )); | |
546 goto Bad_Format; | |
547 } | |
548 else | |
549 { | |
550 FT_ULong table_len; | |
551 if (face->goto_table( face, TTAG_CFF, stream, &table_len) != TT_
Err_Table_Missing && | |
552 face->goto_table( face, TTAG_loca, stream, &table_len) =
= TT_Err_Table_Missing) | |
553 { | |
554 FT_TRACE2(( "[not a valid TTF font]\n" )); | |
555 goto Bad_Format; | |
556 } | |
557 } | |
558 | |
559 #ifdef TT_USE_BYTECODE_INTERPRETER | |
560 ttface->face_flags |= FT_FACE_FLAG_HINTER; | |
561 #endif | |
562 | |
563 /* If we are performing a simple font format check, exit immediately. */ | |
564 if ( face_index < 0 ) | |
565 return FT_Err_Ok; | |
566 | |
567 /* Load font directory */ | |
568 error = sfnt->load_face( stream, face, face_index, num_params, params ); | |
569 if ( error ) | |
570 goto Exit; | |
571 | |
572 if ( tt_check_trickyness( ttface ) ) | |
573 ttface->face_flags |= FT_FACE_FLAG_TRICKY; | |
574 | |
575 error = tt_face_load_hdmx( face, stream ); | |
576 if ( error ) | |
577 goto Exit; | |
578 | |
579 if ( FT_IS_SCALABLE( ttface ) ) | |
580 { | |
581 | |
582 #ifdef FT_CONFIG_OPTION_INCREMENTAL | |
583 | |
584 if ( !ttface->internal->incremental_interface ) | |
585 error = tt_face_load_loca( face, stream ); | |
586 if ( !error ) | |
587 error = tt_face_load_cvt( face, stream ); | |
588 if ( !error ) | |
589 error = tt_face_load_fpgm( face, stream ); | |
590 if ( !error ) | |
591 error = tt_face_load_prep( face, stream ); | |
592 | |
593 /* Check the scalable flag based on `loca'. */ | |
594 if ( !ttface->internal->incremental_interface && | |
595 ttface->num_fixed_sizes && | |
596 face->glyph_locations && | |
597 tt_check_single_notdef( ttface ) ) | |
598 { | |
599 FT_TRACE5(( "tt_face_init:" | |
600 " Only the `.notdef' glyph has an outline.\n" | |
601 " " | |
602 " Resetting scalable flag to FALSE.\n" )); | |
603 | |
604 ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; | |
605 } | |
606 | |
607 #else | |
608 | |
609 if ( !error ) | |
610 error = tt_face_load_loca( face, stream ); | |
611 if ( !error ) | |
612 error = tt_face_load_cvt( face, stream ); | |
613 if ( !error ) | |
614 error = tt_face_load_fpgm( face, stream ); | |
615 if ( !error ) | |
616 error = tt_face_load_prep( face, stream ); | |
617 | |
618 /* Check the scalable flag based on `loca'. */ | |
619 if ( ttface->num_fixed_sizes && | |
620 face->glyph_locations && | |
621 tt_check_single_notdef( ttface ) ) | |
622 { | |
623 FT_TRACE5(( "tt_face_init:" | |
624 " Only the `.notdef' glyph has an outline.\n" | |
625 " " | |
626 " Resetting scalable flag to FALSE.\n" )); | |
627 | |
628 ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; | |
629 } | |
630 | |
631 #endif | |
632 | |
633 } | |
634 | |
635 #if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \ | |
636 !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER ) | |
637 | |
638 { | |
639 FT_Bool unpatented_hinting; | |
640 int i; | |
641 | |
642 | |
643 /* Determine whether unpatented hinting is to be used for this face. */ | |
644 unpatented_hinting = FT_BOOL | |
645 ( library->debug_hooks[FT_DEBUG_HOOK_UNPATENTED_HINTING] != NULL ); | |
646 | |
647 for ( i = 0; i < num_params && !face->unpatented_hinting; i++ ) | |
648 if ( params[i].tag == FT_PARAM_TAG_UNPATENTED_HINTING ) | |
649 unpatented_hinting = TRUE; | |
650 | |
651 if ( !unpatented_hinting ) | |
652 ttface->internal->ignore_unpatented_hinter = TRUE; | |
653 } | |
654 | |
655 #endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING && | |
656 !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ | |
657 | |
658 /* initialize standard glyph loading routines */ | |
659 TT_Init_Glyph_Loading( face ); | |
660 | |
661 Exit: | |
662 return error; | |
663 | |
664 Bad_Format: | |
665 error = FT_THROW( Unknown_File_Format ); | |
666 goto Exit; | |
667 } | |
668 | |
669 | |
670 /*************************************************************************/ | |
671 /* */ | |
672 /* <Function> */ | |
673 /* tt_face_done */ | |
674 /* */ | |
675 /* <Description> */ | |
676 /* Finalize a given face object. */ | |
677 /* */ | |
678 /* <Input> */ | |
679 /* face :: A pointer to the face object to destroy. */ | |
680 /* */ | |
681 FT_LOCAL_DEF( void ) | |
682 tt_face_done( FT_Face ttface ) /* TT_Face */ | |
683 { | |
684 TT_Face face = (TT_Face)ttface; | |
685 FT_Memory memory; | |
686 FT_Stream stream; | |
687 SFNT_Service sfnt; | |
688 | |
689 | |
690 if ( !face ) | |
691 return; | |
692 | |
693 memory = ttface->memory; | |
694 stream = ttface->stream; | |
695 sfnt = (SFNT_Service)face->sfnt; | |
696 | |
697 /* for `extended TrueType formats' (i.e. compressed versions) */ | |
698 if ( face->extra.finalizer ) | |
699 face->extra.finalizer( face->extra.data ); | |
700 | |
701 if ( sfnt ) | |
702 sfnt->done_face( face ); | |
703 | |
704 /* freeing the locations table */ | |
705 tt_face_done_loca( face ); | |
706 | |
707 tt_face_free_hdmx( face ); | |
708 | |
709 /* freeing the CVT */ | |
710 FT_FREE( face->cvt ); | |
711 face->cvt_size = 0; | |
712 | |
713 /* freeing the programs */ | |
714 FT_FRAME_RELEASE( face->font_program ); | |
715 FT_FRAME_RELEASE( face->cvt_program ); | |
716 face->font_program_size = 0; | |
717 face->cvt_program_size = 0; | |
718 | |
719 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT | |
720 tt_done_blend( memory, face->blend ); | |
721 face->blend = NULL; | |
722 #endif | |
723 } | |
724 | |
725 | |
726 /*************************************************************************/ | |
727 /* */ | |
728 /* SIZE FUNCTIONS */ | |
729 /* */ | |
730 /*************************************************************************/ | |
731 | |
732 #ifdef TT_USE_BYTECODE_INTERPRETER | |
733 | |
734 /*************************************************************************/ | |
735 /* */ | |
736 /* <Function> */ | |
737 /* tt_size_run_fpgm */ | |
738 /* */ | |
739 /* <Description> */ | |
740 /* Run the font program. */ | |
741 /* */ | |
742 /* <Input> */ | |
743 /* size :: A handle to the size object. */ | |
744 /* */ | |
745 /* pedantic :: Set if bytecode execution should be pedantic. */ | |
746 /* */ | |
747 /* <Return> */ | |
748 /* FreeType error code. 0 means success. */ | |
749 /* */ | |
750 FT_LOCAL_DEF( FT_Error ) | |
751 tt_size_run_fpgm( TT_Size size, | |
752 FT_Bool pedantic ) | |
753 { | |
754 TT_Face face = (TT_Face)size->root.face; | |
755 TT_ExecContext exec; | |
756 FT_Error error; | |
757 | |
758 | |
759 /* debugging instances have their own context */ | |
760 if ( size->debug ) | |
761 exec = size->context; | |
762 else | |
763 exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context; | |
764 | |
765 if ( !exec ) | |
766 return FT_THROW( Could_Not_Find_Context ); | |
767 | |
768 TT_Load_Context( exec, face, size ); | |
769 | |
770 exec->callTop = 0; | |
771 exec->top = 0; | |
772 | |
773 exec->period = 64; | |
774 exec->phase = 0; | |
775 exec->threshold = 0; | |
776 | |
777 exec->instruction_trap = FALSE; | |
778 exec->F_dot_P = 0x4000L; | |
779 | |
780 exec->pedantic_hinting = pedantic; | |
781 | |
782 { | |
783 FT_Size_Metrics* metrics = &exec->metrics; | |
784 TT_Size_Metrics* tt_metrics = &exec->tt_metrics; | |
785 | |
786 | |
787 metrics->x_ppem = 0; | |
788 metrics->y_ppem = 0; | |
789 metrics->x_scale = 0; | |
790 metrics->y_scale = 0; | |
791 | |
792 tt_metrics->ppem = 0; | |
793 tt_metrics->scale = 0; | |
794 tt_metrics->ratio = 0x10000L; | |
795 } | |
796 | |
797 /* allow font program execution */ | |
798 TT_Set_CodeRange( exec, | |
799 tt_coderange_font, | |
800 face->font_program, | |
801 face->font_program_size ); | |
802 | |
803 /* disable CVT and glyph programs coderange */ | |
804 TT_Clear_CodeRange( exec, tt_coderange_cvt ); | |
805 TT_Clear_CodeRange( exec, tt_coderange_glyph ); | |
806 | |
807 if ( face->font_program_size > 0 ) | |
808 { | |
809 error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 ); | |
810 | |
811 if ( !error ) | |
812 { | |
813 FT_TRACE4(( "Executing `fpgm' table.\n" )); | |
814 | |
815 error = face->interpreter( exec ); | |
816 } | |
817 } | |
818 else | |
819 error = FT_Err_Ok; | |
820 | |
821 if ( !error ) | |
822 TT_Save_Context( exec, size ); | |
823 | |
824 return error; | |
825 } | |
826 | |
827 | |
828 /*************************************************************************/ | |
829 /* */ | |
830 /* <Function> */ | |
831 /* tt_size_run_prep */ | |
832 /* */ | |
833 /* <Description> */ | |
834 /* Run the control value program. */ | |
835 /* */ | |
836 /* <Input> */ | |
837 /* size :: A handle to the size object. */ | |
838 /* */ | |
839 /* pedantic :: Set if bytecode execution should be pedantic. */ | |
840 /* */ | |
841 /* <Return> */ | |
842 /* FreeType error code. 0 means success. */ | |
843 /* */ | |
844 FT_LOCAL_DEF( FT_Error ) | |
845 tt_size_run_prep( TT_Size size, | |
846 FT_Bool pedantic ) | |
847 { | |
848 TT_Face face = (TT_Face)size->root.face; | |
849 TT_ExecContext exec; | |
850 FT_Error error; | |
851 | |
852 | |
853 /* debugging instances have their own context */ | |
854 if ( size->debug ) | |
855 exec = size->context; | |
856 else | |
857 exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context; | |
858 | |
859 if ( !exec ) | |
860 return FT_THROW( Could_Not_Find_Context ); | |
861 | |
862 TT_Load_Context( exec, face, size ); | |
863 | |
864 exec->callTop = 0; | |
865 exec->top = 0; | |
866 | |
867 exec->instruction_trap = FALSE; | |
868 | |
869 exec->pedantic_hinting = pedantic; | |
870 | |
871 TT_Set_CodeRange( exec, | |
872 tt_coderange_cvt, | |
873 face->cvt_program, | |
874 face->cvt_program_size ); | |
875 | |
876 TT_Clear_CodeRange( exec, tt_coderange_glyph ); | |
877 | |
878 if ( face->cvt_program_size > 0 ) | |
879 { | |
880 error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 ); | |
881 | |
882 if ( !error && !size->debug ) | |
883 { | |
884 FT_TRACE4(( "Executing `prep' table.\n" )); | |
885 | |
886 error = face->interpreter( exec ); | |
887 } | |
888 } | |
889 else | |
890 error = FT_Err_Ok; | |
891 | |
892 /* UNDOCUMENTED! The MS rasterizer doesn't allow the following */ | |
893 /* graphics state variables to be modified by the CVT program. */ | |
894 | |
895 exec->GS.dualVector.x = 0x4000; | |
896 exec->GS.dualVector.y = 0; | |
897 exec->GS.projVector.x = 0x4000; | |
898 exec->GS.projVector.y = 0x0; | |
899 exec->GS.freeVector.x = 0x4000; | |
900 exec->GS.freeVector.y = 0x0; | |
901 | |
902 exec->GS.rp0 = 0; | |
903 exec->GS.rp1 = 0; | |
904 exec->GS.rp2 = 0; | |
905 | |
906 exec->GS.gep0 = 1; | |
907 exec->GS.gep1 = 1; | |
908 exec->GS.gep2 = 1; | |
909 | |
910 exec->GS.loop = 1; | |
911 | |
912 /* save as default graphics state */ | |
913 size->GS = exec->GS; | |
914 | |
915 TT_Save_Context( exec, size ); | |
916 | |
917 return error; | |
918 } | |
919 | |
920 #endif /* TT_USE_BYTECODE_INTERPRETER */ | |
921 | |
922 | |
923 #ifdef TT_USE_BYTECODE_INTERPRETER | |
924 | |
925 static void | |
926 tt_size_done_bytecode( FT_Size ftsize ) | |
927 { | |
928 TT_Size size = (TT_Size)ftsize; | |
929 TT_Face face = (TT_Face)ftsize->face; | |
930 FT_Memory memory = face->root.memory; | |
931 | |
932 | |
933 if ( size->debug ) | |
934 { | |
935 /* the debug context must be deleted by the debugger itself */ | |
936 size->context = NULL; | |
937 size->debug = FALSE; | |
938 } | |
939 | |
940 FT_FREE( size->cvt ); | |
941 size->cvt_size = 0; | |
942 | |
943 /* free storage area */ | |
944 FT_FREE( size->storage ); | |
945 size->storage_size = 0; | |
946 | |
947 /* twilight zone */ | |
948 tt_glyphzone_done( &size->twilight ); | |
949 | |
950 FT_FREE( size->function_defs ); | |
951 FT_FREE( size->instruction_defs ); | |
952 | |
953 size->num_function_defs = 0; | |
954 size->max_function_defs = 0; | |
955 size->num_instruction_defs = 0; | |
956 size->max_instruction_defs = 0; | |
957 | |
958 size->max_func = 0; | |
959 size->max_ins = 0; | |
960 | |
961 size->bytecode_ready = 0; | |
962 size->cvt_ready = 0; | |
963 } | |
964 | |
965 | |
966 /* Initialize bytecode-related fields in the size object. */ | |
967 /* We do this only if bytecode interpretation is really needed. */ | |
968 static FT_Error | |
969 tt_size_init_bytecode( FT_Size ftsize, | |
970 FT_Bool pedantic ) | |
971 { | |
972 FT_Error error; | |
973 TT_Size size = (TT_Size)ftsize; | |
974 TT_Face face = (TT_Face)ftsize->face; | |
975 FT_Memory memory = face->root.memory; | |
976 FT_Int i; | |
977 | |
978 FT_UShort n_twilight; | |
979 TT_MaxProfile* maxp = &face->max_profile; | |
980 | |
981 | |
982 size->bytecode_ready = 1; | |
983 size->cvt_ready = 0; | |
984 | |
985 size->max_function_defs = maxp->maxFunctionDefs; | |
986 size->max_instruction_defs = maxp->maxInstructionDefs; | |
987 | |
988 size->num_function_defs = 0; | |
989 size->num_instruction_defs = 0; | |
990 | |
991 size->max_func = 0; | |
992 size->max_ins = 0; | |
993 | |
994 size->cvt_size = face->cvt_size; | |
995 size->storage_size = maxp->maxStorage; | |
996 | |
997 /* Set default metrics */ | |
998 { | |
999 TT_Size_Metrics* metrics = &size->ttmetrics; | |
1000 | |
1001 | |
1002 metrics->rotated = FALSE; | |
1003 metrics->stretched = FALSE; | |
1004 | |
1005 /* set default compensation (all 0) */ | |
1006 for ( i = 0; i < 4; i++ ) | |
1007 metrics->compensations[i] = 0; | |
1008 } | |
1009 | |
1010 /* allocate function defs, instruction defs, cvt, and storage area */ | |
1011 if ( FT_NEW_ARRAY( size->function_defs, size->max_function_defs ) || | |
1012 FT_NEW_ARRAY( size->instruction_defs, size->max_instruction_defs ) || | |
1013 FT_NEW_ARRAY( size->cvt, size->cvt_size ) || | |
1014 FT_NEW_ARRAY( size->storage, size->storage_size ) ) | |
1015 goto Exit; | |
1016 | |
1017 /* reserve twilight zone */ | |
1018 n_twilight = maxp->maxTwilightPoints; | |
1019 | |
1020 /* there are 4 phantom points (do we need this?) */ | |
1021 n_twilight += 4; | |
1022 | |
1023 error = tt_glyphzone_new( memory, n_twilight, 0, &size->twilight ); | |
1024 if ( error ) | |
1025 goto Exit; | |
1026 | |
1027 size->twilight.n_points = n_twilight; | |
1028 | |
1029 size->GS = tt_default_graphics_state; | |
1030 | |
1031 /* set `face->interpreter' according to the debug hook present */ | |
1032 { | |
1033 FT_Library library = face->root.driver->root.library; | |
1034 | |
1035 | |
1036 face->interpreter = (TT_Interpreter) | |
1037 library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE]; | |
1038 if ( !face->interpreter ) | |
1039 face->interpreter = (TT_Interpreter)TT_RunIns; | |
1040 } | |
1041 | |
1042 /* Fine, now run the font program! */ | |
1043 error = tt_size_run_fpgm( size, pedantic ); | |
1044 /* It seems fpgm proc is causing some problem for some font, so we ignor
e the error. TESTDOC: Bug #12690 - Restaurantkarte_Oktober09+Wild.pdf*/ | |
1045 if ( error ) | |
1046 tt_size_done_bytecode( ftsize ); | |
1047 return TT_Err_Ok; | |
1048 | |
1049 Exit: | |
1050 if ( error ) | |
1051 tt_size_done_bytecode( ftsize ); | |
1052 | |
1053 return error; | |
1054 } | |
1055 | |
1056 | |
1057 FT_LOCAL_DEF( FT_Error ) | |
1058 tt_size_ready_bytecode( TT_Size size, | |
1059 FT_Bool pedantic ) | |
1060 { | |
1061 FT_Error error = FT_Err_Ok; | |
1062 | |
1063 | |
1064 if ( !size->bytecode_ready ) | |
1065 { | |
1066 error = tt_size_init_bytecode( (FT_Size)size, pedantic ); | |
1067 if ( error ) | |
1068 goto Exit; | |
1069 } | |
1070 | |
1071 /* rescale CVT when needed */ | |
1072 if ( !size->cvt_ready ) | |
1073 { | |
1074 FT_UInt i; | |
1075 TT_Face face = (TT_Face)size->root.face; | |
1076 | |
1077 | |
1078 /* Scale the cvt values to the new ppem. */ | |
1079 /* We use by default the y ppem to scale the CVT. */ | |
1080 for ( i = 0; i < size->cvt_size; i++ ) | |
1081 size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); | |
1082 | |
1083 /* all twilight points are originally zero */ | |
1084 for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ ) | |
1085 { | |
1086 size->twilight.org[i].x = 0; | |
1087 size->twilight.org[i].y = 0; | |
1088 size->twilight.cur[i].x = 0; | |
1089 size->twilight.cur[i].y = 0; | |
1090 } | |
1091 | |
1092 /* clear storage area */ | |
1093 for ( i = 0; i < (FT_UInt)size->storage_size; i++ ) | |
1094 size->storage[i] = 0; | |
1095 | |
1096 size->GS = tt_default_graphics_state; | |
1097 | |
1098 tt_size_run_prep( size, pedantic );/* It seems prep proc is causing some p
roblem for some font, so we ignore the error. TESTDOC: Bug #5025 - naredba-rd-16
-296.pdf */ | |
1099 /* However we can't disable the prep. TESTDOC: Bug #0063 - 050826_diff
er_table.pdf, page #4 */ | |
1100 if ( !error ) | |
1101 size->cvt_ready = 1; | |
1102 } | |
1103 | |
1104 Exit: | |
1105 return error; | |
1106 } | |
1107 | |
1108 #endif /* TT_USE_BYTECODE_INTERPRETER */ | |
1109 | |
1110 | |
1111 /*************************************************************************/ | |
1112 /* */ | |
1113 /* <Function> */ | |
1114 /* tt_size_init */ | |
1115 /* */ | |
1116 /* <Description> */ | |
1117 /* Initialize a new TrueType size object. */ | |
1118 /* */ | |
1119 /* <InOut> */ | |
1120 /* size :: A handle to the size object. */ | |
1121 /* */ | |
1122 /* <Return> */ | |
1123 /* FreeType error code. 0 means success. */ | |
1124 /* */ | |
1125 FT_LOCAL_DEF( FT_Error ) | |
1126 tt_size_init( FT_Size ttsize ) /* TT_Size */ | |
1127 { | |
1128 TT_Size size = (TT_Size)ttsize; | |
1129 FT_Error error = FT_Err_Ok; | |
1130 | |
1131 #ifdef TT_USE_BYTECODE_INTERPRETER | |
1132 size->bytecode_ready = 0; | |
1133 size->cvt_ready = 0; | |
1134 #endif | |
1135 | |
1136 size->ttmetrics.valid = FALSE; | |
1137 size->strike_index = 0xFFFFFFFFUL; | |
1138 | |
1139 return error; | |
1140 } | |
1141 | |
1142 | |
1143 /*************************************************************************/ | |
1144 /* */ | |
1145 /* <Function> */ | |
1146 /* tt_size_done */ | |
1147 /* */ | |
1148 /* <Description> */ | |
1149 /* The TrueType size object finalizer. */ | |
1150 /* */ | |
1151 /* <Input> */ | |
1152 /* size :: A handle to the target size object. */ | |
1153 /* */ | |
1154 FT_LOCAL_DEF( void ) | |
1155 tt_size_done( FT_Size ttsize ) /* TT_Size */ | |
1156 { | |
1157 TT_Size size = (TT_Size)ttsize; | |
1158 | |
1159 | |
1160 #ifdef TT_USE_BYTECODE_INTERPRETER | |
1161 if ( size->bytecode_ready ) | |
1162 tt_size_done_bytecode( ttsize ); | |
1163 #endif | |
1164 | |
1165 size->ttmetrics.valid = FALSE; | |
1166 } | |
1167 | |
1168 | |
1169 /*************************************************************************/ | |
1170 /* */ | |
1171 /* <Function> */ | |
1172 /* tt_size_reset */ | |
1173 /* */ | |
1174 /* <Description> */ | |
1175 /* Reset a TrueType size when resolutions and character dimensions */ | |
1176 /* have been changed. */ | |
1177 /* */ | |
1178 /* <Input> */ | |
1179 /* size :: A handle to the target size object. */ | |
1180 /* */ | |
1181 FT_LOCAL_DEF( FT_Error ) | |
1182 tt_size_reset( TT_Size size ) | |
1183 { | |
1184 TT_Face face; | |
1185 FT_Error error = FT_Err_Ok; | |
1186 FT_Size_Metrics* metrics; | |
1187 | |
1188 | |
1189 size->ttmetrics.valid = FALSE; | |
1190 | |
1191 face = (TT_Face)size->root.face; | |
1192 | |
1193 metrics = &size->metrics; | |
1194 | |
1195 /* copy the result from base layer */ | |
1196 *metrics = size->root.metrics; | |
1197 | |
1198 if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 ) | |
1199 return FT_THROW( Invalid_PPem ); | |
1200 | |
1201 /* This bit flag, if set, indicates that the ppems must be */ | |
1202 /* rounded to integers. Nearly all TrueType fonts have this bit */ | |
1203 /* set, as hinting won't work really well otherwise. */ | |
1204 /* */ | |
1205 if ( face->header.Flags & 8 ) | |
1206 { | |
1207 metrics->x_scale = FT_DivFix( metrics->x_ppem << 6, | |
1208 face->root.units_per_EM ); | |
1209 metrics->y_scale = FT_DivFix( metrics->y_ppem << 6, | |
1210 face->root.units_per_EM ); | |
1211 | |
1212 metrics->ascender = | |
1213 FT_PIX_ROUND( FT_MulFix( face->root.ascender, metrics->y_scale ) ); | |
1214 metrics->descender = | |
1215 FT_PIX_ROUND( FT_MulFix( face->root.descender, metrics->y_scale ) ); | |
1216 metrics->height = | |
1217 FT_PIX_ROUND( FT_MulFix( face->root.height, metrics->y_scale ) ); | |
1218 metrics->max_advance = | |
1219 FT_PIX_ROUND( FT_MulFix( face->root.max_advance_width, | |
1220 metrics->x_scale ) ); | |
1221 } | |
1222 | |
1223 /* compute new transformation */ | |
1224 if ( metrics->x_ppem >= metrics->y_ppem ) | |
1225 { | |
1226 size->ttmetrics.scale = metrics->x_scale; | |
1227 size->ttmetrics.ppem = metrics->x_ppem; | |
1228 size->ttmetrics.x_ratio = 0x10000L; | |
1229 size->ttmetrics.y_ratio = FT_DivFix( metrics->y_ppem, | |
1230 metrics->x_ppem ); | |
1231 } | |
1232 else | |
1233 { | |
1234 size->ttmetrics.scale = metrics->y_scale; | |
1235 size->ttmetrics.ppem = metrics->y_ppem; | |
1236 size->ttmetrics.x_ratio = FT_DivFix( metrics->x_ppem, | |
1237 metrics->y_ppem ); | |
1238 size->ttmetrics.y_ratio = 0x10000L; | |
1239 } | |
1240 | |
1241 #ifdef TT_USE_BYTECODE_INTERPRETER | |
1242 size->cvt_ready = 0; | |
1243 #endif /* TT_USE_BYTECODE_INTERPRETER */ | |
1244 | |
1245 if ( !error ) | |
1246 size->ttmetrics.valid = TRUE; | |
1247 | |
1248 return error; | |
1249 } | |
1250 | |
1251 | |
1252 /*************************************************************************/ | |
1253 /* */ | |
1254 /* <Function> */ | |
1255 /* tt_driver_init */ | |
1256 /* */ | |
1257 /* <Description> */ | |
1258 /* Initialize a given TrueType driver object. */ | |
1259 /* */ | |
1260 /* <Input> */ | |
1261 /* driver :: A handle to the target driver object. */ | |
1262 /* */ | |
1263 /* <Return> */ | |
1264 /* FreeType error code. 0 means success. */ | |
1265 /* */ | |
1266 FT_LOCAL_DEF( FT_Error ) | |
1267 tt_driver_init( FT_Module ttdriver ) /* TT_Driver */ | |
1268 { | |
1269 | |
1270 #ifdef TT_USE_BYTECODE_INTERPRETER | |
1271 | |
1272 TT_Driver driver = (TT_Driver)ttdriver; | |
1273 | |
1274 | |
1275 if ( !TT_New_Context( driver ) ) | |
1276 return FT_THROW( Could_Not_Find_Context ); | |
1277 | |
1278 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING | |
1279 driver->interpreter_version = TT_INTERPRETER_VERSION_38; | |
1280 #else | |
1281 driver->interpreter_version = TT_INTERPRETER_VERSION_35; | |
1282 #endif | |
1283 | |
1284 #else /* !TT_USE_BYTECODE_INTERPRETER */ | |
1285 | |
1286 FT_UNUSED( ttdriver ); | |
1287 | |
1288 #endif /* !TT_USE_BYTECODE_INTERPRETER */ | |
1289 | |
1290 return FT_Err_Ok; | |
1291 } | |
1292 | |
1293 | |
1294 /*************************************************************************/ | |
1295 /* */ | |
1296 /* <Function> */ | |
1297 /* tt_driver_done */ | |
1298 /* */ | |
1299 /* <Description> */ | |
1300 /* Finalize a given TrueType driver. */ | |
1301 /* */ | |
1302 /* <Input> */ | |
1303 /* driver :: A handle to the target TrueType driver. */ | |
1304 /* */ | |
1305 FT_LOCAL_DEF( void ) | |
1306 tt_driver_done( FT_Module ttdriver ) /* TT_Driver */ | |
1307 { | |
1308 #ifdef TT_USE_BYTECODE_INTERPRETER | |
1309 TT_Driver driver = (TT_Driver)ttdriver; | |
1310 | |
1311 | |
1312 /* destroy the execution context */ | |
1313 if ( driver->context ) | |
1314 { | |
1315 TT_Done_Context( driver->context ); | |
1316 driver->context = NULL; | |
1317 } | |
1318 #else | |
1319 FT_UNUSED( ttdriver ); | |
1320 #endif | |
1321 | |
1322 } | |
1323 | |
1324 | |
1325 /*************************************************************************/ | |
1326 /* */ | |
1327 /* <Function> */ | |
1328 /* tt_slot_init */ | |
1329 /* */ | |
1330 /* <Description> */ | |
1331 /* Initialize a new slot object. */ | |
1332 /* */ | |
1333 /* <InOut> */ | |
1334 /* slot :: A handle to the slot object. */ | |
1335 /* */ | |
1336 /* <Return> */ | |
1337 /* FreeType error code. 0 means success. */ | |
1338 /* */ | |
1339 FT_LOCAL_DEF( FT_Error ) | |
1340 tt_slot_init( FT_GlyphSlot slot ) | |
1341 { | |
1342 return FT_GlyphLoader_CreateExtra( slot->internal->loader ); | |
1343 } | |
1344 | |
1345 | |
1346 /* END */ | |
OLD | NEW |