ttobjs.c 27.2 KB
Newer Older
David Turner's avatar
David Turner committed
1
2
3
4
5
6
/***************************************************************************/
/*                                                                         */
/*  ttobjs.c                                                               */
/*                                                                         */
/*    Objects manager (body).                                              */
/*                                                                         */
Werner Lemberg's avatar
   
Werner Lemberg committed
7
/*  Copyright 1996-2000 by                                                 */
David Turner's avatar
David Turner committed
8
9
/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
/*                                                                         */
Werner Lemberg's avatar
   
Werner Lemberg committed
10
11
/*  This file is part of the FreeType project, and may only be used,       */
/*  modified, and distributed under the terms of the FreeType project      */
David Turner's avatar
David Turner committed
12
13
14
15
16
17
18
/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
/*  this file you indicate that you have read the license and              */
/*  understand and accept it fully.                                        */
/*                                                                         */
/***************************************************************************/


19
20
21
22
23
24
25
26
#include <freetype/internal/ftdebug.h>
#include <freetype/internal/ftcalc.h>
#include <freetype/internal/ftstream.h>
#include <freetype/ttnameid.h>
#include <freetype/tttags.h>

#include <freetype/internal/sfnt.h>
#include <freetype/internal/psnames.h>
David Turner's avatar
David Turner committed
27

Werner Lemberg's avatar
   
Werner Lemberg committed
28

29
30
31
32
#ifdef FT_FLAT_COMPILE

#include "ttgload.h"
#include "ttpload.h"
Werner Lemberg's avatar
   
Werner Lemberg committed
33

34
35
36
37
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
#include "ttinterp.h"
#endif

Werner Lemberg's avatar
   
Werner Lemberg committed
38
#else /* FT_FLAT_COMPILE */
David Turner's avatar
David Turner committed
39

40
41
#include <truetype/ttgload.h>
#include <truetype/ttpload.h>
Werner Lemberg's avatar
   
Werner Lemberg committed
42

43
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
44
#include <truetype/ttinterp.h>
45
46
#endif

Werner Lemberg's avatar
   
Werner Lemberg committed
47
48
#endif /* FT_FLAT_COMPILE */

49
50
51
52

#include <freetype/internal/tterrors.h>


Werner Lemberg's avatar
   
Werner Lemberg committed
53
54
55
56
57
58
59

  /*************************************************************************/
  /*                                                                       */
  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
  /* messages during execution.                                            */
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
60
61
#undef  FT_COMPONENT
#define FT_COMPONENT  trace_ttobjs
David Turner's avatar
David Turner committed
62
63


Werner Lemberg's avatar
   
Werner Lemberg committed
64
65
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER

David Turner's avatar
David Turner committed
66
67
68
69
70
71
  /*************************************************************************/
  /*                                                                       */
  /*                       GLYPH ZONE FUNCTIONS                            */
  /*                                                                       */
  /*************************************************************************/

Werner Lemberg's avatar
   
Werner Lemberg committed
72

73
74
75
76
77
78
79
80
81
82
83
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    TT_Done_GlyphZone                                                  */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Deallocates a glyph zone.                                          */
  /*                                                                       */
  /* <Input>                                                               */
  /*    zone :: A pointer to the target glyph zone.                        */
  /*                                                                       */
84
  FT_LOCAL_DEF
Werner Lemberg's avatar
   
Werner Lemberg committed
85
  void  TT_Done_GlyphZone( TT_GlyphZone*  zone )
