ttobjs.c 29.9 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, 2002 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 )
Werner Lemberg's avatar
   
Werner Lemberg committed
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
    FT_FREE( zone->contours );
    FT_FREE( zone->tags );
    FT_FREE( zone->cur );
    FT_FREE( zone->org );
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

    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
109
  TT_New_GlyphZone( FT_Memory     memory,
                    FT_UShort     maxPoints,
                    FT_Short      maxContours,
                    TT_GlyphZone  zone )
110
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
111
112
    FT_Error  error;

113
114
115
116

    if ( maxPoints > 0 )
      maxPoints += 2;

117
    FT_MEM_SET( zone, 0, sizeof ( *zone ) );
118
119
    zone->memory = memory;

120
121
122
123
    if ( FT_NEW_ARRAY( zone->org,      maxPoints * 2 ) ||
         FT_NEW_ARRAY( zone->cur,      maxPoints * 2 ) ||
         FT_NEW_ARRAY( zone->tags,     maxPoints     ) ||
         FT_NEW_ARRAY( zone->contours, maxContours   ) )
124
125
126
127
128
129
    {
      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
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
Werner Lemberg's avatar
   
Werner Lemberg committed
136
  /*    TT_Face_Init                                                       */
David Turner's avatar
David Turner committed
137
138
139
140
141
  /*                                                                       */
  /* <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
  TT_Face_Init( FT_Stream      stream,
Werner Lemberg's avatar
   
Werner Lemberg committed
158
159
160
161
                TT_Face        face,
                FT_Int         face_index,
                FT_Int         num_params,
                FT_Parameter*  params )
David Turner's avatar
David Turner committed
162
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
163
164
    FT_Error      error;
    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 */
174
    if ( FT_STREAM_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
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
Werner Lemberg's avatar
   
Werner Lemberg committed
219
  /*    TT_Face_Done                                                       */
David Turner's avatar
David Turner committed
220
221
222
223
224
225
226
  /*                                                                       */
  /* <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_Face_Done( TT_Face  face )
David Turner's avatar
David Turner committed
229
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
230
231
    FT_Memory     memory = face->root.memory;
    FT_Stream     stream = face->root.stream;
David Turner's avatar
David Turner committed
232

Werner Lemberg's avatar
   
Werner Lemberg committed
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

    /* freeing the locations table */
244
    FT_FREE( face->glyph_locations );
David Turner's avatar
David Turner committed
245
246
247
    face->num_locations = 0;

    /* freeing the CVT */
248
    FT_FREE( face->cvt );
David Turner's avatar
David Turner committed
249
250
251
    face->cvt_size = 0;

    /* freeing the programs */
252
253
    FT_FRAME_RELEASE( face->font_program );
    FT_FRAME_RELEASE( 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
    face->font_program_size = 0;
    face->cvt_program_size  = 0;
  }


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


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
Werner Lemberg's avatar
   
Werner Lemberg committed
269
  /*    TT_Size_Init                                                       */
David Turner's avatar
David Turner committed
270
271
272
273
274
275
276
277
  /*                                                                       */
  /* <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_Size_Init( 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 */
Werner Lemberg's avatar
   
Werner Lemberg committed
329
    if ( FT_NEW_ARRAY( size->function_defs,    size->max_function_defs    ) ||
330
         FT_NEW_ARRAY( size->instruction_defs, size->max_instruction_defs ) ||
Werner Lemberg's avatar
   
Werner Lemberg committed
331
332
         FT_NEW_ARRAY( size->cvt,              size->cvt_size             ) ||
         FT_NEW_ARRAY( size->storage,          size->storage_size         ) )
David Turner's avatar
David Turner committed
333
334
335
336
337

      goto Fail_Memory;

    /* reserve twilight zone */
    n_twilight = maxp->maxTwilightPoints;
338
    error = TT_New_GlyphZone( memory, n_twilight, 0, &size->twilight );
David Turner's avatar
David Turner committed
339
340
341
342
343
344
345
    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
346
      FT_Library  library = face->root.driver->root.library;
347

Werner Lemberg's avatar
   
Werner Lemberg committed
348

David Turner's avatar
David Turner committed
349
      face->interpreter = (TT_Interpreter)
Werner Lemberg's avatar
   
Werner Lemberg committed
350
351
                            library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE];
      if ( !face->interpreter )
David Turner's avatar
David Turner committed
352
353
354
355
356
357
        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
358
359
    if ( !size->debug )
      exec = TT_New_Context( face );
David Turner's avatar
David Turner committed
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381

    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
382
383
384
385
      metrics->x_ppem   = 0;
      metrics->y_ppem   = 0;
      metrics->x_scale  = 0;
      metrics->y_scale  = 0;
David Turner's avatar
David Turner committed
386

Werner Lemberg's avatar
   
Werner Lemberg committed
387
388
389
      tt_metrics->ppem  = 0;
      tt_metrics->scale = 0;
      tt_metrics->ratio = 0x10000L;
David Turner's avatar
David Turner committed
390
391
392
393
394
395
396
397
398
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
    }

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

