ttobjs.c 30.2 KB
Newer Older
David Turner's avatar
David Turner committed
1
2
3
4
5
6
/***************************************************************************/
/*                                                                         */
/*  ttobjs.c                                                               */
/*                                                                         */
/*    Objects manager (body).                                              */
/*                                                                         */
Werner Lemberg's avatar
   
Werner Lemberg committed
7
/*  Copyright 1996-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
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
60
  /*    tt_glyphzone_done                                                  */
61
62
63
64
65
66
67
  /*                                                                       */
  /* <Description>                                                         */
  /*    Deallocates a glyph zone.                                          */
  /*                                                                       */
  /* <Input>                                                               */
  /*    zone :: A pointer to the target glyph zone.                        */
  /*                                                                       */
68
  FT_LOCAL_DEF( void )
69
  tt_glyphzone_done( 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

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


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
87
  /*    tt_glyphzone_new                                                   */
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
  /*                                                                       */
  /* <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 )
106
  tt_glyphzone_new( FT_Memory     memory,
Werner Lemberg's avatar
   
Werner Lemberg committed
107
108
109
                    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;

Werner Lemberg's avatar
   
Werner Lemberg committed
117
    FT_MEM_ZERO( zone, 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
      tt_glyphzone_done( zone );
126
127
128
129
    }

    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>                                                            */
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 )
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
    if ( face->root.face_flags & FT_FACE_FLAG_SCALABLE )
200
      {
Werner Lemberg's avatar
   
Werner Lemberg committed
201

202
#ifdef FT_CONFIG_OPTION_INCREMENTAL
Werner Lemberg's avatar
   
Werner Lemberg committed
203

204
        if ( !face->root.internal->incremental_interface )
205
          error = tt_face_load_loca( face, stream );
206
        if ( !error )
207
208
          error = tt_face_load_cvt      ( face, stream ) ||
                  tt_face_load_fpgm ( face, stream );
Werner Lemberg's avatar
   
Werner Lemberg committed
209

210
#else
Werner Lemberg's avatar
   
Werner Lemberg committed
211

212
        if ( !error )
213
214
215
          error = tt_face_load_loca( face, stream ) ||
                  tt_face_load_cvt      ( face, stream ) ||
                  tt_face_load_fpgm ( face, stream );
Werner Lemberg's avatar
   
Werner Lemberg committed
216

217
#endif
Werner Lemberg's avatar
   
Werner Lemberg committed
218

219
      }
Werner Lemberg's avatar
   
Werner Lemberg committed
220

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

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

227
  Bad_Format:
Werner Lemberg's avatar
Werner Lemberg committed
228
    error = TT_Err_Unknown_File_Format;
229
    goto Exit;
David Turner's avatar
David Turner committed
230
231
232
233
234
235
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
236
  /*    tt_face_done                                                       */
David Turner's avatar
David Turner committed
237
238
239
240
241
242
243
  /*                                                                       */
  /* <Description>                                                         */
  /*    Finalizes a given face object.                                     */
  /*                                                                       */
  /* <Input>                                                               */
  /*    face :: A pointer to the face object to destroy.                   */
  /*                                                                       */
244
  FT_LOCAL_DEF( void )
245
  tt_face_done( TT_Face  face )
David Turner's avatar
David Turner committed
246
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
247
248
    FT_Memory     memory = face->root.memory;
    FT_Stream     stream = face->root.stream;
David Turner's avatar
David Turner committed
249

Werner Lemberg's avatar
   
Werner Lemberg committed
250
    SFNT_Service  sfnt   = (SFNT_Service)face->sfnt;
251

Werner Lemberg's avatar
   
Werner Lemberg committed
252

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

    if ( sfnt )
      sfnt->done_face( face );
David Turner's avatar
David Turner committed
259
260

    /* freeing the locations table */
261
    FT_FREE( face->glyph_locations );
David Turner's avatar
David Turner committed
262
263
264
    face->num_locations = 0;

    /* freeing the CVT */
265
    FT_FREE( face->cvt );
David Turner's avatar
David Turner committed
266
267
268
    face->cvt_size = 0;

    /* freeing the programs */
269
270
    FT_FRAME_RELEASE( face->font_program );
    FT_FRAME_RELEASE( face->cvt_program );
