PageRenderTime 493ms CodeModel.GetById 120ms app.highlight 257ms RepoModel.GetById 105ms app.codeStats 1ms

/src/compiler/android-ndk/jni/freetype/src/cff/cffobjs.c

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