ttobjs.c 30.3 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-2001 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
/*  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.                                        */
/*                                                                         */
/***************************************************************************/

Werner Lemberg's avatar
   
Werner Lemberg committed
18

19
20
21
22
#include <ft2build.h>
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_CALC_H
#include FT_INTERNAL_STREAM_H
23
#include FT_TRUETYPE_IDS_H
24
25
26
27
#include FT_TRUETYPE_TAGS_H
#include FT_INTERNAL_SFNT_H
#include FT_INTERNAL_POSTSCRIPT_NAMES_H

28
29
#include "ttgload.h"
#include "ttpload.h"
Werner Lemberg's avatar
   
Werner Lemberg committed
30

31
32
#include "tterrors.h"

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

Werner Lemberg's avatar
   
Werner Lemberg committed
37
38
39
40
41
42
43

  /*************************************************************************/
  /*                                                                       */
  /* 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
44
45
#undef  FT_COMPONENT
#define FT_COMPONENT  trace_ttobjs
David Turner's avatar
David Turner committed
46
47


Werner Lemberg's avatar
   
Werner Lemberg committed
48
49
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER

David Turner's avatar
David Turner committed
50
51
52
53
54
55
  /*************************************************************************/
  /*                                                                       */
  /*                       GLYPH ZONE FUNCTIONS                            */
  /*                                                                       */
  /*************************************************************************/

Werner Lemberg's avatar
   
Werner Lemberg committed
56

57
58
59
60
61
62
63
64
65
66
67
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    TT_Done_GlyphZone                                                  */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Deallocates a glyph zone.                                          */
  /*                                                                       */
  /* <Input>                                                               */
  /*    zone :: A pointer to the target glyph zone.                        */
  /*                                                                       */
68
  FT_LOCAL_DEF( void )
69
  TT_Done_GlyphZone( TT_GlyphZone   zone )