David Turner's avatar
David Turner committed
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
    face->font_program_size = 0;
    face->cvt_program_size  = 0;
  }


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


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
286
  /*    tt_size_init                                                       */
David Turner's avatar
David Turner committed
287
288
289
290
291
292
293
294
  /*                                                                       */
  /* <Description>                                                         */
  /*    Initializes a new TrueType size object.                            */
  /*                                                                       */
  /* <InOut>                                                               */
  /*    size :: A handle to the size object.                               */
  /*                                                                       */
  /* <Return>                                                              */
Werner Lemberg's avatar
   
Werner Lemberg committed
295
  /*    FreeType error code.  0 means success.                             */
David Turner's avatar
David Turner committed
296
  /*                                                                       */
297
  FT_LOCAL_DEF( FT_Error )
298
  tt_size_init( TT_Size  size )
David Turner's avatar
David Turner committed
299
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
300
301
    FT_Error  error = TT_Err_Ok;

302

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

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

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

Werner Lemberg's avatar
   
Werner Lemberg committed
313

David Turner's avatar
David Turner committed
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
    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
333

David Turner's avatar
David Turner committed
334
335
336
337
338
339
340
341
342
343
344
      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
345
    /* allocate function defs, instruction defs, cvt, and storage area */
Werner Lemberg's avatar
   
Werner Lemberg committed
346
    if ( FT_NEW_ARRAY( size->function_defs,    size->max_function_defs    ) ||
347
         FT_NEW_ARRAY( size->instruction_defs, size->max_instruction_defs ) ||
Werner Lemberg's avatar
   
Werner Lemberg committed
348
349
         FT_NEW_ARRAY( size->cvt,              size->cvt_size             ) ||
         FT_NEW_ARRAY( size->storage,          size->storage_size         ) )
David Turner's avatar
David Turner committed
350
351
352
353
354

      goto Fail_Memory;

    /* reserve twilight zone */
    n_twilight = maxp->maxTwilightPoints;
355
    error = tt_glyphzone_new( memory, n_twilight, 0, &size->twilight );
David Turner's avatar
David Turner committed
356
357
358
359
360
361
362
    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
363
      FT_Library  library = face->root.driver->root.library;
364

Werner Lemberg's avatar
   
Werner Lemberg committed
365

David Turner's avatar
David Turner committed
366
      face->interpreter = (TT_Interpreter)
Werner Lemberg's avatar
   
Werner Lemberg committed
367
368
                            library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE];
      if ( !face->interpreter )
David Turner's avatar
David Turner committed
369
370
371
372
373
374
        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
375
376
    if ( !size->debug )
      exec = TT_New_Context( face );
David Turner's avatar
David Turner committed
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398

    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
399
400
401
402
      metrics->x_ppem   = 0;
      metrics->y_ppem   = 0;
      metrics->x_scale  = 0;
      metrics->y_scale  = 0;
David Turner's avatar
David Turner committed
403

Werner Lemberg's avatar
   
Werner Lemberg committed
404
405
406
      tt_metrics->ppem  = 0;
      tt_metrics->scale = 0;
      tt_metrics->ratio = 0x10000L;
David Turner's avatar
David Turner committed
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
435
436
437
438
439
440
441
442
    }

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

443
444
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */

David Turner's avatar
David Turner committed
445
446
447
    size->ttmetrics.valid = FALSE;
    return error;

448
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg's avatar
   
Werner Lemberg committed
449

David Turner's avatar
David Turner committed
450
451
452
453
454
  Fail_Exec:
    if ( !size->debug )
      TT_Done_Context( exec );

  Fail_Memory:
Werner Lemberg's avatar
   
Werner Lemberg committed
455

456
    tt_size_done( size );
David Turner's avatar
David Turner committed
457
    return error;
Werner Lemberg's avatar
   
Werner Lemberg committed
458
459
460

#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */

David Turner's avatar
David Turner committed
461
462
463
464
465
466
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
467
  /*    tt_size_done                                                       */
David Turner's avatar
David Turner committed
468
469
470
471
472
473
474
  /*                                                                       */
  /* <Description>                                                         */
  /*    The TrueType size object finalizer.                                */
  /*                                                                       */
  /* <Input>                                                               */
  /*    size :: A handle to the target size object.                        */
  /*                                                                       */
475
  FT_LOCAL_DEF( void )
