~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/freetype/src/cff/cffobjs.c

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************/
 
2
/*                                                                         */
 
3
/*  cffobjs.c                                                              */
 
4
/*                                                                         */
 
5
/*    OpenType objects manager (body).                                     */
 
6
/*                                                                         */
 
7
/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */
 
8
/*            2010 by                                                      */
 
9
/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 
10
/*                                                                         */
 
11
/*  This file is part of the FreeType project, and may only be used,       */
 
12
/*  modified, and distributed under the terms of the FreeType project      */
 
13
/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
 
14
/*  this file you indicate that you have read the license and              */
 
15
/*  understand and accept it fully.                                        */
 
16
/*                                                                         */
 
17
/***************************************************************************/
 
18
 
 
19
 
 
20
#include <ft2build.h>
 
21
#include FT_INTERNAL_DEBUG_H
 
22
#include FT_INTERNAL_CALC_H
 
23
#include FT_INTERNAL_STREAM_H
 
24
#include FT_ERRORS_H
 
25
#include FT_TRUETYPE_IDS_H
 
26
#include FT_TRUETYPE_TAGS_H
 
27
#include FT_INTERNAL_SFNT_H
 
28
#include "cffobjs.h"
 
29
#include "cffload.h"
 
30
#include "cffcmap.h"
 
31
#include "cfferrs.h"
 
32
#include "cffpic.h"
 
33
 
 
34
 
 
35
  /*************************************************************************/
 
36
  /*                                                                       */
 
37
  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
 
38
  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
 
39
  /* messages during execution.                                            */
 
40
  /*                                                                       */
 
41
#undef  FT_COMPONENT
 
42
#define FT_COMPONENT  trace_cffobjs
 
43
 
 
44
 
 
45
  /*************************************************************************/
 
46
  /*                                                                       */
 
47
  /*                            SIZE FUNCTIONS                             */
 
48
  /*                                                                       */
 
49
  /*  Note that we store the global hints in the size's `internal' root    */
 
50
  /*  field.                                                               */
 
51
  /*                                                                       */
 
52
  /*************************************************************************/
 
53
 
 
54
 
 
55
  static PSH_Globals_Funcs
 
56
  cff_size_get_globals_funcs( CFF_Size  size )
 
57
  {
 
58
    CFF_Face          face     = (CFF_Face)size->root.face;
 
59
    CFF_Font          font     = (CFF_Font)face->extra.data;
 
60
    PSHinter_Service  pshinter = font->pshinter;
 
61
    FT_Module         module;
 
62
 
 
63
 
 
64
    module = FT_Get_Module( size->root.face->driver->root.library,
 
65
                            "pshinter" );
 
66
    return ( module && pshinter && pshinter->get_globals_funcs )
 
67
           ? pshinter->get_globals_funcs( module )
 
68
           : 0;
 
69
  }
 
70
 
 
71
 
 
72
  FT_LOCAL_DEF( void )
 
73
  cff_size_done( FT_Size  cffsize )        /* CFF_Size */
 
74
  {
 
75
    CFF_Size      size     = (CFF_Size)cffsize;
 
76
    CFF_Face      face     = (CFF_Face)size->root.face;
 
77
    CFF_Font      font     = (CFF_Font)face->extra.data;
 
78
    CFF_Internal  internal = (CFF_Internal)cffsize->internal;
 
79
 
 
80
 
 
81
    if ( internal )
 
82
    {
 
83
      PSH_Globals_Funcs  funcs;
 
84
 
 
85
 
 
86
      funcs = cff_size_get_globals_funcs( size );
 
87
      if ( funcs )
 
88
      {
 
89
        FT_UInt  i;
 
90
 
 
91
 
 
92
        funcs->destroy( internal->topfont );
 
93
 
 
94
        for ( i = font->num_subfonts; i > 0; i-- )
 
95
          funcs->destroy( internal->subfonts[i - 1] );
 
96
      }
 
97
 
 
98
      /* `internal' is freed by destroy_size (in ftobjs.c) */
 
99
    }
 
100
  }
 
101
 
 
102
 
 
103
  /* CFF and Type 1 private dictionaries have slightly different      */
 
104
  /* structures; we need to synthesize a Type 1 dictionary on the fly */
 
105
 
 
106
  static void
 
107
  cff_make_private_dict( CFF_SubFont  subfont,
 
108
                         PS_Private   priv )
 
109
  {
 
110
    CFF_Private  cpriv = &subfont->private_dict;
 
111
    FT_UInt      n, count;
 
112
 
 
113
 
 
114
    FT_MEM_ZERO( priv, sizeof ( *priv ) );
 
115
 
 
116
    count = priv->num_blue_values = cpriv->num_blue_values;
 
117
    for ( n = 0; n < count; n++ )
 
118
      priv->blue_values[n] = (FT_Short)cpriv->blue_values[n];
 
119
 
 
120
    count = priv->num_other_blues = cpriv->num_other_blues;
 
121
    for ( n = 0; n < count; n++ )
 
122
      priv->other_blues[n] = (FT_Short)cpriv->other_blues[n];
 
123
 
 
124
    count = priv->num_family_blues = cpriv->num_family_blues;
 
125
    for ( n = 0; n < count; n++ )
 
126
      priv->family_blues[n] = (FT_Short)cpriv->family_blues[n];
 
127
 
 
128
    count = priv->num_family_other_blues = cpriv->num_family_other_blues;
 
129
    for ( n = 0; n < count; n++ )
 
130
      priv->family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n];
 