70
71
72
  {
    FT_Memory  memory = zone->memory;

Werner Lemberg's avatar
   
Werner Lemberg committed
73

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
    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.                             */
  /*                                                                       */
105
  FT_LOCAL_DEF( FT_Error )
Werner Lemberg's avatar
   
Werner Lemberg committed
106
107
108
  TT_New_GlyphZone( FT_Memory      memory,
                    FT_UShort      maxPoints,
                    FT_Short       maxContours,
109
                    TT_GlyphZone   zone )
110
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
111
112
    FT_Error  error;

113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

    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
130
131
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */

132

David Turner's avatar
David Turner committed
133
134
135
136
137
138
139
140
141
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    TT_Init_Face                                                       */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Initializes a given TrueType face object.                          */
  /*                                                                       */
  /* <Input>                                                               */
Werner Lemberg's avatar
   
Werner Lemberg committed
142
143
  /*    stream     :: The source font stream.                              */
  /*                                                                       */
David Turner's avatar
David Turner committed
144
  /*    face_index :: The index of the font face in the resource.          */
Werner Lemberg's avatar
   
Werner Lemberg committed
145
146
147
148
149
150
  /*                                                                       */
  /*    num_params :: Number of additional generic parameters.  Ignored.   */
  /*                                                                       */
  /*    params     :: Additional generic parameters.  Ignored.             */
  /*                                                                       */
  /* <InOut>                                                               */
David Turner's avatar
David Turner committed
151
152
153
  /*    face       :: The newly built face object.                         */
  /*                                                                       */
  /* <Return>                                                              */
Werner Lemberg's avatar
   
Werner Lemberg committed
154
  /*    FreeType error code.  0 means success.                             */
David Turner's avatar
David Turner committed
155
  /*                                                                       */
156
  FT_LOCAL_DEF( FT_Error )
Werner Lemberg's avatar
   
Werner Lemberg committed
157
158
159
160
161
  TT_Init_Face( FT_Stream      stream,
                TT_Face        face,
                FT_Int         face_index,
                FT_Int         num_params,
                FT_Parameter*  params )
David Turner's avatar
David Turner committed
162
  {
163
    FT_Error         error;
David Turner's avatar
David Turner committed
164
    FT_Library       library;
165
    SFNT_Service  sfnt;
Werner Lemberg's avatar
   
Werner Lemberg committed
166

Werner Lemberg's avatar
   
Werner Lemberg committed
167

David Turner's avatar
David Turner committed
168
    library = face->root.driver->root.library;
169
    sfnt    = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" );
Werner Lemberg's avatar
   
Werner Lemberg committed
170
171
    if ( !sfnt )
      goto Bad_Format;
172

David Turner's avatar
David Turner committed
173
    /* create input stream from resource */
Werner Lemberg's avatar
   
Werner Lemberg committed
174
    if ( FILE_Seek( 0 ) )
David Turner's avatar
David Turner committed
175
176
      goto Exit;

177
    /* check that we have a valid TrueType file */
178
    error = sfnt->init_face( stream, face, face_index, num_params, params );
Werner Lemberg's avatar
   
Werner Lemberg committed
179
180
    if ( error )
      goto Exit;
181

182
    /* We must also be able to accept Mac/GX fonts, as well as OT ones */
Werner Lemberg's avatar
   
Werner Lemberg committed
183
184
    if ( face->format_tag != 0x00010000L &&    /* MS fonts  */
         face->format_tag != TTAG_true   )     /* Mac fonts */
185
    {
Werner Lemberg's avatar
   
Werner Lemberg committed
186
      FT_TRACE2(( "[not a valid TTF font]\n" ));
187
      goto Bad_Format;
188
189
    }

Werner Lemberg's avatar
   
Werner Lemberg committed
190
    /* If we are performing a simple font format check, exit immediately */
David Turner's avatar
David Turner committed
191
192
193
    if ( face_index < 0 )
      return TT_Err_Ok;

194
195
    /* Load font directory */
    error = sfnt->load_face( stream, face, face_index, num_params, params );
Werner Lemberg's avatar
   
Werner Lemberg committed
196
197
    if ( error )
      goto Exit;
David Turner's avatar
David Turner committed
198

Werner Lemberg's avatar
   
Werner Lemberg committed
199
200
201
202
    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
203

Werner Lemberg's avatar
   
Werner Lemberg committed
204
    /* initialize standard glyph loading routines */
205
206
    TT_Init_Glyph_Loading( face );

David Turner's avatar
David Turner committed
207
208
  Exit:
    return error;
Werner Lemberg's avatar
   
Werner Lemberg committed
209

210
  Bad_Format:
Werner Lemberg's avatar
Werner Lemberg committed
211
    error = TT_Err_Unknown_File_Format;
212
    goto Exit;
David Turner's avatar
David Turner committed
213
214
215
216
217
218
219
220
221
222
223
224
225
226
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    TT_Done_Face                                                       */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Finalizes a given face object.                                     */
  /*                                                                       */
  /* <Input>                                                               */
  /*    face :: A pointer to the face object to destroy.                   */
  /*                                                                       */
227
  FT_LOCAL_DEF( void )
Werner Lemberg's avatar
   
Werner Lemberg committed
228
  TT_Done_Face( TT_Face  face )
David Turner's avatar
David Turner committed
229
230
  {
    FT_Memory  memory = face->root.memory;
231
    FT_Stream  stream = face->root.stream;
David Turner's avatar
David Turner committed
232

233
    SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
234

Werner Lemberg's avatar
   
Werner Lemberg committed
235

Werner Lemberg's avatar
   
Werner Lemberg committed
236
237
    /* for `extended TrueType formats' (i.e. compressed versions) */
    if ( face->extra.finalizer )
238
      face->extra.finalizer( face->extra.data );
Werner Lemberg's avatar
   
Werner Lemberg committed
239
240
241

    if ( sfnt )
      sfnt->done_face( face );
David Turner's avatar
David Turner committed
242
243
244
245
246
247
248
249
250
251

    /* 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 */
252
253
    RELEASE_Frame( face->font_program );
    RELEASE_Frame( face->cvt_program );
David Turner's avatar
David Turner committed
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
    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
278
  /*    FreeType error code.  0 means success.                             */
David Turner's avatar
David Turner committed
279
  /*                                                                       */
280
  FT_LOCAL_DEF( FT_Error )
Werner Lemberg's avatar
   
Werner Lemberg committed
281
  TT_Init_Size( TT_Size  size )
David Turner's avatar
David Turner committed
282
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
283
284
    FT_Error  error = TT_Err_Ok;

285

286
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg's avatar
   
Werner Lemberg committed
287

David Turner's avatar
David Turner committed
288
289
    TT_Face    face   = (TT_Face)size->root.face;
    FT_Memory  memory = face->root.memory;
290
    FT_Int     i;
David Turner's avatar
David Turner committed
291
292

    TT_ExecContext  exec;
293
    FT_UShort       n_twilight;
294
    TT_MaxProfile*  maxp = &face->max_profile;
David Turner's avatar
David Turner committed
295

Werner Lemberg's avatar
   
Werner Lemberg committed
296

David Turner's avatar
David Turner committed
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
    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
316

David Turner's avatar
David Turner committed
317
318
319
320
321
322
323
324
325
326
327
      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
328
    /* allocate function defs, instruction defs, cvt, and storage area */
David Turner's avatar
David Turner committed
329
330
331
332
333
334
335
336
337
    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,
338
                      size->cvt_size, FT_Long )     ||
David Turner's avatar
David Turner committed
339
340

         ALLOC_ARRAY( size->storage,
341
                      size->storage_size, FT_Long ) )
David Turner's avatar
David Turner committed
342
343
344
345
346

      goto Fail_Memory;

    /* reserve twilight zone */
    n_twilight = maxp->maxTwilightPoints;
347
    error = TT_New_GlyphZone( memory, n_twilight, 0, &size->twilight );
David Turner's avatar
David Turner committed
348
349
350
351
352
353
354
    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
355
      FT_Library  library = face->root.driver->root.library;
356

Werner Lemberg's avatar
   
Werner Lemberg committed
357

David Turner's avatar
David Turner committed
358
      face->interpreter = (TT_Interpreter)
Werner Lemberg's avatar
   
Werner Lemberg committed
359
360
                            library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE];
      if ( !face->interpreter )