476
  tt_size_done( TT_Size  size )
David Turner's avatar
David Turner committed
477
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
478

479
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg's avatar
   
Werner Lemberg committed
480

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

Werner Lemberg's avatar
   
Werner Lemberg committed
483

David Turner's avatar
David Turner committed
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;
    }

491
    FT_FREE( size->cvt );
David Turner's avatar
David Turner committed
492
493
494
    size->cvt_size = 0;

    /* free storage area */
495
    FT_FREE( size->storage );
David Turner's avatar
David Turner committed
496
497
498
    size->storage_size = 0;

    /* twilight zone */
499
    tt_glyphzone_done( &size->twilight );
David Turner's avatar
David Turner committed
500

501
502
    FT_FREE( size->function_defs );
    FT_FREE( size->instruction_defs );
Werner Lemberg's avatar
   
Werner Lemberg committed
503

David Turner's avatar
David Turner committed
504
505
506
507
508
509
510
    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
511

512
#endif
David Turner's avatar
David Turner committed
513
514
515
516
517
518
519
520

    size->ttmetrics.valid = FALSE;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
Werner Lemberg's avatar
   
Werner Lemberg committed
521
  /*    Reset_Outline_Size                                                 */
David Turner's avatar
David Turner committed
522
523
  /*                                                                       */
  /* <Description>                                                         */
Werner Lemberg's avatar
   
Werner Lemberg committed
524
525
  /*    Resets a TrueType outline size when resolutions and character      */
  /*    dimensions have been changed.                                      */
David Turner's avatar
David Turner committed
526
527
528
529
  /*                                                                       */
  /* <Input>                                                               */
  /*    size :: A handle to the target size object.                        */
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
530
531
  static FT_Error
  Reset_Outline_Size( TT_Size  size )
David Turner's avatar
David Turner committed
532
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
533
534
    TT_Face           face;
    FT_Error          error = TT_Err_Ok;
David Turner's avatar
David Turner committed
535
536
537

    FT_Size_Metrics*  metrics;

Werner Lemberg's avatar
   
Werner Lemberg committed
538

David Turner's avatar
David Turner committed
539
540
541
542
543
    if ( size->ttmetrics.valid )
      return TT_Err_Ok;

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

544
    metrics = &size->metrics;
David Turner's avatar
David Turner committed
545
546
547
548
549
550
551
552
553

    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
554
      size->ttmetrics.x_ratio = 0x10000L;
David Turner's avatar
David Turner committed
555
556
557
558
559
560
561
562
563
564
565
      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
566
      size->ttmetrics.y_ratio = 0x10000L;
David Turner's avatar
David Turner committed
567
568
569
    }

    /* Compute root ascender, descender, test height, and max_advance */
Werner Lemberg's avatar
   
Werner Lemberg committed
570
571
572
573
574
575
576
577
    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
578

579

580
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
Werner Lemberg's avatar
   
Werner Lemberg committed
581
    /* set to `invalid' by default */
Werner Lemberg's avatar
   
Werner Lemberg committed
582
    size->strike_index = 0xFFFFU;
583
584
#endif

585
586
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER

David Turner's avatar
David Turner committed
587
    {
Werner Lemberg's avatar
   
Werner Lemberg committed
588
589
      TT_ExecContext  exec;
      FT_UInt         i, j;
590

Werner Lemberg's avatar
   
Werner Lemberg committed
591

592
593
594
595
      /* 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 );
596

597
      /* All twilight points are originally zero */
598
      for ( j = 0; j < (FT_UInt)size->twilight.n_points; j++ )
599
600
601
602
603
604
      {
        size->twilight.org[j].x = 0;
        size->twilight.org[j].y = 0;
        size->twilight.cur[j].x = 0;
        size->twilight.cur[j].y = 0;
      }
605

606
      /* clear storage area */
607
      for ( i = 0; i < (FT_UInt)size->storage_size; i++ )
608
        size->storage[i] = 0;
609

610
      size->GS = tt_default_graphics_state;
611

612
613
614
615
616
617
      /* 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 */
618

619
620
      if ( !exec )
        return TT_Err_Could_Not_Find_Context;
621

622
      TT_Load_Context( exec, face, size );
623

624
625
626
627
      TT_Set_CodeRange( exec,
                        tt_coderange_cvt,
                        face->cvt_program,
                        face->cvt_program_size );
628

629
      TT_Clear_CodeRange( exec, tt_coderange_glyph );
630

631
      exec->instruction_trap = FALSE;
632

633
634
      exec->top     = 0;
      exec->callTop = 0;
635

636
637
638
639
      if ( face->cvt_program_size > 0 )
      {
        error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
        if ( error )
Werner Lemberg's avatar
   
Werner Lemberg committed
640
          goto End;
641

642
643
644
645
646
        if ( !size->debug )
          error = face->interpreter( exec );
      }
      else
        error = TT_Err_Ok;
647

648
649
      size->GS = exec->GS;
      /* save default graphics state */
650

Werner Lemberg's avatar
   
Werner Lemberg committed
651
    End:
652
      TT_Save_Context( exec, size );
653

David Turner's avatar
David Turner committed
654
      if ( !size->debug )
655
656
        TT_Done_Context( exec );
      /* debugging instances keep their context */
David Turner's avatar
David Turner committed
657
    }