86
87
88
  {
    FT_Memory  memory = zone->memory;

Werner Lemberg's avatar
   
Werner Lemberg committed
89

90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
    FREE( zone->contours );
    FREE( zone->tags );
    FREE( zone->cur );
    FREE( zone->org );

    zone->max_points   = zone->n_points   = 0;
    zone->max_contours = zone->n_contours = 0;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    TT_New_GlyphZone                                                   */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Allocates a new glyph zone.                                        */
  /*                                                                       */
  /* <Input>                                                               */
  /*    memory      :: A handle to the current memory object.              */
  /*                                                                       */
  /*    maxPoints   :: The capacity of glyph zone in points.               */
  /*                                                                       */
  /*    maxContours :: The capacity of glyph zone in contours.             */
  /*                                                                       */
  /* <Output>                                                              */
  /*    zone        :: A pointer to the target glyph zone record.          */
  /*                                                                       */
  /* <Return>                                                              */
  /*    FreeType error code.  0 means success.                             */
  /*                                                                       */
121
  FT_LOCAL_DEF
Werner Lemberg's avatar
   
Werner Lemberg committed
122
123
124
125
  FT_Error TT_New_GlyphZone( FT_Memory      memory,
                             FT_UShort      maxPoints,
                             FT_Short       maxContours,
                             TT_GlyphZone*  zone )
126
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
127
128
    FT_Error  error;

129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145

    if ( maxPoints > 0 )
      maxPoints += 2;

    MEM_Set( zone, 0, sizeof ( *zone ) );
    zone->memory = memory;

    if ( ALLOC_ARRAY( zone->org,      maxPoints * 2, FT_F26Dot6 ) ||
         ALLOC_ARRAY( zone->cur,      maxPoints * 2, FT_F26Dot6 ) ||
         ALLOC_ARRAY( zone->tags,     maxPoints,     FT_Byte    ) ||
         ALLOC_ARRAY( zone->contours, maxContours,   FT_UShort  ) )
    {
      TT_Done_GlyphZone( zone );
    }

    return error;
  }
Werner Lemberg's avatar
   
Werner Lemberg committed
146
147
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */

148

David Turner's avatar
David Turner committed
149
150
151
152
153
154
155
156
157
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    TT_Init_Face                                                       */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Initializes a given TrueType face object.                          */
  /*                                                                       */
  /* <Input>                                                               */
Werner Lemberg's avatar
   
Werner Lemberg committed
158
159
  /*    stream     :: The source font stream.                              */
  /*                                                                       */
David Turner's avatar
David Turner committed
160
  /*    face_index :: The index of the font face in the resource.          */
Werner Lemberg's avatar
   
Werner Lemberg committed
161
162
163
164
165
166
  /*                                                                       */
  /*    num_params :: Number of additional generic parameters.  Ignored.   */
  /*                                                                       */
  /*    params     :: Additional generic parameters.  Ignored.             */
  /*                                                                       */
  /* <InOut>                                                               */
David Turner's avatar
David Turner committed
167
168
169
  /*    face       :: The newly built face object.                         */
  /*                                                                       */
  /* <Return>                                                              */
Werner Lemberg's avatar
   
Werner Lemberg committed
170
  /*    FreeType error code.  0 means success.                             */
David Turner's avatar
David Turner committed
171
  /*                                                                       */
172
  FT_LOCAL
173
  FT_Error  TT_Init_Face( FT_Stream      stream,
174
                          TT_Face        face,
175
176
                          FT_Int         face_index,
                          FT_Int         num_params,
177
                          FT_Parameter*  params )