David Turner's avatar
David Turner committed
361
362
363
364
365
366
        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
367
368
    if ( !size->debug )
      exec = TT_New_Context( face );
David Turner's avatar
David Turner committed
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390

    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
391
392
393
394
      metrics->x_ppem   = 0;
      metrics->y_ppem   = 0;
      metrics->x_scale  = 0;
      metrics->y_scale  = 0;
David Turner's avatar
David Turner committed
395

Werner Lemberg's avatar
   
Werner Lemberg committed
396
397
398
      tt_metrics->ppem  = 0;
      tt_metrics->scale = 0;
      tt_metrics->ratio = 0x10000L;
David Turner's avatar
David Turner committed
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
    }

    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 );

435
436
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */

David Turner's avatar
David Turner committed
437
438
439
    size->ttmetrics.valid = FALSE;
    return error;

440
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg's avatar
   
Werner Lemberg committed
441

David Turner's avatar
David Turner committed
442
443
444
445
446
  Fail_Exec:
    if ( !size->debug )
      TT_Done_Context( exec );

  Fail_Memory:
Werner Lemberg's avatar
   
Werner Lemberg committed
447

David Turner's avatar
David Turner committed
448
449
    TT_Done_Size( size );
    return error;
Werner Lemberg's avatar
   
Werner Lemberg committed
450
451
452

#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */

David Turner's avatar
David Turner committed
453
454
455
456
457
458
459
460
461
462
463
464
465
466
  }


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

471
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg's avatar
   
Werner Lemberg committed
472

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

Werner Lemberg's avatar
   
Werner Lemberg committed
475

David Turner's avatar
David Turner committed
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
    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 */
491
    TT_Done_GlyphZone( &size->twilight );
David Turner's avatar
David Turner committed
492
493
494

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

David Turner's avatar
David Turner committed
496
497
498
499
500
501
502
    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
503

504
#endif
David Turner's avatar
David Turner committed
505
506
507
508
509
510
511
512

    size->ttmetrics.valid = FALSE;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
Werner Lemberg's avatar
   
Werner Lemberg committed
513
  /*    Reset_Outline_Size                                                 */
David Turner's avatar
David Turner committed
514
515
  /*                                                                       */
  /* <Description>                                                         */
Werner Lemberg's avatar
   
Werner Lemberg committed
516
517
  /*    Resets a TrueType outline size when resolutions and character      */
  /*    dimensions have been changed.                                      */
David Turner's avatar
David Turner committed
518
519
520
521
  /*                                                                       */
  /* <Input>                                                               */
  /*    size :: A handle to the target size object.                        */
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
522
523
  static FT_Error
  Reset_Outline_Size( TT_Size  size )