Werner Lemberg's avatar
   
Werner Lemberg committed
658

659
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
David Turner's avatar
David Turner committed
660
661
662
663
664
665
666

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

    return error;
  }

Werner Lemberg's avatar
   
Werner Lemberg committed
667

668
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
Werner Lemberg's avatar
   
Werner Lemberg committed
669
670
671
672
673
674
675
676
677
678
679
680
681

  /*************************************************************************/
  /*                                                                       */
  /* <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
682
683
  static FT_Error
  Reset_SBit_Size( TT_Size  size )
684
685
686
687
688
689
690
  {
    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
691
    SFNT_Service      sfnt;
692

Werner Lemberg's avatar
   
Werner Lemberg committed
693

694
    metrics = &size->metrics;
695

Werner Lemberg's avatar
   
Werner Lemberg committed
696
    if ( size->strike_index != 0xFFFFU )
697
698
699
      return TT_Err_Ok;

    face = (TT_Face)size->root.face;
700
    sfnt = (SFNT_Service)face->sfnt;
701
702
703
704

    sbit_metrics = &size->strike_metrics;

    error = sfnt->set_sbit_strike(face,
Werner Lemberg's avatar
   
Werner Lemberg committed
705
706
                                  metrics->x_ppem, metrics->y_ppem,
                                  &strike_index);
707

Werner Lemberg's avatar
   
Werner Lemberg committed
708
    if ( !error )
709
    {
Werner Lemberg's avatar
   
Werner Lemberg committed
710
      TT_SBit_Strike  strike = face->sbit_strikes + strike_index;
Werner Lemberg's avatar
   
Werner Lemberg committed
711
712


Werner Lemberg's avatar
   
Werner Lemberg committed
713
714
      sbit_metrics->x_ppem      = metrics->x_ppem;
      sbit_metrics->y_ppem      = metrics->y_ppem;
715
716
717
718
719
#if 0
      /*
       * sbit_metrics->?_scale
       * are not used now.
       */
Werner Lemberg's avatar
   
Werner Lemberg committed
720
721
      sbit_metrics->x_scale     = 1 << 16;
      sbit_metrics->y_scale     = 1 << 16;
722
#endif
Werner Lemberg's avatar
   
Werner Lemberg committed
723

724
      sbit_metrics->ascender    = strike->hori.ascender  << 6;
Werner Lemberg's avatar
   
Werner Lemberg committed
725
      sbit_metrics->descender   = strike->hori.descender << 6;
Werner Lemberg's avatar
   
Werner Lemberg committed
726

727
      /* XXX: Is this correct? */
Werner Lemberg's avatar
   
Werner Lemberg committed
728
729
      sbit_metrics->height      = sbit_metrics->ascender -
                                  sbit_metrics->descender;
Werner Lemberg's avatar
   
Werner Lemberg committed
730

731
      /* XXX: Is this correct? */