426
427
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */

David Turner's avatar
David Turner committed
428
429
430
    size->ttmetrics.valid = FALSE;
    return error;

431
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg's avatar
   
Werner Lemberg committed
432

David Turner's avatar
David Turner committed
433
434
435
436
437
  Fail_Exec:
    if ( !size->debug )
      TT_Done_Context( exec );

  Fail_Memory:
Werner Lemberg's avatar
   
Werner Lemberg committed
438

Werner Lemberg's avatar
   
Werner Lemberg committed
439
    TT_Size_Done( size );
David Turner's avatar
David Turner committed
440
    return error;
Werner Lemberg's avatar
   
Werner Lemberg committed
441
442
443

#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */

David Turner's avatar
David Turner committed
444
445
446
447
448
449
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
Werner Lemberg's avatar
   
Werner Lemberg committed
450
  /*    TT_Size_Done                                                       */
David Turner's avatar
David Turner committed
451
452
453
454
455
456
457
  /*                                                                       */
  /* <Description>                                                         */
  /*    The TrueType size object finalizer.                                */
  /*                                                                       */
  /* <Input>                                                               */
  /*    size :: A handle to the target size object.                        */
  /*                                                                       */
458
  FT_LOCAL_DEF( void )
Werner Lemberg's avatar
   
Werner Lemberg committed
459
  TT_Size_Done( TT_Size  size )
David Turner's avatar
David Turner committed
460
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
461

462
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg's avatar
   
Werner Lemberg committed
463

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

Werner Lemberg's avatar
   
Werner Lemberg committed
466

David Turner's avatar
David Turner committed
467
468
469
470
471
472
473
    if ( size->debug )
    {
      /* the debug context must be deleted by the debugger itself */
      size->context = NULL;
      size->debug   = FALSE;
    }

474
    FT_FREE( size->cvt );
David Turner's avatar
David Turner committed
475
476
477
    size->cvt_size = 0;

    /* free storage area */
478
    FT_FREE( size->storage );
David Turner's avatar
David Turner committed
479
480
481
    size->storage_size = 0;

    /* twilight zone */
482
    TT_Done_GlyphZone( &size->twilight );
David Turner's avatar
David Turner committed
483

484
485
    FT_FREE( size->function_defs );
    FT_FREE( size->instruction_defs );
Werner Lemberg's avatar
   
Werner Lemberg committed
486

David Turner's avatar
David Turner committed
487
488
489
490
491
492
493
    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
494

495
#endif
David Turner's avatar
David Turner committed
496
497
498
499
500
501
502
503

    size->ttmetrics.valid = FALSE;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
Werner Lemberg's avatar
   
Werner Lemberg committed
504
  /*    Reset_Outline_Size                                                 */
