ttobjs.c 30.8 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;

Werner Lemberg's avatar
   
Werner Lemberg committed
456
457
#if defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER ) || \
    defined( TT_CONFIG_OPTION_EMBEDDED_BITMAPS )
Werner Lemberg's avatar
   
Werner Lemberg committed
458

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

  Fail_Memory:
Werner Lemberg's avatar
   
Werner Lemberg committed
464

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

#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */

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


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

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

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

Werner Lemberg's avatar
   
Werner Lemberg committed
492

David Turner's avatar
David Turner committed
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
    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 */
508
    TT_Done_GlyphZone( &size->twilight );
David Turner's avatar
David Turner committed
509
510
511

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

David Turner's avatar
David Turner committed
513
514
515
516
517
518
519
    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
520

521
#endif
David Turner's avatar
David Turner committed
522
523
524
525
526
527
528
529

    size->ttmetrics.valid = FALSE;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
Werner Lemberg's avatar
   
Werner Lemberg committed
530
  /*    Reset_Outline_Size                                                 */
David Turner's avatar
David Turner committed
531
532
  /*                                                                       */
  /* <Description>                                                         */
Werner Lemberg's avatar
   
Werner Lemberg committed
533
534
  /*    Resets a TrueType outline size when resolutions and character      */
  /*    dimensions have been changed.                                      */
David Turner's avatar
David Turner committed
535
536
537
538
  /*                                                                       */
  /* <Input>                                                               */
  /*    size :: A handle to the target size object.                        */
  /*                                                                       */
539
540
  static
  FT_Error  Reset_Outline_Size( TT_Size  size )
David Turner's avatar
David Turner committed
541
  {
542
    TT_Face   face;
543
    FT_Error  error = TT_Err_Ok;
David Turner's avatar
David Turner committed
544
545
546

    FT_Size_Metrics*  metrics;

Werner Lemberg's avatar
   
Werner Lemberg committed
547

David Turner's avatar
David Turner committed
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
    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
563
      size->ttmetrics.x_ratio = 0x10000L;
David Turner's avatar
David Turner committed
564
565
566
567
568
569
570
571
572
573
574
      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
575
      size->ttmetrics.y_ratio = 0x10000L;
David Turner's avatar
David Turner committed
576
577
578
    }

    /* Compute root ascender, descender, test height, and max_advance */
Werner Lemberg's avatar
   
Werner Lemberg committed
579
580
581
582
583
584
585
586
    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
587

588
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg's avatar
   
Werner Lemberg committed
589

590
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
Werner Lemberg's avatar
   
Werner Lemberg committed
591
    /* set to `invalid' by default */
592
593
594
    size->strike_index = 0xFFFF;
#endif

David Turner's avatar
David Turner committed
595
    {
Werner Lemberg's avatar
   
Werner Lemberg committed
596
597
      TT_ExecContext  exec;
      FT_UInt         i, j;
598

Werner Lemberg's avatar
   
Werner Lemberg committed
599

600
601
602
603
      /* 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 );
604

605
606
607
608
609
610
611
612
      /* 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;
      }
613

614
615
616
      /* clear storage area */
      for ( i = 0; i < size->storage_size; i++ )
        size->storage[i] = 0;
617

618
      size->GS = tt_default_graphics_state;
619

620
621
622
623
624
625
      /* 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 */
626

627
628
      if ( !exec )
        return TT_Err_Could_Not_Find_Context;
629

630
      TT_Load_Context( exec, face, size );
631

632
633
634
635
      TT_Set_CodeRange( exec,
                        tt_coderange_cvt,
                        face->cvt_program,
                        face->cvt_program_size );
636

637
      TT_Clear_CodeRange( exec, tt_coderange_glyph );
638

639
      exec->instruction_trap = FALSE;
640

641
642
      exec->top     = 0;
      exec->callTop = 0;
643

644
645
646
647
      if ( face->cvt_program_size > 0 )
      {
        error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
        if ( error )
Werner Lemberg's avatar
   
Werner Lemberg committed
648
          goto End;
649

650
651
652
653
654
        if ( !size->debug )
          error = face->interpreter( exec );
      }
      else
        error = TT_Err_Ok;
655

656
657
      size->GS = exec->GS;
      /* save default graphics state */
658

Werner Lemberg's avatar
   
Werner Lemberg committed
659
    End:
660
      TT_Save_Context( exec, size );
661

David Turner's avatar
David Turner committed
662
      if ( !size->debug )
663
664
        TT_Done_Context( exec );
      /* debugging instances keep their context */
David Turner's avatar
David Turner committed
665
    }