David Turner's avatar
David Turner committed
178
  {
179
    FT_Error         error;
David Turner's avatar
David Turner committed
180
    FT_Library       library;
Werner Lemberg's avatar
   
Werner Lemberg committed
181
182
    SFNT_Interface*  sfnt;

Werner Lemberg's avatar
   
Werner Lemberg committed
183

David Turner's avatar
David Turner committed
184
185
    library = face->root.driver->root.library;
    sfnt    = (SFNT_Interface*)FT_Get_Module_Interface( library, "sfnt" );
Werner Lemberg's avatar
   
Werner Lemberg committed
186
187
    if ( !sfnt )
      goto Bad_Format;
188

David Turner's avatar
David Turner committed
189
    /* create input stream from resource */
Werner Lemberg's avatar
   
Werner Lemberg committed
190
    if ( FILE_Seek( 0 ) )
David Turner's avatar
David Turner committed
191
192
      goto Exit;

193
    /* check that we have a valid TrueType file */
194
    error = sfnt->init_face( stream, face, face_index, num_params, params );
Werner Lemberg's avatar
   
Werner Lemberg committed
195
196
    if ( error )
      goto Exit;
197

198
    /* We must also be able to accept Mac/GX fonts, as well as OT ones */
Werner Lemberg's avatar
   
Werner Lemberg committed
199
200
    if ( face->format_tag != 0x00010000L &&    /* MS fonts  */
         face->format_tag != TTAG_true   )     /* Mac fonts */
201
    {
Werner Lemberg's avatar
   
Werner Lemberg committed
202
      FT_TRACE2(( "[not a valid TTF font]\n" ));
203
      goto Bad_Format;
204
205
    }

Werner Lemberg's avatar
   
Werner Lemberg committed
206
    /* If we are performing a simple font format check, exit immediately */
David Turner's avatar
David Turner committed
207
208
209
    if ( face_index < 0 )
      return TT_Err_Ok;

210
211
    /* Load font directory */
    error = sfnt->load_face( stream, face, face_index, num_params, params );
Werner Lemberg's avatar
   
Werner Lemberg committed
212
213
    if ( error )
      goto Exit;
David Turner's avatar
David Turner committed
214

Werner Lemberg's avatar
   
Werner Lemberg committed
215
216
217
218
    if ( face->root.face_flags & FT_FACE_FLAG_SCALABLE )
      error = TT_Load_Locations( face, stream ) ||
              TT_Load_CVT      ( face, stream ) ||
              TT_Load_Programs ( face, stream );
Werner Lemberg's avatar
   
Werner Lemberg committed
219

Werner Lemberg's avatar
   
Werner Lemberg committed
220
    /* initialize standard glyph loading routines */
221
222
    TT_Init_Glyph_Loading( face );

David Turner's avatar
David Turner committed
223
224
  Exit:
    return error;
Werner Lemberg's avatar
   
Werner Lemberg committed
225

226
227
228
  Bad_Format:
    error = FT_Err_Unknown_File_Format;
    goto Exit;
David Turner's avatar
David Turner committed
229
230
231
232
233
234
235
236
237
238
239
240
241
242
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    TT_Done_Face                                                       */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Finalizes a given face object.                                     */
  /*                                                                       */
  /* <Input>                                                               */
  /*    face :: A pointer to the face object to destroy.                   */
  /*                                                                       */
243
  FT_LOCAL
David Turner's avatar
David Turner committed
244
245
246
  void  TT_Done_Face( TT_Face  face )
  {
    FT_Memory  memory = face->root.memory;
247
    FT_Stream  stream = face->root.stream;
David Turner's avatar
David Turner committed
248

Werner Lemberg's avatar
   
Werner Lemberg committed
249
    SFNT_Interface*  sfnt = (SFNT_Interface*)face->sfnt;
250

Werner Lemberg's avatar
   
Werner Lemberg committed
251

Werner Lemberg's avatar
   
Werner Lemberg committed
252
253
    /* for `extended TrueType formats' (i.e. compressed versions) */
    if ( face->extra.finalizer )
254
      face->extra.finalizer( face->extra.data );
Werner Lemberg's avatar
   
Werner Lemberg committed
255
256
257

    if ( sfnt )
      sfnt->done_face( face );
David Turner's avatar
David Turner committed
258
259
260
261
262
263
264
265
266
267

    /* freeing the locations table */
    FREE( face->glyph_locations );
    face->num_locations = 0;

    /* freeing the CVT */
    FREE( face->cvt );
    face->cvt_size = 0;

    /* freeing the programs */
268
269
    RELEASE_Frame( face->font_program );
    RELEASE_Frame( face->cvt_program );
David Turner's avatar
David Turner committed
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
    face->font_program_size = 0;
    face->cvt_program_size  = 0;
  }


  /*************************************************************************/
  /*                                                                       */
  /*                           SIZE  FUNCTIONS                             */
  /*                                                                       */
  /*************************************************************************/


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    TT_Init_Size                                                       */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Initializes a new TrueType size object.                            */
  /*                                                                       */
  /* <InOut>                                                               */
  /*    size :: A handle to the size object.                               */
  /*                                                                       */
  /* <Return>                                                              */
Werner Lemberg's avatar
   
Werner Lemberg committed
294
  /*    FreeType error code.  0 means success.                             */
David Turner's avatar
David Turner committed
295
  /*                                                                       */
296
  FT_LOCAL
297
  FT_Error  TT_Init_Size( TT_Size  size )
David Turner's avatar
David Turner committed
298
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
299
300
    FT_Error  error = TT_Err_Ok;

301

302
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg's avatar
   
Werner Lemberg committed
303

David Turner's avatar
David Turner committed
304
305
    TT_Face    face   = (TT_Face)size->root.face;
    FT_Memory  memory = face->root.memory;
306
    FT_Int     i;
David Turner's avatar
David Turner committed
307
308

    TT_ExecContext  exec;
309
    FT_UShort       n_twilight;
310
    TT_MaxProfile*  maxp = &face->max_profile;
David Turner's avatar
David Turner committed
311

Werner Lemberg's avatar
   
Werner Lemberg committed
312

David Turner's avatar
David Turner committed
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
    size->ttmetrics.valid = FALSE;

    size->max_function_defs    = maxp->maxFunctionDefs;
    size->max_instruction_defs = maxp->maxInstructionDefs;

    size->num_function_defs    = 0;
    size->num_instruction_defs = 0;

    size->max_func = 0;
    size->max_ins  = 0;

    size->cvt_size     = face->cvt_size;
    size->storage_size = maxp->maxStorage;

    /* Set default metrics */
    {
      FT_Size_Metrics*  metrics  = &size->root.metrics;
      TT_Size_Metrics*  metrics2 = &size->ttmetrics;

Werner Lemberg's avatar
   
Werner Lemberg committed
332

David Turner's avatar
David Turner committed
333
334
335
336
337
338
339
340
341
342
343
      metrics->x_ppem = 0;
      metrics->y_ppem = 0;

      metrics2->rotated   = FALSE;
      metrics2->stretched = FALSE;

      /* set default compensation (all 0) */
      for ( i = 0; i < 4; i++ )
        metrics2->compensations[i] = 0;
    }

Werner Lemberg's avatar
   
Werner Lemberg committed
344
    /* allocate function defs, instruction defs, cvt, and storage area */
David Turner's avatar
David Turner committed
345
346
347
348
349
350
351
352
353
    if ( ALLOC_ARRAY( size->function_defs,
                      size->max_function_defs,
                      TT_DefRecord )                ||

         ALLOC_ARRAY( size->instruction_defs,
                      size->max_instruction_defs,
                      TT_DefRecord )                ||

         ALLOC_ARRAY( size->cvt,
354
                      size->cvt_size, FT_Long )     ||
David Turner's avatar
David Turner committed
355
356

         ALLOC_ARRAY( size->storage,
357
                      size->storage_size, FT_Long ) )
David Turner's avatar
David Turner committed
358
359
360
361
362

      goto Fail_Memory;

    /* reserve twilight zone */
    n_twilight = maxp->maxTwilightPoints;
363
    error = TT_New_GlyphZone( memory, n_twilight, 0, &size->twilight );
David Turner's avatar
David Turner committed
364
365
366
367
368
369
370
    if ( error )
      goto Fail_Memory;

    size->twilight.n_points = n_twilight;

    /* set `face->interpreter' according to the debug hook present */
    {
David Turner's avatar
David Turner committed
371
      FT_Library  library = face->root.driver->root.library;
372

Werner Lemberg's avatar
   
Werner Lemberg committed
373

David Turner's avatar
David Turner committed
374
      face->interpreter = (TT_Interpreter)
Werner Lemberg's avatar
   
Werner Lemberg committed
375
376
                            library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE];
      if ( !face->interpreter )
David Turner's avatar
David Turner committed
377
378
379
380
381
382
        face->interpreter = (TT_Interpreter)TT_RunIns;
    }

    /* Fine, now execute the font program! */
    exec = size->context;
    /* size objects used during debugging have their own context */