David Turner's avatar
David Turner committed
505
506
  /*                                                                       */
  /* <Description>                                                         */
Werner Lemberg's avatar
   
Werner Lemberg committed
507
508
  /*    Resets a TrueType outline size when resolutions and character      */
  /*    dimensions have been changed.                                      */
David Turner's avatar
David Turner committed
509
510
511
512
  /*                                                                       */
  /* <Input>                                                               */
  /*    size :: A handle to the target size object.                        */
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
513
514
  static FT_Error
  Reset_Outline_Size( TT_Size  size )
David Turner's avatar
David Turner committed
515
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
516
517
    TT_Face           face;
    FT_Error          error = TT_Err_Ok;
David Turner's avatar
David Turner committed
518
519
520

    FT_Size_Metrics*  metrics;

Werner Lemberg's avatar
   
Werner Lemberg committed
521

David Turner's avatar
David Turner committed
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
    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
537
      size->ttmetrics.x_ratio = 0x10000L;
David Turner's avatar
David Turner committed
538
539
540
541
542
543
544
545
546
547
548
      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
549
      size->ttmetrics.y_ratio = 0x10000L;
David Turner's avatar
David Turner committed
550
551
552
    }

    /* Compute root ascender, descender, test height, and max_advance */
Werner Lemberg's avatar
   
Werner Lemberg committed
553
554
555
556
557
558
559
560
    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
561

562
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
Werner Lemberg's avatar
   
Werner Lemberg committed
563
    /* set to `invalid' by default */
Werner Lemberg's avatar
   
Werner Lemberg committed
564
    size->strike_index = 0xFFFFU;
565
566
#endif

567
568
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER

David Turner's avatar
David Turner committed
569
    {
Werner Lemberg's avatar
   
Werner Lemberg committed
570
571
      TT_ExecContext  exec;
      FT_UInt         i, j;
572

Werner Lemberg's avatar
   
Werner Lemberg committed
573

574
575
576
577
      /* 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 );
578

579
      /* All twilight points are originally zero */
580
      for ( j = 0; j < (FT_UInt)size->twilight.n_points; j++ )
581
582
583
584
585
586
      {
        size->twilight.org[j].x = 0;
        size->twilight.org[j].y = 0;
        size->twilight.cur[j].x = 0;
        size->twilight.cur[j].y = 0;
      }
587

588
      /* clear storage area */
589
      for ( i = 0; i < (FT_UInt)size->storage_size; i++ )
590
        size->storage[i] = 0;
591

592
      size->GS = tt_default_graphics_state;
593

594
595
596
597
598
599
      /* 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 */
600

601
602
      if ( !exec )
        return TT_Err_Could_Not_Find_Context;
603

604
      TT_Load_Context( exec, face, size );
605

606
607
608
609
      TT_Set_CodeRange( exec,
                        tt_coderange_cvt,
                        face->cvt_program,
                        face->cvt_program_size );
610

611
      TT_Clear_CodeRange( exec, tt_coderange_glyph );
612

613
      exec->instruction_trap = FALSE;
614

615
616
      exec->top     = 0;
      exec->callTop = 0;
617

618
619
620
621
      if ( face->cvt_program_size > 0 )
      {
        error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
        if ( error )
Werner Lemberg's avatar
   
Werner Lemberg committed
622
          goto End;
623

624
625
626
627
628
        if ( !size->debug )
          error = face->interpreter( exec );
      }
      else
        error = TT_Err_Ok;
629

630
631
      size->GS = exec->GS;
      /* save default graphics state */
632

Werner Lemberg's avatar
   
Werner Lemberg committed
633
    End:
634
      TT_Save_Context( exec, size );
635

David Turner's avatar
David Turner committed
636
      if ( !size->debug )
637
638
        TT_Done_Context( exec );
      /* debugging instances keep their context */
David Turner's avatar
David Turner committed
639
    }
Werner Lemberg's avatar
   
Werner Lemberg committed
640