732
733
      sbit_metrics->max_advance = ( strike->hori.min_origin_SB  +
                                    strike->hori.max_width      +
734
735
736
737
738
739
                                    strike->hori.min_advance_SB ) << 6;

      size->strike_index = strike_index;
    }
    else
    {
Werner Lemberg's avatar
   
Werner Lemberg committed
740
      size->strike_index = 0xFFFFU;
Werner Lemberg's avatar
   
Werner Lemberg committed
741

742
743
744
745
746
747
748
749
750
751
      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
752

753
754
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */

Werner Lemberg's avatar
   
Werner Lemberg committed
755

756
757
758
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
759
  /*    tt_size_reset                                                      */
760
761
762
763
764
765
766
767
  /*                                                                       */
  /* <Description>                                                         */
  /*    Resets a TrueType size when resolutions and character dimensions   */
  /*    have been changed.                                                 */
  /*                                                                       */
  /* <Input>                                                               */
  /*    size :: A handle to the target size object.                        */
  /*                                                                       */
768
  FT_LOCAL_DEF( FT_Error )
769
  tt_size_reset( TT_Size  size )
770
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
771
    FT_Face   face;
772
773
    FT_Error  error = TT_Err_Ok;

Werner Lemberg's avatar
   
Werner Lemberg committed
774

775
776
777
778
779
    face = size->root.face;

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

      if ( error )
Werner Lemberg's avatar
   
Werner Lemberg committed
783
        return error;
784
785
786
    }

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

788
789
    if ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES )
    {
Werner Lemberg's avatar
   
Werner Lemberg committed
790
      if ( size->strike_index == 0xFFFFU )
791
792
        error = Reset_SBit_Size( size );

Werner Lemberg's avatar
   
Werner Lemberg committed
793
      if ( !error && !( face->face_flags & FT_FACE_FLAG_SCALABLE ) )
794
        size->root.metrics = size->strike_metrics;
795
    }
Werner Lemberg's avatar
   
Werner Lemberg committed
796
797
798
799

#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */

    if ( face->face_flags & FT_FACE_FLAG_SCALABLE )
800
801
802
803
      return TT_Err_Ok;
    else
      return error;
  }
David Turner's avatar
David Turner committed
804

Werner Lemberg's avatar
   
Werner Lemberg committed
805

David Turner's avatar
David Turner committed
806
807
808
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
809
  /*    tt_driver_init                                                     */
David Turner's avatar
David Turner committed
810
811
812
813
814
815
816
817
  /*                                                                       */
  /* <Description>                                                         */
  /*    Initializes a given TrueType driver object.                        */
  /*                                                                       */
  /* <Input>                                                               */
  /*    driver :: A handle to the target driver object.                    */
  /*                                                                       */
  /* <Return>                                                              */
Werner Lemberg's avatar
   
Werner Lemberg committed
818
  /*    FreeType error code.  0 means success.                             */
David Turner's avatar
David Turner committed
819
  /*                                                                       */
820
  FT_LOCAL_DEF( FT_Error )
821
  tt_driver_init( TT_Driver  driver )
David Turner's avatar
David Turner committed
822
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
823
    FT_Error  error;
Werner Lemberg's avatar
   
Werner Lemberg committed
824

Werner Lemberg's avatar
   
Werner Lemberg committed
825
826

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

David Turner's avatar
David Turner committed
829
    return error;
David Turner's avatar
David Turner committed
830
831
832
833
834
835
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
836
  /*    tt_driver_done                                                     */
David Turner's avatar
David Turner committed
837
838
839
840
841
842
843
  /*                                                                       */
  /* <Description>                                                         */
  /*    Finalizes a given TrueType driver.                                 */
  /*                                                                       */
  /* <Input>                                                               */
  /*    driver :: A handle to the target TrueType driver.                  */
  /*                                                                       */
844
  FT_LOCAL_DEF( void )
845
  tt_driver_done( TT_Driver  driver )
David Turner's avatar
David Turner committed
846
  {
847
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
Werner Lemberg's avatar
   
Werner Lemberg committed
848

David Turner's avatar
David Turner committed
849
850
851
    /* destroy the execution context */
    if ( driver->context )
    {
David Turner's avatar
David Turner committed
852
      TT_Destroy_Context( driver->context, driver->root.root.memory );
David Turner's avatar
David Turner committed
853
854
      driver->context = NULL;
    }
855
#else
Werner Lemberg's avatar
   
Werner Lemberg committed
856
    FT_UNUSED( driver );
857
#endif
Werner Lemberg's avatar
   
Werner Lemberg committed
858

David Turner's avatar
David Turner committed
859
860
861
862
  }


/* END */