Werner Lemberg's avatar
   
Werner Lemberg committed
383
384
    if ( !size->debug )
      exec = TT_New_Context( face );
David Turner's avatar
David Turner committed
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406

    if ( !exec )
    {
      error = TT_Err_Could_Not_Find_Context;
      goto Fail_Memory;
    }

    size->GS = tt_default_graphics_state;
    TT_Load_Context( exec, face, size );

    exec->callTop   = 0;
    exec->top       = 0;

    exec->period    = 64;
    exec->phase     = 0;
    exec->threshold = 0;

    {
      FT_Size_Metrics*  metrics    = &exec->metrics;
      TT_Size_Metrics*  tt_metrics = &exec->tt_metrics;


Werner Lemberg's avatar
   
Werner Lemberg committed
407
408
409
410
      metrics->x_ppem   = 0;
      metrics->y_ppem   = 0;
      metrics->x_scale  = 0;
      metrics->y_scale  = 0;
David Turner's avatar
David Turner committed
411

Werner Lemberg's avatar
   
Werner Lemberg committed
412
413
414
      tt_metrics->ppem  = 0;
      tt_metrics->scale = 0;
      tt_metrics->ratio = 0x10000L;
David Turner's avatar
David Turner committed
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
    }

    exec->instruction_trap = FALSE;

    exec->cvtSize = size->cvt_size;
    exec->cvt     = size->cvt;

    exec->F_dot_P = 0x10000L;

    /* allow font program execution */
    TT_Set_CodeRange( exec,
                      tt_coderange_font,
                      face->font_program,
                      face->font_program_size );

    /* disable CVT and glyph programs coderange */
    TT_Clear_CodeRange( exec, tt_coderange_cvt );
    TT_Clear_CodeRange( exec, tt_coderange_glyph );

    if ( face->font_program_size > 0 )
    {
      error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 );
      if ( !error )
        error = face->interpreter( exec );

      if ( error )
        goto Fail_Exec;
    }
    else
      error = TT_Err_Ok;

    TT_Save_Context( exec, size );

    if ( !size->debug )
      TT_Done_Context( exec );