641
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
David Turner's avatar
David Turner committed
642
643
644
645
646
647
648

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

    return error;
  }

Werner Lemberg's avatar
   
Werner Lemberg committed
649

650
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
Werner Lemberg's avatar
   
Werner Lemberg committed
651
652
653
654
655
656
657
658
659
660
661
662
663

  /*************************************************************************/
  /*                                                                       */
  /* <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
664
665
  static FT_Error
  Reset_SBit_Size( TT_Size  size )
666
667
668
669
670
671
672
  {
    TT_Face           face;
    FT_Error          error = TT_Err_Ok;

    FT_ULong          strike_index;
    FT_Size_Metrics*  metrics;
    FT_Size_Metrics*  sbit_metrics;
Werner Lemberg's avatar
   
Werner Lemberg committed
673
    SFNT_Service      sfnt;
674

Werner Lemberg's avatar
   
Werner Lemberg committed
675

676
677
    metrics = &size->root.metrics;

Werner Lemberg's avatar
   
Werner Lemberg committed
678
    if ( size->strike_index != 0xFFFFU )
679
680
681
      return TT_Err_Ok;

    face = (TT_Face)size->root.face;
682
    sfnt = (SFNT_Service)face->sfnt;
683
684
685
686

    sbit_metrics = &size->strike_metrics;

    error = sfnt->set_sbit_strike(face,
Werner Lemberg's avatar
   
Werner Lemberg committed
687
688
                                  metrics->x_ppem, metrics->y_ppem,
                                  &strike_index);
689

Werner Lemberg's avatar
   
Werner Lemberg committed
690
    if ( !error )
691
    {
Werner Lemberg's avatar
   
Werner Lemberg committed
692
      TT_SBit_Strike  strike = face->sbit_strikes + strike_index;
Werner Lemberg's avatar
   
Werner Lemberg committed
693
694


Werner Lemberg's avatar
   
Werner Lemberg committed
695
696
      sbit_metrics->x_ppem      = metrics->x_ppem;
      sbit_metrics->y_ppem      = metrics->y_ppem;
697
698
699
700
701
#if 0
      /*
       * sbit_metrics->?_scale
       * are not used now.
       */
Werner Lemberg's avatar
   
Werner Lemberg committed
702
703
      sbit_metrics->x_scale     = 1 << 16;
      sbit_metrics->y_scale     = 1 << 16;
704
#endif
Werner Lemberg's avatar
   
Werner Lemberg committed
705

Werner Lemberg's avatar
   
Werner Lemberg committed
706
707
      sbit_metrics->ascender    = strike->hori.ascender << 6;
      sbit_metrics->descender   = strike->hori.descender << 6;
Werner Lemberg's avatar
   
Werner Lemberg committed
708

709
      /* XXX: Is this correct? */
Werner Lemberg's avatar
   
Werner Lemberg committed
710
711
      sbit_metrics->height      = sbit_metrics->ascender -
                                  sbit_metrics->descender;
Werner Lemberg's avatar
   
Werner Lemberg committed
712

713
714
715
716
717
718
719
720
721
      /* 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
    {
Werner Lemberg's avatar
   
Werner Lemberg committed
722
      size->strike_index = 0xFFFFU;
Werner Lemberg's avatar
   
Werner Lemberg committed
723

724
725
726
727
728
729
730
731
732
733
      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
734

735
736
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */

Werner Lemberg's avatar
   
Werner Lemberg committed
737

738
739
740
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
Werner Lemberg's avatar
   
Werner Lemberg committed
741
  /*    TT_Size_Reset                                                      */
742
743
744
745
746
747
748
749
  /*                                                                       */
  /* <Description>                                                         */
  /*    Resets a TrueType size when resolutions and character dimensions   */
  /*    have been changed.                                                 */
  /*                                                                       */
  /* <Input>                                                               */
  /*    size :: A handle to the target size object.                        */
  /*                                                                       */
750
  FT_LOCAL_DEF( FT_Error )