David Turner's avatar
David Turner committed
524
  {
525
    TT_Face   face;
526
    FT_Error  error = TT_Err_Ok;
David Turner's avatar
David Turner committed
527
528
529

    FT_Size_Metrics*  metrics;

Werner Lemberg's avatar
   
Werner Lemberg committed
530

David Turner's avatar
David Turner committed
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
    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
546
      size->ttmetrics.x_ratio = 0x10000L;
David Turner's avatar
David Turner committed
547
548
549
550
551
552
553
554
555
556
557
      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
558
      size->ttmetrics.y_ratio = 0x10000L;
David Turner's avatar
David Turner committed
559
560
561
    }

    /* Compute root ascender, descender, test height, and max_advance */
Werner Lemberg's avatar
   
Werner Lemberg committed
562
563
564
565
566
567
568
569
    metrics->ascender    = ( FT_MulFix( face->root.ascender,
                                        metrics->y_scale ) + 32 ) & -64;
    metrics->descender   = ( FT_MulFix( face->root.descender,
                                        metrics->y_scale ) + 32 ) & -64;
    metrics->height      = ( FT_MulFix( face->root.height,
                                        metrics->y_scale ) + 32 ) & -64;
    metrics->max_advance = ( FT_MulFix( face->root.max_advance_width,
                                        metrics->x_scale ) + 32 ) & -64;
David Turner's avatar
David Turner committed
570

571
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
Werner Lemberg's avatar
   
Werner Lemberg committed
572
    /* set to `invalid' by default */
573
574
575
    size->strike_index = 0xFFFF;
#endif

576
577
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER

David Turner's avatar
David Turner committed
578
    {
Werner Lemberg's avatar
   
Werner Lemberg committed
579
580
      TT_ExecContext  exec;
      FT_UInt         i, j;
581

Werner Lemberg's avatar
   
Werner Lemberg committed
582

583
584
585
586
      /* 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 );
587

588
      /* All twilight points are originally zero */
589
      for ( j = 0; j < (FT_UInt)size->twilight.n_points; j++ )
590
591
592
593
594
595
      {
        size->twilight.org[j].x = 0;
        size->twilight.org[j].y = 0;
        size->twilight.cur[j].x = 0;
        size->twilight.cur[j].y = 0;
      }
596

597
      /* clear storage area */
598
      for ( i = 0; i < (FT_UInt)size->storage_size; i++ )
599
        size->storage[i] = 0;
600

601
      size->GS = tt_default_graphics_state;
602

603
604
605
606
607
608
      /* 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 */
609

610
611
      if ( !exec )
        return TT_Err_Could_Not_Find_Context;
612

613
      TT_Load_Context( exec, face, size );
614

615
616
617
618
      TT_Set_CodeRange( exec,
                        tt_coderange_cvt,
                        face->cvt_program,
                        face->cvt_program_size );
619

620
      TT_Clear_CodeRange( exec, tt_coderange_glyph );
621

622
      exec->instruction_trap = FALSE;
623

624
625
      exec->top     = 0;
      exec->callTop = 0;
626

627
628
629
630
      if ( face->cvt_program_size > 0 )
      {
        error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
        if ( error )
Werner Lemberg's avatar
   
Werner Lemberg committed
631
          goto End;
632

633
634
635
636
637
        if ( !size->debug )
          error = face->interpreter( exec );
      }
      else
        error = TT_Err_Ok;
638

639
640
      size->GS = exec->GS;
      /* save default graphics state */
641

Werner Lemberg's avatar
   
Werner Lemberg committed
642
    End:
643
      TT_Save_Context( exec, size );
644

David Turner's avatar
David Turner committed
645
      if ( !size->debug )
646
647
        TT_Done_Context( exec );
      /* debugging instances keep their context */
David Turner's avatar
David Turner committed
648
    }
Werner Lemberg's avatar
   
Werner Lemberg committed
649

650
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
David Turner's avatar
David Turner committed
651
652
653
654
655
656
657

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

    return error;
  }

Werner Lemberg's avatar
   
Werner Lemberg committed
658

659
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
Werner Lemberg's avatar
   