451
452
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */

David Turner's avatar
David Turner committed
453
454
455
    size->ttmetrics.valid = FALSE;
    return error;

456
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg's avatar
   
Werner Lemberg committed
457

David Turner's avatar
David Turner committed
458
459
460
461
462
  Fail_Exec:
    if ( !size->debug )
      TT_Done_Context( exec );

  Fail_Memory:
Werner Lemberg's avatar
   
Werner Lemberg committed
463

David Turner's avatar
David Turner committed
464
465
    TT_Done_Size( size );
    return error;
Werner Lemberg's avatar
   
Werner Lemberg committed
466
467
468

#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */

David Turner's avatar
David Turner committed
469
470
471
472
473
474
475
476
477
478
479
480
481
482
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    TT_Done_Size                                                       */
  /*                                                                       */
  /* <Description>                                                         */
  /*    The TrueType size object finalizer.                                */
  /*                                                                       */
  /* <Input>                                                               */
  /*    size :: A handle to the target size object.                        */
  /*                                                                       */
483
  FT_LOCAL_DEF
David Turner's avatar
David Turner committed
484
485
  void  TT_Done_Size( TT_Size  size )
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
486

487
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg's avatar
   
Werner Lemberg committed
488

David Turner's avatar
David Turner committed
489
490
    FT_Memory  memory = size->root.face->memory;