Werner Lemberg's avatar
   
Werner Lemberg committed
751
  TT_Size_Reset( TT_Size  size )
752
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
753
    FT_Face   face;
754
755
    FT_Error  error = TT_Err_Ok;

Werner Lemberg's avatar
   
Werner Lemberg committed
756

757
758
759
760
761
    face = size->root.face;

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

      if ( error )
Werner Lemberg's avatar
   
Werner Lemberg committed
765
        return error;
766
767
768
    }

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

770
771
    if ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES )
    {
Werner Lemberg's avatar
   
Werner Lemberg committed
772
      if ( size->strike_index == 0xFFFFU )
773
774
        error = Reset_SBit_Size( size );

Werner Lemberg's avatar
   
Werner Lemberg committed
775
      if ( !error && !( face->face_flags & FT_FACE_FLAG_SCALABLE ) )
776
        size->root.metrics = size->strike_metrics;
777
    }
Werner Lemberg's avatar
   
Werner Lemberg committed
778
779
780
781

#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */

    if ( face->face_flags & FT_FACE_FLAG_SCALABLE )
782
783
784
785
      return TT_Err_Ok;
    else
      return error;
  }
David Turner's avatar
David Turner committed
786

Werner Lemberg's avatar
   
Werner Lemberg committed
787

David Turner's avatar
David Turner committed
788
789
790
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
Werner Lemberg's avatar
   
Werner Lemberg committed
791
  /*    TT_Driver_Init                                                     */
David Turner's avatar
David Turner committed
792
793
794
795
796
797
798
799
  /*                                                                       */
  /* <Description>                                                         */
  /*    Initializes a given TrueType driver object.                        */
  /*                                                                       */
  /* <Input>                                                               */
  /*    driver :: A handle to the target driver object.                    */
  /*                                                                       */
  /* <Return>                                                              */
Werner Lemberg's avatar
   
Werner Lemberg committed
800
  /*    FreeType error code.  0 means success.                             */
David Turner's avatar
David Turner committed
801
  /*                                                                       */
802
  FT_LOCAL_DEF( FT_Error )
Werner Lemberg's avatar
   
Werner Lemberg committed
803
  TT_Driver_Init( TT_Driver  driver )
David Turner's avatar
David Turner committed
804
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
805
    FT_Error  error;
Werner Lemberg's avatar
   
Werner Lemberg committed
806

Werner Lemberg's avatar
   
Werner Lemberg committed
807
808

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

David Turner's avatar
David Turner committed
811
    return error;
David Turner's avatar
David Turner committed
812
813
814
815
816
817
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
Werner Lemberg's avatar
   
Werner Lemberg committed
818
  /*    TT_Driver_Done                                                     */
David Turner's avatar
David Turner committed
819
820
821
822
823
824
825
  /*                                                                       */
  /* <Description>                                                         */
  /*    Finalizes a given TrueType driver.                                 */
  /*                                                                       */
  /* <Input>                                                               */
  /*    driver :: A handle to the target TrueType driver.                  */
  /*                                                                       */
826
  FT_LOCAL_DEF( void )
Werner Lemberg's avatar
   
Werner Lemberg committed
827
  TT_Driver_Done( TT_Driver  driver )
David Turner's avatar
David Turner committed
828
  {
829
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg's avatar
   
Werner Lemberg committed
830

David Turner's avatar
David Turner committed
831
832
833
    /* destroy the execution context */
    if ( driver->context )
    {
David Turner's avatar
David Turner committed
834
      TT_Destroy_Context( driver->context, driver->root.root.memory );
David Turner's avatar
David Turner committed
835
836
      driver->context = NULL;
    }
837
#else
Werner Lemberg's avatar
   
Werner Lemberg committed
838
    FT_UNUSED( driver );
839
#endif
Werner Lemberg's avatar
   
Werner Lemberg committed
840

David Turner's avatar
David Turner committed
841
842
843
844
  }


/* END */