131
 
 
132
    priv->blue_scale = cpriv->blue_scale;
 
133
    priv->blue_shift = (FT_Int)cpriv->blue_shift;
 
134
    priv->blue_fuzz  = (FT_Int)cpriv->blue_fuzz;
 
135
 
 
136
    priv->standard_width[0]  = (FT_UShort)cpriv->standard_width;
 
137
    priv->standard_height[0] = (FT_UShort)cpriv->standard_height;
 
138
 
 
139
    count = priv->num_snap_widths = cpriv->num_snap_widths;
 
140
    for ( n = 0; n < count; n++ )
 
141
      priv->snap_widths[n] = (FT_Short)cpriv->snap_widths[n];
 
142
 
 
143
    count = priv->num_snap_heights = cpriv->num_snap_heights;
 
144
    for ( n = 0; n < count; n++ )
 
145
      priv->snap_heights[n] = (FT_Short)cpriv->snap_heights[n];
 
146
 
 
147
    priv->force_bold     = cpriv->force_bold;
 
148
    priv->language_group = cpriv->language_group;
 
149
    priv->lenIV          = cpriv->lenIV;
 
150
  }
 
151
 
 
152
 
 
153
  FT_LOCAL_DEF( FT_Error )
 
154
  cff_size_init( FT_Size  cffsize )         /* CFF_Size */
 
155
  {
 
156
    CFF_Size           size  = (CFF_Size)cffsize;
 
157
    FT_Error           error = CFF_Err_Ok;
 
158
    PSH_Globals_Funcs  funcs = cff_size_get_globals_funcs( size );
 
159
 
 
160
 
 
161
    if ( funcs )
 
162
    {
 
163
      CFF_Face      face     = (CFF_Face)cffsize->face;
 
164
      CFF_Font      font     = (CFF_Font)face->extra.data;
 
165
      CFF_Internal  internal;
 
166
 
 
167
      PS_PrivateRec  priv;
 
168
      FT_Memory      memory = cffsize->face->memory;
 
169
 
 
170
      FT_UInt  i;
 
171
 
 
172
 
 
173
      if ( FT_NEW( internal ) )
 
174
        goto Exit;
 
175
 
 
176
      cff_make_private_dict( &font->top_font, &priv );
 
177
      error = funcs->create( cffsize->face->memory, &priv,
 
178
                             &internal->topfont );
 
179
      if ( error )
 
180
        goto Exit;
 
181
 
 
182
      for ( i = font->num_subfonts; i > 0; i-- )
 
183
      {
 
184
        CFF_SubFont  sub = font->subfonts[i - 1];
 
185
 
 
186
 
 
187
        cff_make_private_dict( sub, &priv );
 
188
        error = funcs->create( cffsize->face->memory, &priv,
 
189
                               &internal->subfonts[i - 1] );
 
190
        if ( error )
 
191
          goto Exit;
 
192
      }
 
193
 
 
194
      cffsize->internal = (FT_Size_Internal)(void*)internal;
 
195
    }
 
196
 
 
197
    size->strike_index = 0xFFFFFFFFUL;
 
198
 
 
199
  Exit:
 
200
    return error;
 
201
  }
 
202
 
 
203
 
 
204
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
 
205
 
 
206
  FT_LOCAL_DEF( FT_Error )
 
207
  cff_size_select( FT_Size   size,
 
208
                   FT_ULong  strike_index )
 
209
  {
 
210
    CFF_Size           cffsize = (CFF_Size)size;
 
211
    PSH_Globals_Funcs  funcs;
 
212
 
 
213
 
 
214
    cffsize->strike_index = strike_index;
 
215
 
 
216
    FT_Select_Metrics( size->face, strike_index );
 
217
 
 
218
    funcs = cff_size_get_globals_funcs( cffsize );
 
219
 
 
220
    if ( funcs )
 
221
    {
 
222
      CFF_Face      face     = (CFF_Face)size->face;
 
223
      CFF_Font      font     = (CFF_Font)face->extra.data;
 
224
      CFF_Internal  internal = (CFF_Internal)size->internal;
 
225
 
 
226
      FT_ULong  top_upm  = font->top_font.font_dict.units_per_em;
 
227
      FT_UInt   i;
 
228
 
 
229
 
 
230
      funcs->set_scale( internal->topfont,
 
231
                        size->metrics.x_scale, size->metrics.y_scale,
 
232
                        0, 0 );
 
233
 
 
234
      for ( i = font->num_subfonts; i > 0; i-- )
 
235
      {
 
236
        CFF_SubFont  sub     = font->subfonts[i - 1];
 
237
        FT_ULong     sub_upm = sub->font_dict.units_per_em;
 
238
        FT_Pos       x_scale, y_scale;
 
239
 
 
240
 
 
241
        if ( top_upm != sub_upm )
 
242
        {
 
243
          x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm );
 
244
          y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm );
 
245
        }
 
246
        else
 
247
        {
 
248
          x_scale = size->metrics.x_scale;
 
249
          y_scale = size->metrics.y_scale;
 
250
        }
 
251
 
 
252
        funcs->set_scale( internal->subfonts[i - 1],
 
253
                          x_scale, y_scale, 0, 0 );
 
254
      }
 