Werner Lemberg's avatar
   
Werner Lemberg committed
491

David Turner's avatar
David Turner committed
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
    if ( size->debug )
    {
      /* the debug context must be deleted by the debugger itself */
      size->context = NULL;
      size->debug   = FALSE;
    }

    FREE( size->cvt );
    size->cvt_size = 0;

    /* free storage area */
    FREE( size->storage );
    size->storage_size = 0;

    /* twilight zone */
507
    TT_Done_GlyphZone( &size->twilight );
David Turner's avatar
David Turner committed
508
509
510

    FREE( size->function_defs );
    FREE( size->instruction_defs );
Werner Lemberg's avatar
   
Werner Lemberg committed
511

David Turner's avatar
David Turner committed
512
513
514
515
516
517
518
    size->num_function_defs    = 0;
    size->max_function_defs    = 0;
    size->num_instruction_defs = 0;
    size->max_instruction_defs = 0;

    size->max_func = 0;
    size->max_ins  = 0;
Werner Lemberg's avatar
   
Werner Lemberg committed
519

520
#endif
David Turner's avatar
David Turner committed
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537

    size->ttmetrics.valid = FALSE;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    TT_Reset_Size                                                      */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Resets a TrueType size when resolutions and character dimensions   */
  /*    have been changed.                                                 */
  /*                                                                       */
  /* <Input>                                                               */
  /*    size :: A handle to the target size object.                        */
  /*                                                                       */
538
  FT_LOCAL
539
  FT_Error  TT_Reset_Size( TT_Size  size )
David Turner's avatar
David Turner committed
540
  {
541
    TT_Face   face;
542
    FT_Error  error = TT_Err_Ok;
David Turner's avatar
David Turner committed
543
544
545

    FT_Size_Metrics*  metrics;

Werner Lemberg's avatar
   
Werner Lemberg committed
546

David Turner's avatar
David Turner committed
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
    if ( size->ttmetrics.valid )
      return TT_Err_Ok;

    face = (TT_Face)size->root.face;

    metrics = &size->root.metrics;

    if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 )
      return TT_Err_Invalid_PPem;

    /* compute new transformation */
    if ( metrics->x_ppem >= metrics->y_ppem )
    {
      size->ttmetrics.scale   = metrics->x_scale;
      size->ttmetrics.ppem    = metrics->x_ppem;
Werner Lemberg's avatar
   
Werner Lemberg committed
562
      size->ttmetrics.x_ratio = 0x10000L;
David Turner's avatar
David Turner committed
563
564
565
566
567
568
569
570
571
572
573
      size->ttmetrics.y_ratio = FT_MulDiv( metrics->y_ppem,
                                           0x10000L,
                                           metrics->x_ppem );
    }
    else
    {
      size->ttmetrics.scale   = metrics->y_scale;
      size->ttmetrics.ppem    = metrics->y_ppem;
      size->ttmetrics.x_ratio = FT_MulDiv( metrics->x_ppem,
                                           0x10000L,
                                           metrics->y_ppem );
Werner Lemberg's avatar
   
Werner Lemberg committed
574
      size->ttmetrics.y_ratio = 0x10000L;
David Turner's avatar
David Turner committed
575
576
577
    }

    /* Compute root ascender, descender, test height, and max_advance */
Werner Lemberg's avatar
   
Werner Lemberg committed
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619

