blob: 38a80f241494ef123fdd5463714ba8bae83f884f [file] [log] [blame]
David Turnerd2b1f351999-12-16 23:11:37 +00001/***************************************************************************/
2/* */
3/* ttobjs.c */
4/* */
5/* Objects manager (body). */
6/* */
Werner Lemberg78575dc2000-06-12 19:36:41 +00007/* Copyright 1996-2000 by */
David Turnerd2b1f351999-12-16 23:11:37 +00008/* David Turner, Robert Wilhelm, and Werner Lemberg. */
9/* */
Werner Lemberg78575dc2000-06-12 19:36:41 +000010/* This file is part of the FreeType project, and may only be used, */
11/* modified, and distributed under the terms of the FreeType project */
David Turnerd2b1f351999-12-16 23:11:37 +000012/* 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
David Turnerefce08d2000-05-11 18:23:52 +000019#include <freetype/internal/ftdebug.h>
20#include <freetype/internal/ftcalc.h>
21#include <freetype/internal/ftstream.h>
22#include <freetype/ttnameid.h>
23#include <freetype/tttags.h>
David Turnerd2b1f351999-12-16 23:11:37 +000024
David Turnerefce08d2000-05-11 18:23:52 +000025#include <freetype/internal/sfnt.h>
26#include <freetype/internal/psnames.h>
David Turner8f43c712000-02-02 12:16:19 +000027#include <ttobjs.h>
David Turnerd2b1f351999-12-16 23:11:37 +000028
29#include <ttpload.h>
David Turner994d7742000-06-25 04:49:19 +000030#include <ttgload.h>
Werner Lemberge1d5dd72000-06-07 04:48:12 +000031#include <freetype/internal/tterrors.h>
David Turnerd2b1f351999-12-16 23:11:37 +000032
David Turner8f43c712000-02-02 12:16:19 +000033#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
34#include <ttinterp.h>
35#endif
36
Werner Lemberg78575dc2000-06-12 19:36:41 +000037
38 /*************************************************************************/
39 /* */
40 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
41 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
42 /* messages during execution. */
43 /* */
Werner Lemberg5811c7c2000-07-02 13:53:16 +000044#undef FT_COMPONENT
45#define FT_COMPONENT trace_ttobjs
David Turnerd2b1f351999-12-16 23:11:37 +000046
47
48 /*************************************************************************/
49 /* */
50 /* GLYPH ZONE FUNCTIONS */
51 /* */
52 /*************************************************************************/
53
David Turnerf9b8dec2000-06-16 19:34:52 +000054 /*************************************************************************/
55 /* */
56 /* <Function> */
57 /* TT_Done_GlyphZone */
58 /* */
59 /* <Description> */
60 /* Deallocates a glyph zone. */
61 /* */
62 /* <Input> */
63 /* zone :: A pointer to the target glyph zone. */
64 /* */
Werner Lemberg5811c7c2000-07-02 13:53:16 +000065 LOCAL_FUNC
66 void TT_Done_GlyphZone( TT_GlyphZone* zone )
David Turnerf9b8dec2000-06-16 19:34:52 +000067 {
68 FT_Memory memory = zone->memory;
69
Werner Lemberg5811c7c2000-07-02 13:53:16 +000070
David Turnerf9b8dec2000-06-16 19:34:52 +000071 FREE( zone->contours );
72 FREE( zone->tags );
73 FREE( zone->cur );
74 FREE( zone->org );
75
76 zone->max_points = zone->n_points = 0;
77 zone->max_contours = zone->n_contours = 0;
78 }
79
80
81 /*************************************************************************/
82 /* */
83 /* <Function> */
84 /* TT_New_GlyphZone */
85 /* */
86 /* <Description> */
87 /* Allocates a new glyph zone. */
88 /* */
89 /* <Input> */
90 /* memory :: A handle to the current memory object. */
91 /* */
92 /* maxPoints :: The capacity of glyph zone in points. */
93 /* */
94 /* maxContours :: The capacity of glyph zone in contours. */
95 /* */
96 /* <Output> */
97 /* zone :: A pointer to the target glyph zone record. */
98 /* */
99 /* <Return> */
100 /* FreeType error code. 0 means success. */
101 /* */
Werner Lemberg5811c7c2000-07-02 13:53:16 +0000102 LOCAL_FUNC
103 FT_Error TT_New_GlyphZone( FT_Memory memory,
104 FT_UShort maxPoints,
105 FT_Short maxContours,
106 TT_GlyphZone* zone )
David Turnerf9b8dec2000-06-16 19:34:52 +0000107 {
Werner Lemberg5811c7c2000-07-02 13:53:16 +0000108 FT_Error error;
109
David Turnerf9b8dec2000-06-16 19:34:52 +0000110
111 if ( maxPoints > 0 )
112 maxPoints += 2;
113
114 MEM_Set( zone, 0, sizeof ( *zone ) );
115 zone->memory = memory;
116
117 if ( ALLOC_ARRAY( zone->org, maxPoints * 2, FT_F26Dot6 ) ||
118 ALLOC_ARRAY( zone->cur, maxPoints * 2, FT_F26Dot6 ) ||
119 ALLOC_ARRAY( zone->tags, maxPoints, FT_Byte ) ||
120 ALLOC_ARRAY( zone->contours, maxContours, FT_UShort ) )
121 {
122 TT_Done_GlyphZone( zone );
123 }
124
125 return error;
126 }
127
128
129 /*************************************************************************/
130 /* */
131 /* <Function> */
David Turnerd2b1f351999-12-16 23:11:37 +0000132 /* TT_Init_Face */
133 /* */
134 /* <Description> */
135 /* Initializes a given TrueType face object. */
136 /* */
137 /* <Input> */
Werner Lemberg78575dc2000-06-12 19:36:41 +0000138 /* stream :: The source font stream. */
139 /* */
David Turnerd2b1f351999-12-16 23:11:37 +0000140 /* face_index :: The index of the font face in the resource. */
Werner Lemberg78575dc2000-06-12 19:36:41 +0000141 /* */
142 /* num_params :: Number of additional generic parameters. Ignored. */
143 /* */
144 /* params :: Additional generic parameters. Ignored. */
145 /* */
146 /* <InOut> */
David Turnerd2b1f351999-12-16 23:11:37 +0000147 /* face :: The newly built face object. */
148 /* */
149 /* <Return> */
Werner Lemberga929ba92000-06-25 06:47:11 +0000150 /* FreeType error code. 0 means success. */
David Turnerd2b1f351999-12-16 23:11:37 +0000151 /* */
152 LOCAL_DEF
David Turnerf9b8dec2000-06-16 19:34:52 +0000153 FT_Error TT_Init_Face( FT_Stream stream,
David Turner4f2c5542000-05-12 10:19:41 +0000154 TT_Face face,
David Turnerf9b8dec2000-06-16 19:34:52 +0000155 FT_Int face_index,
156 FT_Int num_params,
David Turner4f2c5542000-05-12 10:19:41 +0000157 FT_Parameter* params )
David Turnerd2b1f351999-12-16 23:11:37 +0000158 {
David Turnerf9b8dec2000-06-16 19:34:52 +0000159 FT_Error error;
David Turnerf0df85b2000-06-22 00:17:42 +0000160 FT_Library library;
Werner Lemberg78575dc2000-06-12 19:36:41 +0000161 SFNT_Interface* sfnt;
162
Werner Lemberg5811c7c2000-07-02 13:53:16 +0000163
David Turnerf0df85b2000-06-22 00:17:42 +0000164 library = face->root.driver->root.library;
165 sfnt = (SFNT_Interface*)FT_Get_Module_Interface( library, "sfnt" );
Werner Lemberga929ba92000-06-25 06:47:11 +0000166 if ( !sfnt )
167 goto Bad_Format;
David Turnerc60c61c2000-05-12 15:26:58 +0000168
David Turnerd2b1f351999-12-16 23:11:37 +0000169 /* create input stream from resource */
Werner Lemberg78575dc2000-06-12 19:36:41 +0000170 if ( FILE_Seek( 0 ) )
David Turnerd2b1f351999-12-16 23:11:37 +0000171 goto Exit;
172
David Turnerd42c68e2000-01-27 13:56:02 +0000173 /* check that we have a valid TrueType file */
David Turner2e421312000-05-26 22:13:17 +0000174 error = sfnt->init_face( stream, face, face_index, num_params, params );
Werner Lemberg78575dc2000-06-12 19:36:41 +0000175 if ( error )
176 goto Exit;
David Turnerc60c61c2000-05-12 15:26:58 +0000177
David Turnerd42c68e2000-01-27 13:56:02 +0000178 /* We must also be able to accept Mac/GX fonts, as well as OT ones */
Werner Lemberg78575dc2000-06-12 19:36:41 +0000179 if ( face->format_tag != 0x00010000L && /* MS fonts */
180 face->format_tag != TTAG_true ) /* Mac fonts */
David Turnerd42c68e2000-01-27 13:56:02 +0000181 {
Werner Lemberg78575dc2000-06-12 19:36:41 +0000182 FT_TRACE2(( "[not a valid TTF font]\n" ));
David Turner2e421312000-05-26 22:13:17 +0000183 goto Bad_Format;
David Turnerd42c68e2000-01-27 13:56:02 +0000184 }
185
Werner Lemberg78575dc2000-06-12 19:36:41 +0000186 /* If we are performing a simple font format check, exit immediately */
David Turnerd2b1f351999-12-16 23:11:37 +0000187 if ( face_index < 0 )
188 return TT_Err_Ok;
189
David Turner2e421312000-05-26 22:13:17 +0000190 /* Load font directory */
191 error = sfnt->load_face( stream, face, face_index, num_params, params );
Werner Lemberg78575dc2000-06-12 19:36:41 +0000192 if ( error )
193 goto Exit;
David Turnerd2b1f351999-12-16 23:11:37 +0000194
David Turner2e421312000-05-26 22:13:17 +0000195 error = TT_Load_Locations( face, stream ) ||
196 TT_Load_CVT ( face, stream ) ||
197 TT_Load_Programs ( face, stream );
Werner Lemberg78575dc2000-06-12 19:36:41 +0000198
Werner Lemberga929ba92000-06-25 06:47:11 +0000199 /* initialize standard glyph loading routines */
David Turner994d7742000-06-25 04:49:19 +0000200 TT_Init_Glyph_Loading( face );
201
David Turnerd2b1f351999-12-16 23:11:37 +0000202 Exit:
203 return error;
David Turner2e421312000-05-26 22:13:17 +0000204
205 Bad_Format:
206 error = FT_Err_Unknown_File_Format;
207 goto Exit;
David Turnerd2b1f351999-12-16 23:11:37 +0000208 }
209
210
David Turnerd2b1f351999-12-16 23:11:37 +0000211 /*************************************************************************/
212 /* */
213 /* <Function> */
214 /* TT_Done_Face */
215 /* */
216 /* <Description> */
217 /* Finalizes a given face object. */
218 /* */
219 /* <Input> */
220 /* face :: A pointer to the face object to destroy. */
221 /* */
222 LOCAL_DEF
223 void TT_Done_Face( TT_Face face )
224 {
David Turnerd2b1f351999-12-16 23:11:37 +0000225 FT_Memory memory = face->root.memory;
David Turner2e421312000-05-26 22:13:17 +0000226 FT_Stream stream = face->root.stream;
David Turnerd2b1f351999-12-16 23:11:37 +0000227
Werner Lembergbd5ae402000-07-05 04:32:02 +0000228 SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt;
David Turnerc60c61c2000-05-12 15:26:58 +0000229
Werner Lemberg5811c7c2000-07-02 13:53:16 +0000230
Werner Lemberga929ba92000-06-25 06:47:11 +0000231 /* for `extended TrueType formats' (i.e. compressed versions) */
232 if ( face->extra.finalizer )
David Turner994d7742000-06-25 04:49:19 +0000233 face->extra.finalizer( face->extra.data );
Werner Lemberg78575dc2000-06-12 19:36:41 +0000234
235 if ( sfnt )
236 sfnt->done_face( face );
David Turnerd2b1f351999-12-16 23:11:37 +0000237
238 /* freeing the locations table */
239 FREE( face->glyph_locations );
240 face->num_locations = 0;
241
David Turnerd2b1f351999-12-16 23:11:37 +0000242 /* freeing the CVT */
243 FREE( face->cvt );
244 face->cvt_size = 0;
245
David Turnerd2b1f351999-12-16 23:11:37 +0000246 /* freeing the programs */
David Turner2e421312000-05-26 22:13:17 +0000247 RELEASE_Frame( face->font_program );
248 RELEASE_Frame( face->cvt_program );
David Turnerd2b1f351999-12-16 23:11:37 +0000249 face->font_program_size = 0;
250 face->cvt_program_size = 0;
David Turnerd2b1f351999-12-16 23:11:37 +0000251 }
252
253
254 /*************************************************************************/
255 /* */
256 /* SIZE FUNCTIONS */
257 /* */
258 /*************************************************************************/
259
260
261 /*************************************************************************/
262 /* */
263 /* <Function> */
264 /* TT_Init_Size */
265 /* */
266 /* <Description> */
267 /* Initializes a new TrueType size object. */
268 /* */
269 /* <InOut> */
270 /* size :: A handle to the size object. */
271 /* */
272 /* <Return> */
Werner Lemberga929ba92000-06-25 06:47:11 +0000273 /* FreeType error code. 0 means success. */
David Turnerd2b1f351999-12-16 23:11:37 +0000274 /* */
275 LOCAL_DEF
David Turnerf9b8dec2000-06-16 19:34:52 +0000276 FT_Error TT_Init_Size( TT_Size size )
David Turnerd2b1f351999-12-16 23:11:37 +0000277 {
Werner Lemberg5811c7c2000-07-02 13:53:16 +0000278 FT_Error error = TT_Err_Ok;
279
David Turnerc60c61c2000-05-12 15:26:58 +0000280
David Turner8f43c712000-02-02 12:16:19 +0000281#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg78575dc2000-06-12 19:36:41 +0000282
David Turnerd2b1f351999-12-16 23:11:37 +0000283 TT_Face face = (TT_Face)size->root.face;
284 FT_Memory memory = face->root.memory;
David Turnerf9b8dec2000-06-16 19:34:52 +0000285 FT_Int i;
David Turnerd2b1f351999-12-16 23:11:37 +0000286
David Turnerd2b1f351999-12-16 23:11:37 +0000287 TT_ExecContext exec;
David Turnerf9b8dec2000-06-16 19:34:52 +0000288 FT_UShort n_twilight;
David Turner8f43c712000-02-02 12:16:19 +0000289 TT_MaxProfile* maxp = &face->max_profile;
David Turnerd2b1f351999-12-16 23:11:37 +0000290
Werner Lemberg78575dc2000-06-12 19:36:41 +0000291
David Turnerd2b1f351999-12-16 23:11:37 +0000292 size->ttmetrics.valid = FALSE;
293
294 size->max_function_defs = maxp->maxFunctionDefs;
295 size->max_instruction_defs = maxp->maxInstructionDefs;
296
297 size->num_function_defs = 0;
298 size->num_instruction_defs = 0;
299
300 size->max_func = 0;
301 size->max_ins = 0;
302
303 size->cvt_size = face->cvt_size;
304 size->storage_size = maxp->maxStorage;
305
306 /* Set default metrics */
307 {
308 FT_Size_Metrics* metrics = &size->root.metrics;
309 TT_Size_Metrics* metrics2 = &size->ttmetrics;
310
Werner Lemberg78575dc2000-06-12 19:36:41 +0000311
David Turnerd2b1f351999-12-16 23:11:37 +0000312 metrics->x_ppem = 0;
313 metrics->y_ppem = 0;
314
315 metrics2->rotated = FALSE;
316 metrics2->stretched = FALSE;
317
318 /* set default compensation (all 0) */
319 for ( i = 0; i < 4; i++ )
320 metrics2->compensations[i] = 0;
321 }
322
Werner Lemberg78575dc2000-06-12 19:36:41 +0000323 /* allocate function defs, instruction defs, cvt, and storage area */
David Turnerd2b1f351999-12-16 23:11:37 +0000324 if ( ALLOC_ARRAY( size->function_defs,
325 size->max_function_defs,
326 TT_DefRecord ) ||
327
328 ALLOC_ARRAY( size->instruction_defs,
329 size->max_instruction_defs,
330 TT_DefRecord ) ||
331
332 ALLOC_ARRAY( size->cvt,
David Turnerf9b8dec2000-06-16 19:34:52 +0000333 size->cvt_size, FT_Long ) ||
David Turnerd2b1f351999-12-16 23:11:37 +0000334
335 ALLOC_ARRAY( size->storage,
David Turnerf9b8dec2000-06-16 19:34:52 +0000336 size->storage_size, FT_Long ) )
David Turnerd2b1f351999-12-16 23:11:37 +0000337
338 goto Fail_Memory;
339
340 /* reserve twilight zone */
341 n_twilight = maxp->maxTwilightPoints;
David Turnerf9b8dec2000-06-16 19:34:52 +0000342 error = TT_New_GlyphZone( memory, n_twilight, 0, &size->twilight );
David Turnerd2b1f351999-12-16 23:11:37 +0000343 if ( error )
344 goto Fail_Memory;
345
346 size->twilight.n_points = n_twilight;
347
348 /* set `face->interpreter' according to the debug hook present */
349 {
David Turnerf0df85b2000-06-22 00:17:42 +0000350 FT_Library library = face->root.driver->root.library;
David Turnerc60c61c2000-05-12 15:26:58 +0000351
Werner Lemberga929ba92000-06-25 06:47:11 +0000352
David Turnerd2b1f351999-12-16 23:11:37 +0000353 face->interpreter = (TT_Interpreter)
Werner Lemberg78575dc2000-06-12 19:36:41 +0000354 library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE];
355 if ( !face->interpreter )
David Turnerd2b1f351999-12-16 23:11:37 +0000356 face->interpreter = (TT_Interpreter)TT_RunIns;
357 }
358
359 /* Fine, now execute the font program! */
360 exec = size->context;
David Turnerd2b1f351999-12-16 23:11:37 +0000361 /* size objects used during debugging have their own context */
Werner Lemberg78575dc2000-06-12 19:36:41 +0000362 if ( !size->debug )
363 exec = TT_New_Context( face );
David Turnerd2b1f351999-12-16 23:11:37 +0000364
365 if ( !exec )
366 {
367 error = TT_Err_Could_Not_Find_Context;
368 goto Fail_Memory;
369 }
370
371 size->GS = tt_default_graphics_state;
372 TT_Load_Context( exec, face, size );
373
374 exec->callTop = 0;
375 exec->top = 0;
376
377 exec->period = 64;
378 exec->phase = 0;
379 exec->threshold = 0;
380
381 {
382 FT_Size_Metrics* metrics = &exec->metrics;
383 TT_Size_Metrics* tt_metrics = &exec->tt_metrics;
384
385
Werner Lemberg78575dc2000-06-12 19:36:41 +0000386 metrics->x_ppem = 0;
387 metrics->y_ppem = 0;
388 metrics->x_scale = 0;
389 metrics->y_scale = 0;
David Turnerd2b1f351999-12-16 23:11:37 +0000390
Werner Lemberg78575dc2000-06-12 19:36:41 +0000391 tt_metrics->ppem = 0;
392 tt_metrics->scale = 0;
393 tt_metrics->ratio = 0x10000L;
David Turnerd2b1f351999-12-16 23:11:37 +0000394 }
395
396 exec->instruction_trap = FALSE;
397
398 exec->cvtSize = size->cvt_size;
399 exec->cvt = size->cvt;
400
401 exec->F_dot_P = 0x10000L;
402
403 /* allow font program execution */
404 TT_Set_CodeRange( exec,
405 tt_coderange_font,
406 face->font_program,
407 face->font_program_size );
408
409 /* disable CVT and glyph programs coderange */
410 TT_Clear_CodeRange( exec, tt_coderange_cvt );
411 TT_Clear_CodeRange( exec, tt_coderange_glyph );
412
413 if ( face->font_program_size > 0 )
414 {
415 error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 );
416 if ( !error )
417 error = face->interpreter( exec );
418
419 if ( error )
420 goto Fail_Exec;
421 }
422 else
423 error = TT_Err_Ok;
424
425 TT_Save_Context( exec, size );
426
427 if ( !size->debug )
428 TT_Done_Context( exec );
429
David Turner8f43c712000-02-02 12:16:19 +0000430#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
431
David Turnerd2b1f351999-12-16 23:11:37 +0000432 size->ttmetrics.valid = FALSE;
433 return error;
434
David Turner8f43c712000-02-02 12:16:19 +0000435#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg78575dc2000-06-12 19:36:41 +0000436
David Turnerd2b1f351999-12-16 23:11:37 +0000437 Fail_Exec:
438 if ( !size->debug )
439 TT_Done_Context( exec );
440
441 Fail_Memory:
Werner Lemberg78575dc2000-06-12 19:36:41 +0000442
David Turner8f43c712000-02-02 12:16:19 +0000443#endif
444
David Turnerd2b1f351999-12-16 23:11:37 +0000445 TT_Done_Size( size );
446 return error;
447 }
448
449
450 /*************************************************************************/
451 /* */
452 /* <Function> */
453 /* TT_Done_Size */
454 /* */
455 /* <Description> */
456 /* The TrueType size object finalizer. */
457 /* */
458 /* <Input> */
459 /* size :: A handle to the target size object. */
460 /* */
461 LOCAL_FUNC
462 void TT_Done_Size( TT_Size size )
463 {
Werner Lemberg78575dc2000-06-12 19:36:41 +0000464
David Turner8f43c712000-02-02 12:16:19 +0000465#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg78575dc2000-06-12 19:36:41 +0000466
David Turnerd2b1f351999-12-16 23:11:37 +0000467 FT_Memory memory = size->root.face->memory;
468
Werner Lemberg78575dc2000-06-12 19:36:41 +0000469
David Turnerd2b1f351999-12-16 23:11:37 +0000470 if ( size->debug )
471 {
472 /* the debug context must be deleted by the debugger itself */
473 size->context = NULL;
474 size->debug = FALSE;
475 }
476
477 FREE( size->cvt );
478 size->cvt_size = 0;
479
480 /* free storage area */
481 FREE( size->storage );
482 size->storage_size = 0;
483
484 /* twilight zone */
David Turnerf9b8dec2000-06-16 19:34:52 +0000485 TT_Done_GlyphZone( &size->twilight );
David Turnerd2b1f351999-12-16 23:11:37 +0000486
487 FREE( size->function_defs );
488 FREE( size->instruction_defs );
Werner Lemberg78575dc2000-06-12 19:36:41 +0000489
David Turnerd2b1f351999-12-16 23:11:37 +0000490 size->num_function_defs = 0;
491 size->max_function_defs = 0;
492 size->num_instruction_defs = 0;
493 size->max_instruction_defs = 0;
494
495 size->max_func = 0;
496 size->max_ins = 0;
Werner Lemberg78575dc2000-06-12 19:36:41 +0000497
David Turner8f43c712000-02-02 12:16:19 +0000498#endif
David Turnerd2b1f351999-12-16 23:11:37 +0000499
500 size->ttmetrics.valid = FALSE;
501 }
502
503
504 /*************************************************************************/
505 /* */
506 /* <Function> */
507 /* TT_Reset_Size */
508 /* */
509 /* <Description> */
510 /* Resets a TrueType size when resolutions and character dimensions */
511 /* have been changed. */
512 /* */
513 /* <Input> */
514 /* size :: A handle to the target size object. */
515 /* */
516 LOCAL_DEF
David Turnerf9b8dec2000-06-16 19:34:52 +0000517 FT_Error TT_Reset_Size( TT_Size size )
David Turnerd2b1f351999-12-16 23:11:37 +0000518 {
David Turner8f43c712000-02-02 12:16:19 +0000519 TT_Face face;
David Turnerf9b8dec2000-06-16 19:34:52 +0000520 FT_Error error = TT_Err_Ok;
David Turnerd2b1f351999-12-16 23:11:37 +0000521
522 FT_Size_Metrics* metrics;
523
Werner Lemberg78575dc2000-06-12 19:36:41 +0000524
David Turnerd2b1f351999-12-16 23:11:37 +0000525 if ( size->ttmetrics.valid )
526 return TT_Err_Ok;
527
528 face = (TT_Face)size->root.face;
529
530 metrics = &size->root.metrics;
531
532 if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 )
533 return TT_Err_Invalid_PPem;
534
535 /* compute new transformation */
536 if ( metrics->x_ppem >= metrics->y_ppem )
537 {
538 size->ttmetrics.scale = metrics->x_scale;
539 size->ttmetrics.ppem = metrics->x_ppem;
Werner Lemberg78575dc2000-06-12 19:36:41 +0000540 size->ttmetrics.x_ratio = 0x10000L;
David Turnerd2b1f351999-12-16 23:11:37 +0000541 size->ttmetrics.y_ratio = FT_MulDiv( metrics->y_ppem,
542 0x10000L,
543 metrics->x_ppem );
544 }
545 else
546 {
547 size->ttmetrics.scale = metrics->y_scale;
548 size->ttmetrics.ppem = metrics->y_ppem;
549 size->ttmetrics.x_ratio = FT_MulDiv( metrics->x_ppem,
550 0x10000L,
551 metrics->y_ppem );
Werner Lemberg78575dc2000-06-12 19:36:41 +0000552 size->ttmetrics.y_ratio = 0x10000L;
David Turnerd2b1f351999-12-16 23:11:37 +0000553 }
554
555 /* Compute root ascender, descender, test height, and max_advance */
Werner Lemberg5811c7c2000-07-02 13:53:16 +0000556 metrics->ascender = ( FT_MulFix( face->root.ascender,
557 metrics->y_scale ) + 32 ) & -64;
558 metrics->descender = ( FT_MulFix( face->root.descender,
559 metrics->y_scale ) + 32 ) & -64;
560 metrics->height = ( FT_MulFix( face->root.height,
561 metrics->y_scale ) + 32 ) & -64;
David Turnerd2b1f351999-12-16 23:11:37 +0000562 metrics->max_advance = ( FT_MulFix( face->root.max_advance_width,
Werner Lemberg5811c7c2000-07-02 13:53:16 +0000563 metrics->x_scale ) + 32 ) & -64;
David Turnerd2b1f351999-12-16 23:11:37 +0000564
David Turner8f43c712000-02-02 12:16:19 +0000565#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg78575dc2000-06-12 19:36:41 +0000566
David Turnerd2b1f351999-12-16 23:11:37 +0000567 {
Werner Lemberg5811c7c2000-07-02 13:53:16 +0000568 TT_ExecContext exec;
569 FT_UInt i, j;
David Turnerc60c61c2000-05-12 15:26:58 +0000570
Werner Lemberg78575dc2000-06-12 19:36:41 +0000571
David Turner8f43c712000-02-02 12:16:19 +0000572 /* Scale the cvt values to the new ppem. */
573 /* We use by default the y ppem to scale the CVT. */
David Turner8f43c712000-02-02 12:16:19 +0000574 for ( i = 0; i < size->cvt_size; i++ )
575 size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
David Turnerc60c61c2000-05-12 15:26:58 +0000576
David Turner8f43c712000-02-02 12:16:19 +0000577 /* All twilight points are originally zero */
578 for ( j = 0; j < size->twilight.n_points; j++ )
579 {
580 size->twilight.org[j].x = 0;
581 size->twilight.org[j].y = 0;
582 size->twilight.cur[j].x = 0;
583 size->twilight.cur[j].y = 0;
584 }
David Turnerc60c61c2000-05-12 15:26:58 +0000585
David Turner8f43c712000-02-02 12:16:19 +0000586 /* clear storage area */
587 for ( i = 0; i < size->storage_size; i++ )
588 size->storage[i] = 0;
David Turnerc60c61c2000-05-12 15:26:58 +0000589
David Turner8f43c712000-02-02 12:16:19 +0000590 size->GS = tt_default_graphics_state;
David Turnerc60c61c2000-05-12 15:26:58 +0000591
David Turner8f43c712000-02-02 12:16:19 +0000592 /* get execution context and run prep program */
593 if ( size->debug )
594 exec = size->context;
595 else
596 exec = TT_New_Context( face );
597 /* debugging instances have their own context */
David Turnerc60c61c2000-05-12 15:26:58 +0000598
David Turner8f43c712000-02-02 12:16:19 +0000599 if ( !exec )
600 return TT_Err_Could_Not_Find_Context;
David Turnerc60c61c2000-05-12 15:26:58 +0000601
David Turner8f43c712000-02-02 12:16:19 +0000602 TT_Load_Context( exec, face, size );
David Turnerc60c61c2000-05-12 15:26:58 +0000603
David Turner8f43c712000-02-02 12:16:19 +0000604 TT_Set_CodeRange( exec,
605 tt_coderange_cvt,
606 face->cvt_program,
607 face->cvt_program_size );
David Turnerc60c61c2000-05-12 15:26:58 +0000608
David Turner8f43c712000-02-02 12:16:19 +0000609 TT_Clear_CodeRange( exec, tt_coderange_glyph );
David Turnerc60c61c2000-05-12 15:26:58 +0000610
David Turner8f43c712000-02-02 12:16:19 +0000611 exec->instruction_trap = FALSE;
David Turnerc60c61c2000-05-12 15:26:58 +0000612
David Turner8f43c712000-02-02 12:16:19 +0000613 exec->top = 0;
614 exec->callTop = 0;
David Turnerc60c61c2000-05-12 15:26:58 +0000615
David Turner8f43c712000-02-02 12:16:19 +0000616 if ( face->cvt_program_size > 0 )
617 {
618 error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
619 if ( error )
Werner Lemberg5811c7c2000-07-02 13:53:16 +0000620 goto End;
David Turnerc60c61c2000-05-12 15:26:58 +0000621
David Turner8f43c712000-02-02 12:16:19 +0000622 if ( !size->debug )
623 error = face->interpreter( exec );
624 }
625 else
626 error = TT_Err_Ok;
David Turnerc60c61c2000-05-12 15:26:58 +0000627
David Turner8f43c712000-02-02 12:16:19 +0000628 size->GS = exec->GS;
629 /* save default graphics state */
David Turnerc60c61c2000-05-12 15:26:58 +0000630
Werner Lemberg5811c7c2000-07-02 13:53:16 +0000631 End:
David Turner8f43c712000-02-02 12:16:19 +0000632 TT_Save_Context( exec, size );
David Turnerc60c61c2000-05-12 15:26:58 +0000633
David Turnerd2b1f351999-12-16 23:11:37 +0000634 if ( !size->debug )
David Turner8f43c712000-02-02 12:16:19 +0000635 TT_Done_Context( exec );
636 /* debugging instances keep their context */
David Turnerd2b1f351999-12-16 23:11:37 +0000637 }
Werner Lemberg78575dc2000-06-12 19:36:41 +0000638
David Turner8f43c712000-02-02 12:16:19 +0000639#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
David Turnerd2b1f351999-12-16 23:11:37 +0000640
641 if ( !error )
642 size->ttmetrics.valid = TRUE;
643
644 return error;
645 }
646
647
David Turnerd2b1f351999-12-16 23:11:37 +0000648 /*************************************************************************/
649 /* */
650 /* <Function> */
651 /* TT_Init_Driver */
652 /* */
653 /* <Description> */
654 /* Initializes a given TrueType driver object. */
655 /* */
656 /* <Input> */
657 /* driver :: A handle to the target driver object. */
658 /* */
659 /* <Return> */
Werner Lemberga929ba92000-06-25 06:47:11 +0000660 /* FreeType error code. 0 means success. */
David Turnerd2b1f351999-12-16 23:11:37 +0000661 /* */
662 LOCAL_FUNC
David Turnerf9b8dec2000-06-16 19:34:52 +0000663 FT_Error TT_Init_Driver( TT_Driver driver )
David Turnerd2b1f351999-12-16 23:11:37 +0000664 {
Werner Lemberg5811c7c2000-07-02 13:53:16 +0000665 FT_Error error;
David Turnerc60c61c2000-05-12 15:26:58 +0000666
Werner Lemberga929ba92000-06-25 06:47:11 +0000667
668 /* set `extra' in glyph loader */
669 error = FT_GlyphLoader_Create_Extra( FT_DRIVER( driver )->glyph_loader );
David Turnerf0df85b2000-06-22 00:17:42 +0000670
David Turnerd2b1f351999-12-16 23:11:37 +0000671 /* init extension registry if needed */
Werner Lemberg78575dc2000-06-12 19:36:41 +0000672
David Turnerd2b1f351999-12-16 23:11:37 +0000673#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
Werner Lemberga929ba92000-06-25 06:47:11 +0000674 if ( !error )
David Turnerf0df85b2000-06-22 00:17:42 +0000675 return TT_Init_Extensions( driver );
David Turnerd2b1f351999-12-16 23:11:37 +0000676#endif
David Turnerf0df85b2000-06-22 00:17:42 +0000677
678 return error;
David Turnerd2b1f351999-12-16 23:11:37 +0000679 }
680
681
682 /*************************************************************************/
683 /* */
684 /* <Function> */
685 /* TT_Done_Driver */
686 /* */
687 /* <Description> */
688 /* Finalizes a given TrueType driver. */
689 /* */
690 /* <Input> */
691 /* driver :: A handle to the target TrueType driver. */
692 /* */
693 LOCAL_FUNC
694 void TT_Done_Driver( TT_Driver driver )
695 {
696 /* destroy extensions registry if needed */
Werner Lemberg78575dc2000-06-12 19:36:41 +0000697
David Turnerd2b1f351999-12-16 23:11:37 +0000698#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
Werner Lemberg5811c7c2000-07-02 13:53:16 +0000699
David Turnerd2b1f351999-12-16 23:11:37 +0000700 TT_Done_Extensions( driver );
Werner Lemberg5811c7c2000-07-02 13:53:16 +0000701
David Turnerd2b1f351999-12-16 23:11:37 +0000702#endif
703
David Turner8f43c712000-02-02 12:16:19 +0000704#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg78575dc2000-06-12 19:36:41 +0000705
David Turnerd2b1f351999-12-16 23:11:37 +0000706 /* destroy the execution context */
707 if ( driver->context )
708 {
David Turnerf0df85b2000-06-22 00:17:42 +0000709 TT_Destroy_Context( driver->context, driver->root.root.memory );
David Turnerd2b1f351999-12-16 23:11:37 +0000710 driver->context = NULL;
711 }
Werner Lemberg78575dc2000-06-12 19:36:41 +0000712
David Turner8f43c712000-02-02 12:16:19 +0000713#endif
Werner Lemberg5811c7c2000-07-02 13:53:16 +0000714
David Turnerd2b1f351999-12-16 23:11:37 +0000715 }
716
717
718/* END */