cffobjs.c revision 77f63d23f7d380b0ff02c18fd6a154ab9063128a
1/***************************************************************************/
2/*                                                                         */
3/*  cffobjs.c                                                              */
4/*                                                                         */
5/*    OpenType objects manager (body).                                     */
6/*                                                                         */
7/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by       */
8/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9/*                                                                         */
10/*  This file is part of the FreeType project, and may only be used,       */
11/*  modified, and distributed under the terms of the FreeType project      */
12/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13/*  this file you indicate that you have read the license and              */
14/*  understand and accept it fully.                                        */
15/*                                                                         */
16/***************************************************************************/
17
18
19#include <ft2build.h>
20#include FT_INTERNAL_DEBUG_H
21#include FT_INTERNAL_CALC_H
22#include FT_INTERNAL_STREAM_H
23#include FT_ERRORS_H
24#include FT_TRUETYPE_IDS_H
25#include FT_TRUETYPE_TAGS_H
26#include FT_INTERNAL_SFNT_H
27#include FT_SERVICE_POSTSCRIPT_CMAPS_H
28#include FT_INTERNAL_POSTSCRIPT_HINTS_H
29#include "cffobjs.h"
30#include "cffload.h"
31#include "cffcmap.h"
32#include "cfferrs.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 = (PSHinter_Service)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_Int   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_Int       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_Int   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_Int       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 = (PSHinter_Service)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  FT_LOCAL_DEF( FT_Error )
398  cff_face_init( FT_Stream      stream,
399                 FT_Face        cffface,        /* CFF_Face */
400                 FT_Int         face_index,
401                 FT_Int         num_params,
402                 FT_Parameter*  params )
403  {
404    CFF_Face            face = (CFF_Face)cffface;
405    FT_Error            error;
406    SFNT_Service        sfnt;
407    FT_Service_PsCMaps  psnames;
408    PSHinter_Service    pshinter;
409    FT_Bool             pure_cff    = 1;
410    FT_Bool             sfnt_format = 0;
411
412
413#if 0
414    FT_FACE_FIND_GLOBAL_SERVICE( face, sfnt,     SFNT );
415    FT_FACE_FIND_GLOBAL_SERVICE( face, psnames,  POSTSCRIPT_NAMES );
416    FT_FACE_FIND_GLOBAL_SERVICE( face, pshinter, POSTSCRIPT_HINTER );
417
418    if ( !sfnt )
419      goto Bad_Format;
420#else
421    sfnt = (SFNT_Service)FT_Get_Module_Interface(
422             cffface->driver->root.library, "sfnt" );
423    if ( !sfnt )
424      goto Bad_Format;
425
426    FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
427
428    pshinter = (PSHinter_Service)FT_Get_Module_Interface(
429                 cffface->driver->root.library, "pshinter" );
430#endif
431
432    /* create input stream from resource */
433    if ( FT_STREAM_SEEK( 0 ) )
434      goto Exit;
435
436    /* check whether we have a valid OpenType file */
437    error = sfnt->init_face( stream, face, face_index, num_params, params );
438    if ( !error )
439    {
440      if ( face->format_tag != TTAG_OTTO )  /* `OTTO'; OpenType/CFF font */
441      {
442        FT_TRACE2(( "[not a valid OpenType/CFF font]\n" ));
443        goto Bad_Format;
444      }
445
446      /* if we are performing a simple font format check, exit immediately */
447      if ( face_index < 0 )
448        return CFF_Err_Ok;
449
450      /* UNDOCUMENTED!  A CFF in an SFNT can have only a single font. */
451      if ( face_index > 0 )
452      {
453        FT_ERROR(( "cff_face_init: invalid face index\n" ));
454        error = CFF_Err_Invalid_Argument;
455        goto Exit;
456      }
457
458      sfnt_format = 1;
459
460      /* now, the font can be either an OpenType/CFF font, or an SVG CEF */
461      /* font; in the latter case it doesn't have a `head' table         */
462      error = face->goto_table( face, TTAG_head, stream, 0 );
463      if ( !error )
464      {
465        pure_cff = 0;
466
467        /* load font directory */
468        error = sfnt->load_face( stream, face, 0, num_params, params );
469        if ( error )
470          goto Exit;
471      }
472      else
473      {
474        /* load the `cmap' table explicitly */
475        error = sfnt->load_cmap( face, stream );
476        if ( error )
477          goto Exit;
478
479        /* XXX: we don't load the GPOS table, as OpenType Layout     */
480        /* support will be added later to a layout library on top of */
481        /* FreeType 2                                                */
482      }
483
484      /* now load the CFF part of the file */
485      error = face->goto_table( face, TTAG_CFF, stream, 0 );
486      if ( error )
487        goto Exit;
488    }
489    else
490    {
491      /* rewind to start of file; we are going to load a pure-CFF font */
492      if ( FT_STREAM_SEEK( 0 ) )
493        goto Exit;
494      error = CFF_Err_Ok;
495    }
496
497    /* now load and parse the CFF table in the file */
498    {
499      CFF_Font         cff;
500      CFF_FontRecDict  dict;
501      FT_Memory        memory = cffface->memory;
502      FT_Int32         flags;
503      FT_UInt          i;
504
505
506      if ( FT_NEW( cff ) )
507        goto Exit;
508
509      face->extra.data = cff;
510      error = cff_font_load( stream, face_index, cff, pure_cff );
511      if ( error )
512        goto Exit;
513
514      cff->pshinter = pshinter;
515      cff->psnames  = (void*)psnames;
516
517      cffface->face_index = face_index;
518
519      /* Complement the root flags with some interesting information. */
520      /* Note that this is only necessary for pure CFF and CEF fonts; */
521      /* SFNT based fonts use the `name' table instead.               */
522
523      cffface->num_glyphs = cff->num_glyphs;
524
525      dict = &cff->top_font.font_dict;
526
527      /* we need the `PSNames' module for CFF and CEF formats */
528      /* which aren't CID-keyed                               */
529      if ( dict->cid_registry == 0xFFFFU && !psnames )
530      {
531        FT_ERROR(( "cff_face_init:" ));
532        FT_ERROR(( " cannot open CFF & CEF fonts\n" ));
533        FT_ERROR(( "              " ));
534        FT_ERROR(( " without the `PSNames' module\n" ));
535        goto Bad_Format;
536      }
537
538      if ( !dict->units_per_em )
539        dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM;
540
541      /* Normalize the font matrix so that `matrix->xx' is 1; the */
542      /* scaling is done with `units_per_em' then (at this point, */
543      /* it already contains the scaling factor, but without      */
544      /* normalization of the matrix).                            */
545      /*                                                          */
546      /* Note that the offsets must be expressed in integer font  */
547      /* units.                                                   */
548
549      {
550        FT_Matrix*  matrix = &dict->font_matrix;
551        FT_Vector*  offset = &dict->font_offset;
552        FT_ULong*   upm    = &dict->units_per_em;
553        FT_Fixed    temp   = FT_ABS( matrix->yy );
554
555
556        if ( temp != 0x10000L )
557        {
558          *upm = FT_DivFix( *upm, temp );
559
560          matrix->xx = FT_DivFix( matrix->xx, temp );
561          matrix->yx = FT_DivFix( matrix->yx, temp );
562          matrix->xy = FT_DivFix( matrix->xy, temp );
563          matrix->yy = FT_DivFix( matrix->yy, temp );
564          offset->x  = FT_DivFix( offset->x,  temp );
565          offset->y  = FT_DivFix( offset->y,  temp );
566        }
567
568        offset->x >>= 16;
569        offset->y >>= 16;
570      }
571
572      for ( i = cff->num_subfonts; i > 0; i-- )
573      {
574        CFF_FontRecDict  sub = &cff->subfonts[i - 1]->font_dict;
575        CFF_FontRecDict  top = &cff->top_font.font_dict;
576
577        FT_Matrix*  matrix;
578        FT_Vector*  offset;
579        FT_ULong*   upm;
580        FT_Fixed    temp;
581
582
583        if ( sub->units_per_em )
584        {
585          FT_Int  scaling;
586
587
588          if ( top->units_per_em > 1 && sub->units_per_em > 1 )
589            scaling = FT_MIN( top->units_per_em, sub->units_per_em );
590          else
591            scaling = 1;
592
593          FT_Matrix_Multiply_Scaled( &top->font_matrix,
594                                     &sub->font_matrix,
595                                     scaling );
596          FT_Vector_Transform_Scaled( &sub->font_offset,
597                                      &top->font_matrix,
598                                      scaling );
599
600          sub->units_per_em = FT_MulDiv( sub->units_per_em,
601                                         top->units_per_em,
602                                         scaling );
603        }
604        else
605        {
606          sub->font_matrix = top->font_matrix;
607          sub->font_offset = top->font_offset;
608
609          sub->units_per_em = top->units_per_em;
610        }
611
612        matrix = &sub->font_matrix;
613        offset = &sub->font_offset;
614        upm    = &sub->units_per_em;
615        temp   = FT_ABS( matrix->yy );
616
617        if ( temp != 0x10000L )
618        {
619          *upm = FT_DivFix( *upm, temp );
620
621          /* if *upm is larger than 100*1000 we divide by 1000 --     */
622          /* this can happen if e.g. there is no top-font FontMatrix  */
623          /* and the subfont FontMatrix already contains the complete */
624          /* scaling for the subfont (see section 5.11 of the PLRM)   */
625
626          /* 100 is a heuristic value */
627
628          if ( *upm > 100L * 1000L )
629            *upm = ( *upm + 500 ) / 1000;
630
631          matrix->xx = FT_DivFix( matrix->xx, temp );
632          matrix->yx = FT_DivFix( matrix->yx, temp );
633          matrix->xy = FT_DivFix( matrix->xy, temp );
634          matrix->yy = FT_DivFix( matrix->yy, temp );
635          offset->x  = FT_DivFix( offset->x,  temp );
636          offset->y  = FT_DivFix( offset->y,  temp );
637        }
638
639        offset->x >>= 16;
640        offset->y >>= 16;
641      }
642
643      if ( pure_cff )
644      {
645        char*  style_name = NULL;
646
647
648        /* set up num_faces */
649        cffface->num_faces = cff->num_faces;
650
651        /* compute number of glyphs */
652        if ( dict->cid_registry != 0xFFFFU )
653          cffface->num_glyphs = cff->charset.max_cid;
654        else
655          cffface->num_glyphs = cff->charstrings_index.count;
656
657        /* set global bbox, as well as EM size */
658        cffface->bbox.xMin =   dict->font_bbox.xMin             >> 16;
659        cffface->bbox.yMin =   dict->font_bbox.yMin             >> 16;
660        cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFFU ) >> 16;
661        cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFFU ) >> 16;
662
663        cffface->units_per_EM = (FT_UShort)( dict->units_per_em );
664
665        cffface->ascender  = (FT_Short)( cffface->bbox.yMax );
666        cffface->descender = (FT_Short)( cffface->bbox.yMin );
667
668        cffface->height = (FT_Short)( ( cffface->units_per_EM * 12 ) / 10 );
669        if ( cffface->height < cffface->ascender - cffface->descender )
670          cffface->height = (FT_Short)( cffface->ascender - cffface->descender );
671
672        cffface->underline_position  =
673          (FT_Short)( dict->underline_position >> 16 );
674        cffface->underline_thickness =
675          (FT_Short)( dict->underline_thickness >> 16 );
676
677        /* retrieve font family & style name */
678        cffface->family_name = cff_index_get_name( &cff->name_index,
679                                                   face_index );
680
681        if ( cffface->family_name )
682        {
683          char*  full   = cff_index_get_sid_string( &cff->string_index,
684                                                    dict->full_name,
685                                                    psnames );
686          char*  fullp  = full;
687          char*  family = cffface->family_name;
688          char*  family_name = 0;
689
690
691          if ( dict->family_name )
692          {
693            family_name = cff_index_get_sid_string( &cff->string_index,
694                                                    dict->family_name,
695                                                    psnames);
696            if ( family_name )
697              family = family_name;
698          }
699
700          /* We try to extract the style name from the full name.   */
701          /* We need to ignore spaces and dashes during the search. */
702          if ( full && family )
703          {
704            while ( *fullp )
705            {
706              /* skip common characters at the start of both strings */
707              if ( *fullp == *family )
708              {
709                family++;
710                fullp++;
711                continue;
712              }
713
714              /* ignore spaces and dashes in full name during comparison */
715              if ( *fullp == ' ' || *fullp == '-' )
716              {
717                fullp++;
718                continue;
719              }
720
721              /* ignore spaces and dashes in family name during comparison */
722              if ( *family == ' ' || *family == '-' )
723              {
724                family++;
725                continue;
726              }
727
728              if ( !*family && *fullp )
729              {
730                /* The full name begins with the same characters as the  */
731                /* family name, with spaces and dashes removed.  In this */
732                /* case, the remaining string in `fullp' will be used as */
733                /* the style name.                                       */
734                style_name = cff_strcpy( memory, fullp );
735              }
736              break;
737            }
738
739            if ( family_name )
740              FT_FREE( family_name );
741            FT_FREE( full );
742          }
743        }
744        else
745        {
746          char  *cid_font_name =
747                   cff_index_get_sid_string( &cff->string_index,
748                                             dict->cid_font_name,
749                                             psnames );
750
751
752          /* do we have a `/FontName' for a CID-keyed font? */
753          if ( cid_font_name )
754            cffface->family_name = cid_font_name;
755        }
756
757        if ( style_name )
758          cffface->style_name = style_name;
759        else
760          /* assume "Regular" style if we don't know better */
761          cffface->style_name = cff_strcpy( memory, (char *)"Regular" );
762
763        /*******************************************************************/
764        /*                                                                 */
765        /* Compute face flags.                                             */
766        /*                                                                 */
767        flags = FT_FACE_FLAG_SCALABLE   |       /* scalable outlines */
768                FT_FACE_FLAG_HORIZONTAL |       /* horizontal data   */
769                FT_FACE_FLAG_HINTER;            /* has native hinter */
770
771        if ( sfnt_format )
772          flags |= FT_FACE_FLAG_SFNT;
773
774        /* fixed width font? */
775        if ( dict->is_fixed_pitch )
776          flags |= FT_FACE_FLAG_FIXED_WIDTH;
777
778  /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */
779#if 0
780        /* kerning available? */
781        if ( face->kern_pairs )
782          flags |= FT_FACE_FLAG_KERNING;
783#endif
784
785        cffface->face_flags = flags;
786
787        /*******************************************************************/
788        /*                                                                 */
789        /* Compute style flags.                                            */
790        /*                                                                 */
791        flags = 0;
792
793        if ( dict->italic_angle )
794          flags |= FT_STYLE_FLAG_ITALIC;
795
796        {
797          char  *weight = cff_index_get_sid_string( &cff->string_index,
798                                                    dict->weight,
799                                                    psnames );
800
801
802          if ( weight )
803            if ( !ft_strcmp( weight, "Bold"  ) ||
804                 !ft_strcmp( weight, "Black" ) )
805              flags |= FT_STYLE_FLAG_BOLD;
806          FT_FREE( weight );
807        }
808
809        /* double check */
810        if ( !(flags & FT_STYLE_FLAG_BOLD) && cffface->style_name )
811          if ( !ft_strncmp( cffface->style_name, "Bold", 4 )  ||
812               !ft_strncmp( cffface->style_name, "Black", 5 ) )
813            flags |= FT_STYLE_FLAG_BOLD;
814
815        cffface->style_flags = flags;
816      }
817
818
819#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
820      /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */
821      /* has unset this flag because of the 3.0 `post' table.          */
822      if ( dict->cid_registry == 0xFFFFU )
823        cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES;
824#endif
825
826      if ( dict->cid_registry != 0xFFFFU && pure_cff )
827        cffface->face_flags |= FT_FACE_FLAG_CID_KEYED;
828
829
830      /*******************************************************************/
831      /*                                                                 */
832      /* Compute char maps.                                              */
833      /*                                                                 */
834
835      /* Try to synthesize a Unicode charmap if there is none available */
836      /* already.  If an OpenType font contains a Unicode "cmap", we    */
837      /* will use it, whatever be in the CFF part of the file.          */
838      {
839        FT_CharMapRec  cmaprec;
840        FT_CharMap     cmap;
841        FT_UInt        nn;
842        CFF_Encoding   encoding = &cff->encoding;
843
844
845        for ( nn = 0; nn < (FT_UInt)cffface->num_charmaps; nn++ )
846        {
847          cmap = cffface->charmaps[nn];
848
849          /* Windows Unicode (3,1)? */
850          if ( cmap->platform_id == 3 && cmap->encoding_id == 1 )
851            goto Skip_Unicode;
852
853          /* Deprecated Unicode platform id? */
854          if ( cmap->platform_id == 0 )
855            goto Skip_Unicode; /* Standard Unicode (deprecated) */
856        }
857
858        /* since CID-keyed fonts don't contain glyph names, we can't */
859        /* construct a cmap                                          */
860        if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU )
861          goto Exit;
862
863        /* we didn't find a Unicode charmap -- synthesize one */
864        cmaprec.face        = cffface;
865        cmaprec.platform_id = 3;
866        cmaprec.encoding_id = 1;
867        cmaprec.encoding    = FT_ENCODING_UNICODE;
868
869        nn = (FT_UInt)cffface->num_charmaps;
870
871        FT_CMap_New( &cff_cmap_unicode_class_rec, NULL, &cmaprec, NULL );
872
873        /* if no Unicode charmap was previously selected, select this one */
874        if ( cffface->charmap == NULL && nn != (FT_UInt)cffface->num_charmaps )
875          cffface->charmap = cffface->charmaps[nn];
876
877      Skip_Unicode:
878        if ( encoding->count > 0 )
879        {
880          FT_CMap_Class  clazz;
881
882
883          cmaprec.face        = cffface;
884          cmaprec.platform_id = 7;  /* Adobe platform id */
885
886          if ( encoding->offset == 0 )
887          {
888            cmaprec.encoding_id = TT_ADOBE_ID_STANDARD;
889            cmaprec.encoding    = FT_ENCODING_ADOBE_STANDARD;
890            clazz               = &cff_cmap_encoding_class_rec;
891          }
892          else if ( encoding->offset == 1 )
893          {
894            cmaprec.encoding_id = TT_ADOBE_ID_EXPERT;
895            cmaprec.encoding    = FT_ENCODING_ADOBE_EXPERT;
896            clazz               = &cff_cmap_encoding_class_rec;
897          }
898          else
899          {
900            cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM;
901            cmaprec.encoding    = FT_ENCODING_ADOBE_CUSTOM;
902            clazz               = &cff_cmap_encoding_class_rec;
903          }
904
905          FT_CMap_New( clazz, NULL, &cmaprec, NULL );
906        }
907      }
908    }
909
910  Exit:
911    return error;
912
913  Bad_Format:
914    error = CFF_Err_Unknown_File_Format;
915    goto Exit;
916  }
917
918
919  FT_LOCAL_DEF( void )
920  cff_face_done( FT_Face  cffface )         /* CFF_Face */
921  {
922    CFF_Face      face = (CFF_Face)cffface;
923    FT_Memory     memory;
924    SFNT_Service  sfnt;
925
926
927    if ( !face )
928      return;
929
930    memory = cffface->memory;
931    sfnt   = (SFNT_Service)face->sfnt;
932
933    if ( sfnt )
934      sfnt->done_face( face );
935
936    {
937      CFF_Font  cff = (CFF_Font)face->extra.data;
938
939
940      if ( cff )
941      {
942        cff_font_done( cff );
943        FT_FREE( face->extra.data );
944      }
945    }
946  }
947
948
949  FT_LOCAL_DEF( FT_Error )
950  cff_driver_init( FT_Module  module )
951  {
952    FT_UNUSED( module );
953
954    return CFF_Err_Ok;
955  }
956
957
958  FT_LOCAL_DEF( void )
959  cff_driver_done( FT_Module  module )
960  {
961    FT_UNUSED( module );
962  }
963
964
965/* END */
966