Werner Lemberg committed
660
661
662
663
664
665
666
667
668
669
670
671
672

  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    Reset_SBit_Size                                                    */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Resets a TrueType sbit size when resolutions and character         */
  /*    dimensions have been changed.                                      */
  /*                                                                       */
  /* <Input>                                                               */
  /*    size :: A handle to the target size object.                        */
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
673
674
  static FT_Error
  Reset_SBit_Size( TT_Size  size )
675
676
677
678
679
680
681
  {
    TT_Face           face;
    FT_Error          error = TT_Err_Ok;

    FT_ULong          strike_index;
    FT_Size_Metrics*  metrics;
    FT_Size_Metrics*  sbit_metrics;
682
    SFNT_Service   sfnt;
683

Werner Lemberg's avatar
   
Werner Lemberg committed
684

685
686
    metrics = &size->root.metrics;

Werner Lemberg's avatar
   
Werner Lemberg committed
687
    if ( size->strike_index != 0xFFFF )
688
689
690
      return TT_Err_Ok;

    face = (TT_Face)size->root.face;
691
    sfnt = (SFNT_Service)face->sfnt;
692
693
694
695

    sbit_metrics = &size->strike_metrics;

    error = sfnt->set_sbit_strike(face,
Werner Lemberg's avatar
   
Werner Lemberg committed
696
697
                                  metrics->x_ppem, metrics->y_ppem,
                                  &strike_index);
698

Werner Lemberg's avatar
   
Werner Lemberg committed
699
    if ( !error )
700
    {
701
      TT_SBit_Strike   strike = face->sbit_strikes + strike_index;
Werner Lemberg's avatar
   
Werner Lemberg committed
702
703


Werner Lemberg's avatar
   
Werner Lemberg committed
704
705
      sbit_metrics->x_ppem      = metrics->x_ppem;
      sbit_metrics->y_ppem      = metrics->y_ppem;
706
707
708
709
710
#if 0
      /*
       * sbit_metrics->?_scale
       * are not used now.
       */
Werner Lemberg's avatar
   
Werner Lemberg committed
711
712
      sbit_metrics->x_scale     = 1 << 16;
      sbit_metrics->y_scale     = 1 << 16;
713
#endif
Werner Lemberg's avatar
   
Werner Lemberg committed
714

Werner Lemberg's avatar
   
Werner Lemberg committed
715
716
      sbit_metrics->ascender    = strike->hori.ascender << 6;
      sbit_metrics->descender   = strike->hori.descender << 6;
Werner Lemberg's avatar
   
Werner Lemberg committed
717

718
      /* XXX: Is this correct? */
Werner Lemberg's avatar
   
Werner Lemberg committed
719
720
      sbit_metrics->height      = sbit_metrics->ascender -
                                  sbit_metrics->descender;
Werner Lemberg's avatar
   
Werner Lemberg committed
721

722
723
724
725
726
727
728
729
730
731
      /* XXX: Is this correct? */
      sbit_metrics->max_advance = ( strike->hori.min_origin_SB +
                                    strike->hori.max_width     +
                                    strike->hori.min_advance_SB ) << 6;

      size->strike_index = strike_index;
    }
    else
    {
      size->strike_index = 0xFFFF;
Werner Lemberg's avatar
   
Werner Lemberg committed
732

733
734
735
736
737
738
739
740
741
742
      sbit_metrics->x_ppem      = 0;
      sbit_metrics->y_ppem      = 0;
      sbit_metrics->ascender    = 0;
      sbit_metrics->descender   = 0;
      sbit_metrics->height      = 0;
      sbit_metrics->max_advance = 0;
    }

    return error;
  }
Werner Lemberg's avatar
   
Werner Lemberg committed
743

744
745
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */

Werner Lemberg's avatar
   
Werner Lemberg committed
746

747
748
749
750
751
752
753
754
755
756
757
758
  /*************************************************************************/
  /*                                                                       */
  /* <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.                        */
  /*                                                                       */
759
  FT_LOCAL_DEF( FT_Error )
Werner Lemberg's avatar
   
Werner Lemberg committed
760
  TT_Reset_Size( TT_Size  size )
761
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
762
    FT_Face   face;
763
764
    FT_Error  error = TT_Err_Ok;

Werner Lemberg's avatar
   
Werner Lemberg committed
765