255
    }
 
256
 
 
257
    return CFF_Err_Ok;
 
258
  }
 
259
 
 
260
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
 
261
 
 
262
 
 
263
  FT_LOCAL_DEF( FT_Error )
 
264
  cff_size_request( FT_Size          size,
 
265
                    FT_Size_Request  req )
 
266
  {
 
267
    CFF_Size           cffsize = (CFF_Size)size;
 
268
    PSH_Globals_Funcs  funcs;
 
269
 
 
270
 
 
271
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
 
272
 
 
273
    if ( FT_HAS_FIXED_SIZES( size->face ) )
 
274
    {
 
275
      CFF_Face      cffface = (CFF_Face)size->face;
 
276
      SFNT_Service  sfnt    = (SFNT_Service)cffface->sfnt;
 
277
      FT_ULong      strike_index;
 
278
 
 
279
 
 
280
      if ( sfnt->set_sbit_strike( cffface, req, &strike_index ) )
 
281
        cffsize->strike_index = 0xFFFFFFFFUL;
 
282
      else
 
283
        return cff_size_select( size, strike_index );
 
284
    }
 
285
 
 
286
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
 
287
 
 
288
    FT_Request_Metrics( size->face, req );
 
289
 
 
290
    funcs = cff_size_get_globals_funcs( cffsize );
 
291
 
 
292
    if ( funcs )
 
293
    {
 
294
      CFF_Face      cffface  = (CFF_Face)size->face;
 
295
      CFF_Font      font     = (CFF_Font)cffface->extra.data;
 
296
      CFF_Internal  internal = (CFF_Internal)size->internal;
 
297
 
 
298
      FT_ULong  top_upm  = font->top_font.font_dict.units_per_em;
 
299
      FT_UInt   i;
 
300
 
 
301
 
 
302
      funcs->set_scale( internal->topfont,
 
303
                        size->metrics.x_scale, size->metrics.y_scale,
 
304
                        0, 0 );
 
305
 
 
306
      for ( i = font->num_subfonts; i > 0; i-- )
 
307
      {
 
308
        CFF_SubFont  sub     = font->subfonts[i - 1];
 
309
        FT_ULong     sub_upm = sub->font_dict.units_per_em;
 
310
        FT_Pos       x_scale, y_scale;
 
311
 
 
312
 
 
313
        if ( top_upm != sub_upm )
 
314
        {
 
315
          x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm );
 
316
          y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm );
 
317
        }
 
318
        else
 
319
        {
 
320
          x_scale = size->metrics.x_scale;
 
321
          y_scale = size->metrics.y_scale;
 
322
        }
 
323
 
 
324
        funcs->set_scale( internal->subfonts[i - 1],
 
325
                          x_scale, y_scale, 0, 0 );
 
326
      }
 
327
    }
 
328
 
 
329
    return CFF_Err_Ok;
 
330
  }
 
331
 
 
332
 
 
333
  /*************************************************************************/
 
334
  /*                                                                       */
 
335
  /*                            SLOT  FUNCTIONS                            */
 
336
  /*                                                                       */
 
337
  /*************************************************************************/
 
338
 
 
339
  FT_LOCAL_DEF( void )
 
340
  cff_slot_done( FT_GlyphSlot  slot )
 
341
  {
 
342
    slot->internal->glyph_hints = 0;
 
343
  }
 
344
 
 
345
 
 
346
  FT_LOCAL_DEF( FT_Error )
 
347
  cff_slot_init( FT_GlyphSlot  slot )
 
348
  {
 
349
    CFF_Face          face     = (CFF_Face)slot->face;
 
350
    CFF_Font          font     = (CFF_Font)face->extra.data;
 
351
    PSHinter_Service  pshinter = font->pshinter;
 
352
 
 
353
 
 
354
    if ( pshinter )
 
355
    {
 
356
      FT_Module  module;
 
357
 
 
358
 
 
359
      module = FT_Get_Module( slot->face->driver->root.library,
 
360
                              "pshinter" );
 
361
      if ( module )
 
362
      {
 
363
        T2_Hints_Funcs  funcs;
 
364
 
 
365
 
 
366
        funcs = pshinter->get_t2_funcs( module );
 
367
        slot->internal->glyph_hints = (void*)funcs;
 
368
      }
 
369
    }
 
370
 
 
371
    return CFF_Err_Ok;
 
372
  }
 
373
 
 
374
 
 
375
  /*************************************************************************/
 
376
  /*                                                                       */
 
377
  /*                           FACE  FUNCTIONS                             */
 
378
  /*                                                                       */
 
379
  /*************************************************************************/
 
380
 
 
381
  static FT_String*
 
382
  cff_strcpy( FT_Memory         memory,
 
383
              const FT_String*  source )
 