Werner Lemberg's avatar
   
Werner Lemberg committed
666

667
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
David Turner's avatar
David Turner committed
668
669
670
671
672
673
674

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

    return error;
  }

Werner Lemberg's avatar
   
Werner Lemberg committed
675

676
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
Werner Lemberg's avatar
   
Werner Lemberg committed
677
678
679
680
681
682
683
684
685
686
687
688
689

  /*************************************************************************/
  /*                                                                       */
  /* <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.                        */
  /*                                                                       */
690
691
692
693
694
695
696
697
698
699
700
  static
  FT_Error  Reset_SBit_Size( TT_Size size )
  {
    TT_Face           face;
    FT_Error          error = TT_Err_Ok;

    FT_ULong          strike_index;
    FT_Size_Metrics*  metrics;
    FT_Size_Metrics*  sbit_metrics;
    SFNT_Interface*   sfnt;

Werner Lemberg's avatar
   
Werner Lemberg committed
701

702
703
    metrics = &size->root.metrics;

Werner Lemberg's avatar
   
Werner Lemberg committed
704
    if ( size->strike_index != 0xFFFF )
705
706
707
708
709
710
711
712
      return TT_Err_Ok;

    face = (TT_Face)size->root.face;
    sfnt = (SFNT_Interface*)face->sfnt;

    sbit_metrics = &size->strike_metrics;

    error = sfnt->set_sbit_strike(face,
Werner Lemberg's avatar
   
Werner Lemberg committed
713
714
                                  metrics->x_ppem, metrics->y_ppem,
                                  &strike_index);
715

Werner Lemberg's avatar
   
Werner Lemberg committed
716
    if ( !error )
717
718
719
720
    {
      TT_SBit_Strike*  strike = face->sbit_strikes + strike_index;
      
      
Werner Lemberg's avatar
   
Werner Lemberg committed
721
722
      sbit_metrics->x_ppem      = metrics->x_ppem;
      sbit_metrics->y_ppem      = metrics->y_ppem;
723
724
725
726
727
#if 0
      /*
       * sbit_metrics->?_scale
       * are not used now.
       */
Werner Lemberg's avatar
   
Werner Lemberg committed
728
729
      sbit_metrics->x_scale     = 1 << 16;
      sbit_metrics->y_scale     = 1 << 16;
730
731
#endif
      
Werner Lemberg's avatar
   
Werner Lemberg committed
732
733
      sbit_metrics->ascender    = strike->hori.ascender << 6;
      sbit_metrics->descender   = strike->hori.descender << 6;
734
735
      
      /* XXX: Is this correct? */
Werner Lemberg's avatar
   
Werner Lemberg committed
736
737
      sbit_metrics->height      = sbit_metrics->ascender -
                                  sbit_metrics->descender;
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
      
      /* 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;
      
      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
760

761
762
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */

Werner Lemberg's avatar
   
Werner Lemberg committed
763

764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
  /*************************************************************************/
  /*                                                                       */
  /* <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.                        */
  /*                                                                       */
  FT_LOCAL_DEF
  FT_Error  TT_Reset_Size( TT_Size  size )
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
779
    FT_Face   face;
780
781
    FT_Error  error = TT_Err_Ok;

Werner Lemberg's avatar
   
Werner Lemberg committed
782

783
784
785
786
787
    face = size->root.face;

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

      if ( error )
Werner Lemberg's avatar
   
Werner Lemberg committed
791
        return error;
792
793
794
    }

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

796
797
798
799
    if ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES )
    {
      FT_Size_Metrics* sbit_metrics;

Werner Lemberg's avatar
   
Werner Lemberg committed
800

801
802
803
804
805
      if ( size->strike_index == 0xFFFF )
        error = Reset_SBit_Size( size );

      sbit_metrics = &size->strike_metrics;

Werner Lemberg's avatar
   
Werner Lemberg committed
806
807
      if ( !error && !( face->face_flags & FT_FACE_FLAG_SCALABLE ) )
        size->root.metrics = *sbit_metrics;
808
    }