#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS

    if ( ( !( face->root.face_flags & FT_FACE_FLAG_SCALABLE ) &&
           ( face->root.face_flags & FT_FACE_FLAG_FIXED_SIZES ) ) )
    {
      FT_Int i;


      for ( i = 0; i < face->root.num_fixed_sizes; i++ )
      {
        if ( ( face->sbit_strikes[i].x_ppem  == metrics->x_ppem ) &&
             ( face->sbit_strikes[i].y_ppem == metrics->y_ppem ) )
        {
          /*
           * XXX: We now set horizontal metrics,
           *      but this is not valid if we use vertical layout style
           */
          metrics->ascender =
            face->sbit_strikes[i].hori.ascender * 64;
          metrics->descender =
            face->sbit_strikes[i].hori.descender * 64;
          metrics->height =
            ( face->sbit_strikes[i].hori.ascender -
              face->sbit_strikes[i].hori.descender ) * 64;
          /* XXX: Is this correct? */
          metrics->max_advance =
            ( face->sbit_strikes[i].hori.min_origin_SB +
              face->sbit_strikes[i].hori.max_width +
              face->sbit_strikes[i].hori.min_advance_SB ) * 64;
          break;
        }
      }
      if ( i == face->root.num_fixed_sizes )
        return TT_Err_Invalid_PPem;
    }
    else

#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */

    {
      metrics->ascender    = ( FT_MulFix( face->root.ascender,
Werner Lemberg's avatar
   
Werner Lemberg committed
620
                                          metrics->y_scale ) + 32 ) & -64;
Werner Lemberg's avatar
   
Werner Lemberg committed
621
      metrics->descender   = ( FT_MulFix( face->root.descender,
Werner Lemberg's avatar
   
Werner Lemberg committed
622
                                          metrics->y_scale ) + 32 ) & -64;
Werner Lemberg's avatar
   
Werner Lemberg committed
623
      metrics->height      = ( FT_MulFix( face->root.height,
Werner Lemberg's avatar
   
Werner Lemberg committed
624
                                          metrics->y_scale ) + 32 ) & -64;
Werner Lemberg's avatar
   
Werner Lemberg committed
625
      metrics->max_advance = ( FT_MulFix( face->root.max_advance_width,
Werner Lemberg's avatar
   
Werner Lemberg committed
626
                                          metrics->x_scale ) + 32 ) & -64;
Werner Lemberg's avatar
   
Werner Lemberg committed
627
    }
David Turner's avatar
David Turner committed
628

629
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg's avatar
   
Werner Lemberg committed
630

David Turner's avatar
David Turner committed
631
    {
Werner Lemberg's avatar
   
Werner Lemberg committed
632
633
      TT_ExecContext  exec;
      FT_UInt         i, j;
634

Werner Lemberg's avatar
   
Werner Lemberg committed
635

636
637
638
639
      /* Scale the cvt values to the new ppem.          */
      /* We use by default the y ppem to scale the CVT. */
      for ( i = 0; i < size->cvt_size; i++ )
        size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
640

641
642
643
644
645
646
647
648
      /* All twilight points are originally zero */
      for ( j = 0; j < size->twilight.n_points; j++ )
      {
        size->twilight.org[j].x = 0;
        size->twilight.org[j].y = 0;
        size->twilight.cur[j].x = 0;
        size->twilight.cur[j].y = 0;
      }
649

650
651
652
      /* clear storage area */
      for ( i = 0; i < size->storage_size; i++ )
        size->storage[i] = 0;
653

654
      size->GS = tt_default_graphics_state;
655

656
657
658
659
660
661
      /* get execution context and run prep program */
      if ( size->debug )
        exec = size->context;
      else
        exec = TT_New_Context( face );
      /* debugging instances have their own context */
662

663
664
      if ( !exec )
        return TT_Err_Could_Not_Find_Context;
665

666
      TT_Load_Context( exec, face, size );
667

668
669
670
671
      TT_Set_CodeRange( exec,
                        tt_coderange_cvt,
                        face->cvt_program,
                        face->cvt_program_size );
672

673
      TT_Clear_CodeRange( exec, tt_coderange_glyph );
674

675
      exec->instruction_trap = FALSE;
676

677
678
      exec->top     = 0;
      exec->callTop = 0;
679

680
681
682
683
      if ( face->cvt_program_size > 0 )
      {
        error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
        if ( error )
Werner Lemberg's avatar
   
Werner Lemberg committed
684
          goto End;
685

686
687
688
689
690
        if ( !size->debug )
          error = face->interpreter( exec );
      }
      else
        error = TT_Err_Ok;
691

692
693
      size->GS = exec->GS;
      /* save default graphics state */
694

Werner Lemberg's avatar
   
Werner Lemberg committed
695
    End:
696
      TT_Save_Context( exec, size );
697

David Turner's avatar
David Turner committed
698
      if ( !size->debug )
699
700
        TT_Done_Context( exec );
      /* debugging instances keep their context */
David Turner's avatar
David Turner committed
701
    }