384
  {
 
385
    FT_Error    error;
 
386
    FT_String*  result;
 
387
 
 
388
 
 
389
    (void)FT_STRDUP( result, source );
 
390
 
 
391
    FT_UNUSED( error );
 
392
 
 
393
    return result;
 
394
  }
 
395
 
 
396
 
 
397
  /* Strip all subset prefixes of the form `ABCDEF+'.  Usually, there */
 
398
  /* is only one, but font names like `APCOOG+JFABTD+FuturaBQ-Bold'   */
 
399
  /* have been seen in the wild.                                      */
 
400
 
 
401
  static void
 
402
  remove_subset_prefix( FT_String*  name )
 
403
  {
 
404
    FT_Int32  idx             = 0;
 
405
    FT_Int32  length          = strlen( name ) + 1;
 
406
    FT_Bool   continue_search = 1;
 
407
 
 
408
 
 
409
    while ( continue_search )
 
410
    {
 
411
      if ( length >= 7 && name[6] == '+' )
 
412
      {
 
413
        for ( idx = 0; idx < 6; idx++ )
 
414
        {
 
415
          /* ASCII uppercase letters */
 
416
          if ( !( 'A' <= name[idx] && name[idx] <= 'Z' ) )
 
417
            continue_search = 0;
 
418
        }
 
419
 
 
420
        if ( continue_search )
 
421
        {
 
422
          for ( idx = 7; idx < length; idx++ )
 
423
            name[idx - 7] = name[idx];
 
424
        }
 
425
      }
 
426
      else
 
427
        continue_search = 0;
 
428
    }
 
429
  }
 
430
 
 
431
 
 
432
  FT_LOCAL_DEF( FT_Error )
 
433
  cff_face_init( FT_Stream      stream,
 
434
                 FT_Face        cffface,        /* CFF_Face */
 
435
                 FT_Int         face_index,
 
436
                 FT_Int         num_params,
 
437
                 FT_Parameter*  params )
 