Werner Lemberg's avatar
   
Werner Lemberg committed
809
810
811
812

#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */

    if ( face->face_flags & FT_FACE_FLAG_SCALABLE )
813
814
815
816
      return TT_Err_Ok;
    else
      return error;
  }
David Turner's avatar
David Turner committed
817

Werner Lemberg's avatar
   
Werner Lemberg committed
818

David Turner's avatar
David Turner committed
819
820
821
822
823
824
825
826
827
828
829
830
  /*************************************************************************/
  /*                                                                       */
  /* <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
831
  /*    FreeType error code.  0 means success.                             */
David Turner's avatar
David Turner committed
832
  /*                                                                       */
833
  FT_LOCAL_DEF
834
  FT_Error  TT_Init_Driver( TT_Driver  driver )
David Turner's avatar
David Turner committed
835
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
836
    FT_Error  error;
Werner Lemberg's avatar
   
Werner Lemberg committed
837

Werner Lemberg's avatar
   
Werner Lemberg committed
838
839
840

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

David Turner's avatar
David Turner committed
842
    /* init extension registry if needed */
Werner Lemberg's avatar
   
Werner Lemberg committed
843

David Turner's avatar
David Turner committed
844
#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
Werner Lemberg's avatar
   
Werner Lemberg committed
845
    if ( !error )
David Turner's avatar
David Turner committed
846
      return TT_Init_Extensions( driver );
David Turner's avatar
David Turner committed
847
#endif
David Turner's avatar
David Turner committed
848
849

    return error;
David Turner's avatar
David Turner committed
850
851
852
853
854
855
856
857
858
859
860
861
862
863
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    TT_Done_Driver                                                     */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Finalizes a given TrueType driver.                                 */
  /*                                                                       */
  /* <Input>                                                               */
  /*    driver :: A handle to the target TrueType driver.                  */
  /*                                                                       */
864
  FT_LOCAL_DEF
David Turner's avatar
David Turner committed
865
866
867
  void  TT_Done_Driver( TT_Driver  driver )
  {
    /* destroy extensions registry if needed */
Werner Lemberg's avatar
   
Werner Lemberg committed
868

David Turner's avatar
David Turner committed
869
#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
Werner Lemberg's avatar
   
Werner Lemberg committed
870

David Turner's avatar
David Turner committed
871
    TT_Done_Extensions( driver );
Werner Lemberg's avatar
   
Werner Lemberg committed
872

David Turner's avatar
David Turner committed
873
874
#endif

875
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg's avatar
   
Werner Lemberg committed
876

David Turner's avatar
David Turner committed
877
878
879
    /* destroy the execution context */
    if ( driver->context )
    {
David Turner's avatar
David Turner committed
880
      TT_Destroy_Context( driver->context, driver->root.root.memory );
David Turner's avatar
David Turner committed
881
882
      driver->context = NULL;
    }
883
#else
Werner Lemberg's avatar
   
Werner Lemberg committed
884
    FT_UNUSED( driver );
885
#endif
Werner Lemberg's avatar
   
Werner Lemberg committed
886

David Turner's avatar
David Turner committed
887
888
889
890
  }


/* END */