766
767
768
769
770
    face = size->root.face;

    if ( face->face_flags & FT_FACE_FLAG_SCALABLE )
    {
      if ( !size->ttmetrics.valid )
Werner Lemberg's avatar
   
Werner Lemberg committed
771
        error = Reset_Outline_Size( size );
772
773

      if ( error )
Werner Lemberg's avatar
   
Werner Lemberg committed
774
        return error;
775
776
777
    }

#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
Werner Lemberg's avatar
   
Werner Lemberg committed
778

779
780
781
782
783
    if ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES )
    {
      if ( size->strike_index == 0xFFFF )
        error = Reset_SBit_Size( size );

Werner Lemberg's avatar
   
Werner Lemberg committed
784
      if ( !error && !( face->face_flags & FT_FACE_FLAG_SCALABLE ) )
785
        size->root.metrics = size->strike_metrics;
786
    }
Werner Lemberg's avatar
   
Werner Lemberg committed
787
788
789
790

#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */

    if ( face->face_flags & FT_FACE_FLAG_SCALABLE )
791
792
793
794
      return TT_Err_Ok;
    else
      return error;
  }
David Turner's avatar
David Turner committed
795

Werner Lemberg's avatar
   
Werner Lemberg committed
796

David Turner's avatar
David Turner committed
797
798
799
800
801
802
803
804
805
806
807
808
  /*************************************************************************/
  /*                                                                       */
  /* <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
809
  /*    FreeType error code.  0 means success.                             */
David Turner's avatar
David Turner committed
810
  /*                                                                       */
811
  FT_LOCAL_DEF( FT_Error )
Werner Lemberg's avatar
   
Werner Lemberg committed
812
  TT_Init_Driver( TT_Driver  driver )
David Turner's avatar
David Turner committed
813
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
814
    FT_Error  error;
Werner Lemberg's avatar
   
Werner Lemberg committed
815

Werner Lemberg's avatar
   
Werner Lemberg committed
816
817

    /* set `extra' in glyph loader */
David Turner's avatar
David Turner committed
818
    error = FT_GlyphLoader_CreateExtra( FT_DRIVER( driver )->glyph_loader );
Werner Lemberg's avatar
   
Werner Lemberg committed
819

David Turner's avatar
David Turner committed
820
    /* init extension registry if needed */
Werner Lemberg's avatar
   
Werner Lemberg committed
821

David Turner's avatar
David Turner committed
822
#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
Werner Lemberg's avatar
   
Werner Lemberg committed
823
    if ( !error )
David Turner's avatar
David Turner committed
824
      return TT_Init_Extensions( driver );
David Turner's avatar
David Turner committed
825
#endif
David Turner's avatar
David Turner committed
826
827

    return error;
David Turner's avatar
David Turner committed
828
829
830
831
832
833
834
835
836
837
838
839
840
841
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    TT_Done_Driver                                                     */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Finalizes a given TrueType driver.                                 */
  /*                                                                       */
  /* <Input>                                                               */
  /*    driver :: A handle to the target TrueType driver.                  */
  /*                                                                       */
842
  FT_LOCAL_DEF( void )
Werner Lemberg's avatar
   
Werner Lemberg committed
843
  TT_Done_Driver( TT_Driver  driver )
David Turner's avatar
David Turner committed
844
845
  {
    /* destroy extensions registry if needed */
Werner Lemberg's avatar
   
Werner Lemberg committed
846

David Turner's avatar
David Turner committed
847
#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
Werner Lemberg's avatar
   
Werner Lemberg committed
848

David Turner's avatar
David Turner committed
849
    TT_Done_Extensions( driver );
Werner Lemberg's avatar
   
Werner Lemberg committed
850

David Turner's avatar
David Turner committed
851
852
#endif

853
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg's avatar
   
Werner Lemberg committed
854

David Turner's avatar
David Turner committed
855
856
857
    /* destroy the execution context */
    if ( driver->context )
    {
David Turner's avatar
David Turner committed
858
      TT_Destroy_Context( driver->context, driver->root.root.memory );
David Turner's avatar
David Turner committed
859
860
      driver->context = NULL;
    }
861
#else
Werner Lemberg's avatar
   
Werner Lemberg committed
862
    FT_UNUSED( driver );
863
#endif
Werner Lemberg's avatar
   
Werner Lemberg committed
864

David Turner's avatar
David Turner committed
865
866
867
868
  }


/* END */