438
  {
 
439
    CFF_Face            face = (CFF_Face)cffface;
 
440
    FT_Error            error;
 
441
    SFNT_Service        sfnt;
 
442
    FT_Service_PsCMaps  psnames;
 
443
    PSHinter_Service    pshinter;
 
444
    FT_Bool             pure_cff    = 1;
 
445
    FT_Bool             sfnt_format = 0;
 
446
    FT_Library library = cffface->driver->root.library;
 
447
 
 
448
 
 
449
    sfnt = (SFNT_Service)FT_Get_Module_Interface(
 
450
             library, "sfnt" );
 
451
    if ( !sfnt )
 
452
      goto Bad_Format;
 
453
 
 
454
    FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
 
455
 
 
456
    pshinter = (PSHinter_Service)FT_Get_Module_Interface(
 
457
                 library, "pshinter" );
 
458
 
 
459
    /* create input stream from resource */
 
460
    if ( FT_STREAM_SEEK( 0 ) )
 
461
      goto Exit;
 
462
 
 
463
    /* check whether we have a valid OpenType file */
 
464
    error = sfnt->init_face( stream, face, face_index, num_params, params );
 
465
    if ( !error )
 
466
    {
 
467
      if ( face->format_tag != TTAG_OTTO )  /* `OTTO'; OpenType/CFF font */
 
468
      {
 
469
        FT_TRACE2(( "[not a valid OpenType/CFF font]\n" ));
 
470
        goto Bad_Format;
 
471
      }
 
472
 
 
473
      /* if we are performing a simple font format check, exit immediately */
 
474
      if ( face_index < 0 )
 
475
        return CFF_Err_Ok;
 
476
 
 
477
      /* UNDOCUMENTED!  A CFF in an SFNT can have only a single font. */
 
478
      if ( face_index > 0 )
 
479
      {
 
480
        FT_ERROR(( "cff_face_init: invalid face index\n" ));
 
481
        error = CFF_Err_Invalid_Argument;
 
482
        goto Exit;
 
483
      }
 
484
 
 
485
      sfnt_format = 1;
 
486
 
 
487
      /* now, the font can be either an OpenType/CFF font, or an SVG CEF */
 
488
      /* font; in the latter case it doesn't have a `head' table         */
 
489
      error = face->goto_table( face, TTAG_head, stream, 0 );
 
490
      if ( !error )
 
491
      {
 
492
        pure_cff = 0;
 
493
 
 
494
        /* load font directory */
 
495
        error = sfnt->load_face( stream, face, 0, num_params, params );
 
496
        if ( error )
 
497
          goto Exit;
 
498
      }
 
499
      else
 
500
      {
 
501
        /* load the `cmap' table explicitly */
 
502
        error = sfnt->load_cmap( face, stream );
 
503
        if ( error )
 
504
          goto Exit;
 
505
 
 
506
        /* XXX: we don't load the GPOS table, as OpenType Layout     */
 
507
        /* support will be added later to a layout library on top of */
 
508
        /* FreeType 2                                                */
 
509
      }
 
510
 
 
511
      /* now load the CFF part of the file */
 
512
      error = face->goto_table( face, TTAG_CFF, stream, 0 );
 
513
      if ( error )
 
514
        goto Exit;
 
515
    }
 
516
    else
 
517
    {
 
518
      /* rewind to start of file; we are going to load a pure-CFF font */
 
519
      if ( FT_STREAM_SEEK( 0 ) )
 
520
        goto Exit;
 
521
      error = CFF_Err_Ok;
 
522
    }
 
523
 
 
524
    /* now load and parse the CFF table in the file */
 
525
    {
 
526
      CFF_Font         cff;
 
527
      CFF_FontRecDict  dict;
 
528
      FT_Memory        memory = cffface->memory;
 
529
      FT_Int32         flags;
 
530
      FT_UInt          i;
 
531
 
 
532
 
 
533
      if ( FT_NEW( cff ) )
 
534
        goto Exit;
 
535
 
 
536
      face->extra.data = cff;
 
537
      error = cff_font_load( library, stream, face_index, cff, pure_cff );
 
538
      if ( error )
 
539
        goto Exit;
 
540
 
 
541
      cff->pshinter = pshinter;
 
542
      cff->psnames  = psnames;
 
543
 
 
544
      cffface->face_index = face_index;
 
545
 
 
546
      /* Complement the root flags with some interesting information. */
 
547
      /* Note that this is only necessary for pure CFF and CEF fonts; */
 
548
      /* SFNT based fonts use the `name' table instead.               */
 
549
 
 
550
      cffface->num_glyphs = cff->num_glyphs;
 
551
 
 
552
      dict = &cff->top_font.font_dict;
 
553
 
 
554
      /* we need the `PSNames' module for CFF and CEF formats */
 
555
      /* which aren't CID-keyed                               */
 
556
      if ( dict->cid_registry == 0xFFFFU && !psnames )
 
557
      {
 
558
        FT_ERROR(( "cff_face_init:"
 
559
                   " cannot open CFF & CEF fonts\n"
 
560
                   "              "
 
561
                   " without the `PSNames' module\n" ));
 
562
        goto Bad_Format;
 
563
      }
 
564
 
 
565
      if ( !dict->units_per_em )
 
566
        dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM;
 
567
 
 
568
      /* Normalize the font matrix so that `matrix->xx' is 1; the */
 
569
      /* scaling is done with `units_per_em' then (at this point, */
 
570
      /* it already contains the scaling factor, but without      */
 
571
      /* normalization of the matrix).                            */
 
572
      /*                                                          */
 
573
      /* Note that the offsets must be expressed in integer font  */
 
574
      /* units.                                                   */
 
575
 
 
576
      {
 
577
        FT_Matrix*  matrix = &dict->font_matrix;
 
578
        FT_Vector*  offset = &dict->font_offset;
 
579
        FT_ULong*   upm    = &dict->units_per_em;
 
580
        FT_Fixed    temp   = FT_ABS( matrix->yy );
 
581
 
 
582
 
 
583
        if ( temp != 0x10000L )
 
584
        {
 
585
          *upm = FT_DivFix( *upm, temp );
 
586
 
 
587
          matrix->xx = FT_DivFix( matrix->xx, temp );
 
588
          matrix->yx = FT_DivFix( matrix->yx, temp );
 
589
          matrix->xy = FT_DivFix( matrix->xy, temp );
 
590
          matrix->yy = FT_DivFix( matrix->yy, temp );
 
591
          offset->x  = FT_DivFix( offset->x,  temp );
 
592
          offset->y  = FT_DivFix( offset->y,  temp );
 
593
        }
 
594
 
 
595
        offset->x >>= 16;
 
596
        offset->y >>= 16;
 
597
      }
 
598
 
 
599
      for ( i = cff->num_subfonts; i > 0; i-- )
 
600
      {
 
601
        CFF_FontRecDict  sub = &cff->subfonts[i - 1]->font_dict;
 
602
        CFF_FontRecDict  top = &cff->top_font.font_dict;
 
603
 
 
604
        FT_Matrix*  matrix;
 
605
        FT_Vector*  offset;
 
606
        FT_ULong*   upm;
 
607
        FT_Fixed    temp;
 
608
 
 
609
 
 
610
        if ( sub->units_per_em )
 
611
        {
 
612
          FT_Long  scaling;
 
613
 
 
614
 
 
615
          if ( top->units_per_em > 1 && sub->units_per_em > 1 )
 
616
            scaling = FT_MIN( top->units_per_em, sub->units_per_em );
 
617
          else
 
618
            scaling = 1;
 
619
 
 
620
          FT_Matrix_Multiply_Scaled( &top->font_matrix,
 
621
                                     &sub->font_matrix,
 
622
                                     scaling );
 
623
          FT_Vector_Transform_Scaled( &sub->font_offset,
 
624
                                      &top->font_matrix,
 
625
                                      scaling );
 
626
 
 
627
          sub->units_per_em = FT_MulDiv( sub->units_per_em,
 
628
                                         top->units_per_em,
 
629
                                         scaling );
 
630
        }
 
631
        else
 
632
        {
 
633
          sub->font_matrix = top->font_matrix;
 
634
          sub->font_offset = top->font_offset;
 
635
 
 
636
          sub->units_per_em = top->units_per_em;
 
637
        }
 
638
 
 
639
        matrix = &sub->font_matrix;
 
640
        offset = &sub->font_offset;
 
641
        upm    = &sub->units_per_em;
 
642
        temp   = FT_ABS( matrix->yy );
 
643
 
 
644
        if ( temp != 0x10000L )
 
645
        {
 
646
          *upm = FT_DivFix( *upm, temp );
 
647
 
 
648
          /* if *upm is larger than 100*1000 we divide by 1000 --     */
 
649
          /* this can happen if e.g. there is no top-font FontMatrix  */
 
650
          /* and the subfont FontMatrix already contains the complete */
 
651
          /* scaling for the subfont (see section 5.11 of the PLRM)   */
 
652
 
 
653
          /* 100 is a heuristic value */
 
654
 
 
655
          if ( *upm > 100L * 1000L )
 
656
            *upm = ( *upm + 500 ) / 1000;
 
657
 
 
658
          matrix->xx = FT_DivFix( matrix->xx, temp );
 
659
          matrix->yx = FT_DivFix( matrix->yx, temp );
 
660
          matrix->xy = FT_DivFix( matrix->xy, temp );
 
661
          matrix->yy = FT_DivFix( matrix->yy, temp );
 
662
          offset->x  = FT_DivFix( offset->x,  temp );
 
663
          offset->y  = FT_DivFix( offset->y,  temp );
 
664
        }
 
665
 
 
666
        offset->x >>= 16;
 
667
        offset->y >>= 16;
 
668
      }
 
669
 
 
670
      if ( pure_cff )
 
671
      {
 
672
        char*  style_name = NULL;
 
673
 
 
674
 
 
675
        /* set up num_faces */
 
676
        cffface->num_faces = cff->num_faces;
 
677
 
 
678
        /* compute number of glyphs */
 
679
        if ( dict->cid_registry != 0xFFFFU )
 
680
          cffface->num_glyphs = cff->charset.max_cid + 1;
 
681
        else
 
682
          cffface->num_glyphs = cff->charstrings_index.count;
 
683
 
 
684
        /* set global bbox, as well as EM size */
 
685
        cffface->bbox.xMin =   dict->font_bbox.xMin            >> 16;
 
686
        cffface->bbox.yMin =   dict->font_bbox.yMin            >> 16;
 
687
        /* no `U' suffix here to 0xFFFF! */
 
688
        cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFF ) >> 16;
 
689
        cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFF ) >> 16;
 
690
 
 
691
        cffface->units_per_EM = (FT_UShort)( dict->units_per_em );
 
692
 
 
693
        cffface->ascender  = (FT_Short)( cffface->bbox.yMax );
 
694
        cffface->descender = (FT_Short)( cffface->bbox.yMin );
 
695
 
 
696
        cffface->height = (FT_Short)( ( cffface->units_per_EM * 12 ) / 10 );
 
697
        if ( cffface->height < cffface->ascender - cffface->descender )
 
698
          cffface->height = (FT_Short)( cffface->ascender - cffface->descender );
 
699
 
 
700
        cffface->underline_position  =
 
701
          (FT_Short)( dict->underline_position >> 16 );
 
702
        cffface->underline_thickness =
 
703
          (FT_Short)( dict->underline_thickness >> 16 );
 
704
 
 
705
        /* retrieve font family & style name */
 
706
        cffface->family_name = cff_index_get_name( cff, face_index );
 
707
        if ( cffface->family_name )
 
708
        {
 
709
          char*  full   = cff_index_get_sid_string( cff,
 
710
                                                    dict->full_name );
 
711
          char*  fullp  = full;
 
712
          char*  family = cffface->family_name;
 
713
          char*  family_name = NULL;
 
714
 
 
715
 
 
716
          remove_subset_prefix( cffface->family_name ); 
 
717
 
 
718
          if ( dict->family_name )
 
719
          {
 
720
            family_name = cff_index_get_sid_string( cff,
 
721
                                                    dict->family_name );
 
722
            if ( family_name )
 
723
              family = family_name;
 
724
          }
 
725
 
 
726
          /* We try to extract the style name from the full name.   */
 
727
          /* We need to ignore spaces and dashes during the search. */
 
728
          if ( full && family )
 
729
          {
 
730
            while ( *fullp )
 
731
            {
 
732
              /* skip common characters at the start of both strings */
 
733
              if ( *fullp == *family )
 
734
              {
 
735
                family++;
 
736
                fullp++;
 
737
                continue;
 
738
              }
 
739
 
 
740
              /* ignore spaces and dashes in full name during comparison */
 
741
              if ( *fullp == ' ' || *fullp == '-' )
 
742
              {
 
743
                fullp++;
 
744
                continue;
 
745
              }
 
746
 
 
747
              /* ignore spaces and dashes in family name during comparison */
 
748
              if ( *family == ' ' || *family == '-' )
 
749
              {
 
750
                family++;
 
751
                continue;
 
752
              }
 
753
 
 
754
              if ( !*family && *fullp )
 
755
              {
 
756
                /* The full name begins with the same characters as the  */
 
757
                /* family name, with spaces and dashes removed.  In this */
 
758
                /* case, the remaining string in `fullp' will be used as */
 
759
                /* the style name.                                       */
 
760
                style_name = cff_strcpy( memory, fullp );
 
761
              }
 
762
              break;
 
763
            }
 
764
          }
 
765
        }
 
766
        else
 
767
        {
 
768
          char  *cid_font_name =
 
769
                   cff_index_get_sid_string( cff,
 
770
                                             dict->cid_font_name );
 
771
 
 
772
 
 
773
          /* do we have a `/FontName' for a CID-keyed font? */
 
774
          if ( cid_font_name )
 
775
            cffface->family_name = cff_strcpy( memory, cid_font_name );
 
776
        }
 
777
 
 
778
        if ( style_name )
 
779
          cffface->style_name = style_name;
 
780
        else
 
781
          /* assume "Regular" style if we don't know better */
 
782
          cffface->style_name = cff_strcpy( memory, (char *)"Regular" );
 
783
 
 
784
        /*******************************************************************/
 
785
        /*                                                                 */
 
786
        /* Compute face flags.                                             */
 
787
        /*                                                                 */
 
788
        flags = (FT_UInt32)( FT_FACE_FLAG_SCALABLE   | /* scalable outlines */
 
789
                             FT_FACE_FLAG_HORIZONTAL | /* horizontal data   */
 
790
                             FT_FACE_FLAG_HINTER );    /* has native hinter */
 
791
 
 
792
        if ( sfnt_format )
 
793
          flags |= (FT_UInt32)FT_FACE_FLAG_SFNT;
 
794
 
 
795
        /* fixed width font? */
 
796
        if ( dict->is_fixed_pitch )
 
797
          flags |= (FT_UInt32)FT_FACE_FLAG_FIXED_WIDTH;
 
798
 
 
799
  /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */
 
800
#if 0
 
801
        /* kerning available? */
 
802
        if ( face->kern_pairs )
 
803
          flags |= (FT_UInt32)FT_FACE_FLAG_KERNING;
 
804
#endif
 
805
 
 
806
        cffface->face_flags = flags;
 
807
 
 
808
        /*******************************************************************/
 
809
        /*                                                                 */
 
810
        /* Compute style flags.                                            */
 
811
        /*                                                                 */
 
812
        flags = 0;
 
813
 
 
814
        if ( dict->italic_angle )
 
815
          flags |= FT_STYLE_FLAG_ITALIC;
 
816
 
 
817
        {
 
818
          char  *weight = cff_index_get_sid_string( cff,
 
819
                                                    dict->weight );
 
820
 
 
821
 
 
822
          if ( weight )
 
823
            if ( !ft_strcmp( weight, "Bold"  ) ||
 
824
                 !ft_strcmp( weight, "Black" ) )
 
825
              flags |= FT_STYLE_FLAG_BOLD;
 
826
        }
 
827
 
 
828
        /* double check */
 
829
        if ( !(flags & FT_STYLE_FLAG_BOLD) && cffface->style_name )
 
830
          if ( !ft_strncmp( cffface->style_name, "Bold", 4 )  ||
 
831
               !ft_strncmp( cffface->style_name, "Black", 5 ) )
 
832
            flags |= FT_STYLE_FLAG_BOLD;
 
833
 
 
834
        cffface->style_flags = flags;
 
835
      }
 