Werner Lemberg's avatar
   
Werner Lemberg committed
702

703
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
David Turner's avatar
David Turner committed
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723

    if ( !error )
      size->ttmetrics.valid = TRUE;

    return error;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    TT_Init_Driver                                                     */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Initializes a given TrueType driver object.                        */
  /*                                                                       */
  /* <Input>                                                               */
  /*    driver :: A handle to the target driver object.                    */
  /*                                                                       */
  /* <Return>                                                              */
Werner Lemberg's avatar
   
Werner Lemberg committed
724
  /*    FreeType error code.  0 means success.                             */
David Turner's avatar
David Turner committed
725
  /*                                                                       */
726
  FT_LOCAL_DEF
727
  FT_Error  TT_Init_Driver( TT_Driver  driver )
David Turner's avatar
David Turner committed
728
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
729
    FT_Error  error;
Werner Lemberg's avatar
   
Werner Lemberg committed
730

Werner Lemberg's avatar
   
Werner Lemberg committed
731
732
733

    /* set `extra' in glyph loader */
    error = FT_GlyphLoader_Create_Extra( FT_DRIVER( driver )->glyph_loader );
Werner Lemberg's avatar
   
Werner Lemberg committed
734

David Turner's avatar
David Turner committed
735
    /* init extension registry if needed */
Werner Lemberg's avatar
   
Werner Lemberg committed
736

David Turner's avatar
David Turner committed
737
#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
Werner Lemberg's avatar
   
Werner Lemberg committed
738
    if ( !error )
David Turner's avatar
David Turner committed
739
      return TT_Init_Extensions( driver );
David Turner's avatar
David Turner committed
740
#endif
David Turner's avatar
David Turner committed
741
742

    return error;
David Turner's avatar
David Turner committed
743
744
745
746
747
748
749
750
751
752
753
754
755
756
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    TT_Done_Driver                                                     */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Finalizes a given TrueType driver.                                 */
  /*                                                                       */
  /* <Input>                                                               */
  /*    driver :: A handle to the target TrueType driver.                  */
  /*                                                                       */
757
  FT_LOCAL_DEF
David Turner's avatar
David Turner committed
758
759
760
  void  TT_Done_Driver( TT_Driver  driver )
  {
    /* destroy extensions registry if needed */
Werner Lemberg's avatar
   
Werner Lemberg committed
761

David Turner's avatar
David Turner committed
762
#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
Werner Lemberg's avatar
   
Werner Lemberg committed
763

David Turner's avatar
David Turner committed
764
    TT_Done_Extensions( driver );
Werner Lemberg's avatar
   
Werner Lemberg committed
765

David Turner's avatar
David Turner committed
766
767
#endif

768
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg's avatar
   
Werner Lemberg committed
769

David Turner's avatar
David Turner committed
770
771
772
    /* destroy the execution context */
    if ( driver->context )
    {
David Turner's avatar
David Turner committed
773
      TT_Destroy_Context( driver->context, driver->root.root.memory );
David Turner's avatar
David Turner committed
774
775
      driver->context = NULL;
    }
776
#else
Werner Lemberg's avatar
   
Werner Lemberg committed
777
    FT_UNUSED( driver );
778
#endif
Werner Lemberg's avatar
   
Werner Lemberg committed
779

David Turner's avatar
David Turner committed
780
781
782
783
  }


/* END */