836
 
 
837
 
 
838
#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
 
839
      /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */
 
840
      /* has unset this flag because of the 3.0 `post' table.          */
 
841
      if ( dict->cid_registry == 0xFFFFU )
 
842
        cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES;
 
843
#endif
 
844
 
 
845
      if ( dict->cid_registry != 0xFFFFU && pure_cff )
 
846
        cffface->face_flags |= FT_FACE_FLAG_CID_KEYED;
 
847
 
 
848
 
 
849
      /*******************************************************************/
 
850
      /*                                                                 */
 
851
      /* Compute char maps.                                              */
 
852
      /*                                                                 */
 
853
 
 
854
      /* Try to synthesize a Unicode charmap if there is none available */
 
855
      /* already.  If an OpenType font contains a Unicode "cmap", we    */
 
856
      /* will use it, whatever be in the CFF part of the file.          */
 
857
      {
 
858
        FT_CharMapRec  cmaprec;
 
859
        FT_CharMap     cmap;
 
860
        FT_UInt        nn;
 
861
        CFF_Encoding   encoding = &cff->encoding;
 
862
 
 
863
 
 
864
        for ( nn = 0; nn < (FT_UInt)cffface->num_charmaps; nn++ )
 
865
        {
 
866
          cmap = cffface->charmaps[nn];
 
867
 
 
868
          /* Windows Unicode? */
 
869
          if ( cmap->platform_id == TT_PLATFORM_MICROSOFT &&
 
870
               cmap->encoding_id == TT_MS_ID_UNICODE_CS   )
 
871
            goto Skip_Unicode;
 
872
 
 
873
          /* Apple Unicode platform id? */
 
874
          if ( cmap->platform_id == TT_PLATFORM_APPLE_UNICODE )
 
875
            goto Skip_Unicode; /* Apple Unicode */
 
876
        }
 
877
 
 
878
        /* since CID-keyed fonts don't contain glyph names, we can't */
 
879
        /* construct a cmap                                          */
 
880
        if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU )
 
881
          goto Exit;
 
882
 
 
883
#ifdef FT_MAX_CHARMAP_CACHEABLE
 
884
        if ( nn + 1 > FT_MAX_CHARMAP_CACHEABLE )
 
885
        {
 
886
          FT_ERROR(( "cff_face_init: no Unicode cmap is found, "
 
887
                     "and too many subtables (%d) to add synthesized cmap\n",
 
888
                     nn ));
 
889
          goto Exit;
 
890
        }
 
891
#endif
 
892
 
 
893
        /* we didn't find a Unicode charmap -- synthesize one */
 
894
        cmaprec.face        = cffface;
 
895
        cmaprec.platform_id = TT_PLATFORM_MICROSOFT;
 
896
        cmaprec.encoding_id = TT_MS_ID_UNICODE_CS;
 
897
        cmaprec.encoding    = FT_ENCODING_UNICODE;
 
898
 
 
899
        nn = (FT_UInt)cffface->num_charmaps;
 
900
 
 
901
        error = FT_CMap_New( &FT_CFF_CMAP_UNICODE_CLASS_REC_GET, NULL,
 
902
                             &cmaprec, NULL );
 
903
        if ( error && FT_Err_No_Unicode_Glyph_Name != error )
 
904
          goto Exit;
 
905
        error = FT_Err_Ok;
 
906
 
 
907
        /* if no Unicode charmap was previously selected, select this one */
 
908
        if ( cffface->charmap == NULL && nn != (FT_UInt)cffface->num_charmaps )
 
909
          cffface->charmap = cffface->charmaps[nn];
 
910
 
 
911
      Skip_Unicode:
 
912
#ifdef FT_MAX_CHARMAP_CACHEABLE
 
913
        if ( nn > FT_MAX_CHARMAP_CACHEABLE )
 
914
        {
 
915
          FT_ERROR(( "cff_face_init: Unicode cmap is found, "
 
916
                     "but too many preceding subtables (%d) to access\n",
 
917
                     nn - 1 ));
 
918
          goto Exit;
 
919
        }
 
920
#endif
 
921
        if ( encoding->count > 0 )
 
922
        {
 
923
          FT_CMap_Class  clazz;
 
924
 
 
925
 
 
926
          cmaprec.face        = cffface;
 
927
          cmaprec.platform_id = TT_PLATFORM_ADOBE;  /* Adobe platform id */
 
928
 
 
929
          if ( encoding->offset == 0 )
 
930
          {
 
931
            cmaprec.encoding_id = TT_ADOBE_ID_STANDARD;
 
932
            cmaprec.encoding    = FT_ENCODING_ADOBE_STANDARD;
 
933
            clazz               = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;
 
934
          }
 
935
          else if ( encoding->offset == 1 )
 
936
          {
 
937
            cmaprec.encoding_id = TT_ADOBE_ID_EXPERT;
 
938
            cmaprec.encoding    = FT_ENCODING_ADOBE_EXPERT;
 
939
            clazz               = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;
 
940
          }
 
941
          else
 
942
          {
 
943
            cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM;
 
944
            cmaprec.encoding    = FT_ENCODING_ADOBE_CUSTOM;
 
945
            clazz               = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;
 
946
          }
 
947
 
 
948
          error = FT_CMap_New( clazz, NULL, &cmaprec, NULL );
 
949
        }
 
950
      }
 
951
    }
 
952
 
 
953
  Exit:
 
954
    return error;
 
955
 
 
956
  Bad_Format:
 
957
    error = CFF_Err_Unknown_File_Format;
 
958
    goto Exit;
 
959
  }
 
960
 
 
961
 
 
962
  FT_LOCAL_DEF( void )
 
963
  cff_face_done( FT_Face  cffface )         /* CFF_Face */
 
964
  {
 
965
    CFF_Face      face = (CFF_Face)cffface;
 
966
    FT_Memory     memory;
 
967
    SFNT_Service  sfnt;
 
968
 
 
969
 
 
970
    if ( !face )
 
971
      return;
 
972
 
 
973
    memory = cffface->memory;
 
974
    sfnt   = (SFNT_Service)face->sfnt;
 
975
 
 
976
    if ( sfnt )
 
977
      sfnt->done_face( face );
 
978
 
 
979
    {
 
980
      CFF_Font  cff = (CFF_Font)face->extra.data;
 
981
 
 
982
 
 
983
      if ( cff )
 
984
      {
 
985
        cff_font_done( cff );
 
986
        FT_FREE( face->extra.data );
 
987
      }
 
988
    }
 
989
  }
 
990
 
 
991
 
 
992
  FT_LOCAL_DEF( FT_Error )
 
993
  cff_driver_init( FT_Module  module )
 
994
  {
 
995
    FT_UNUSED( module );
 
996
 
 
997
    return CFF_Err_Ok;
 
998
  }
 
999
 
 
1000
 
 
1001
  FT_LOCAL_DEF( void )
 
1002
  cff_driver_done( FT_Module  module )
 
1003
  {
 
1004
    FT_UNUSED( module );
 
1005
  }
 
1006
 
 
1007
 
 
1008
/* END */