source: trunk/poppler/freetype-2.2.1/src/cff/cffobjs.c @ 150

Last change on this file since 150 was 150, checked in by Eugene Romanenko, 15 years ago

update freetype to 2.2.1

File size: 25.5 KB
Line 
1/***************************************************************************/
2/*                                                                         */
3/*  cffobjs.c                                                              */
4/*                                                                         */
5/*    OpenType objects manager (body).                                     */
6/*                                                                         */
7/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 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_FontRec *)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
77
78    if ( cffsize->internal )
79    {
80      PSH_Globals_Funcs  funcs;
81
82
83      funcs = cff_size_get_globals_funcs( size );
84      if ( funcs )
85        funcs->destroy( (PSH_Globals)cffsize->internal );
86
87      cffsize->internal = 0;
88    }
89  }
90
91
92  FT_LOCAL_DEF( FT_Error )
93  cff_size_init( FT_Size  cffsize )         /* CFF_Size */
94  {
95    CFF_Size           size  = (CFF_Size)cffsize;
96    FT_Error           error = CFF_Err_Ok;
97    PSH_Globals_Funcs  funcs = cff_size_get_globals_funcs( size );
98
99
100    if ( funcs )
101    {
102      PSH_Globals    globals;
103      CFF_Face       face    = (CFF_Face)cffsize->face;
104      CFF_Font       font    = (CFF_FontRec *)face->extra.data;
105      CFF_SubFont    subfont = &font->top_font;
106
107      CFF_Private    cpriv   = &subfont->private_dict;
108      PS_PrivateRec  priv;
109
110
111      /* IMPORTANT: The CFF and Type1 private dictionaries have    */
112      /*            slightly different structures; we need to      */
113      /*            synthetize a type1 dictionary on the fly here. */
114
115      {
116        FT_UInt  n, count;
117
118
119        FT_MEM_ZERO( &priv, sizeof ( priv ) );
120
121        count = priv.num_blue_values = cpriv->num_blue_values;
122        for ( n = 0; n < count; n++ )
123          priv.blue_values[n] = (FT_Short)cpriv->blue_values[n];
124
125        count = priv.num_other_blues = cpriv->num_other_blues;
126        for ( n = 0; n < count; n++ )
127          priv.other_blues[n] = (FT_Short)cpriv->other_blues[n];
128
129        count = priv.num_family_blues = cpriv->num_family_blues;
130        for ( n = 0; n < count; n++ )
131          priv.family_blues[n] = (FT_Short)cpriv->family_blues[n];
132
133        count = priv.num_family_other_blues = cpriv->num_family_other_blues;
134        for ( n = 0; n < count; n++ )
135          priv.family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n];
136
137        priv.blue_scale = cpriv->blue_scale;
138        priv.blue_shift = (FT_Int)cpriv->blue_shift;
139        priv.blue_fuzz  = (FT_Int)cpriv->blue_fuzz;
140
141        priv.standard_width[0]  = (FT_UShort)cpriv->standard_width;
142        priv.standard_height[0] = (FT_UShort)cpriv->standard_height;
143
144        count = priv.num_snap_widths = cpriv->num_snap_widths;
145        for ( n = 0; n < count; n++ )
146          priv.snap_widths[n] = (FT_Short)cpriv->snap_widths[n];
147
148        count = priv.num_snap_heights = cpriv->num_snap_heights;
149        for ( n = 0; n < count; n++ )
150          priv.snap_heights[n] = (FT_Short)cpriv->snap_heights[n];
151
152        priv.force_bold     = cpriv->force_bold;
153        priv.language_group = cpriv->language_group;
154        priv.lenIV          = cpriv->lenIV;
155      }
156
157      error = funcs->create( cffsize->face->memory, &priv, &globals );
158      if ( !error )
159        cffsize->internal = (FT_Size_Internal)(void*)globals;
160    }
161
162    size->strike_index = 0xFFFFFFFFUL;
163
164    return error;
165  }
166
167
168#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
169
170  FT_LOCAL_DEF( FT_Error )
171  cff_size_select( FT_Size   size,
172                   FT_ULong  strike_index )
173  {
174    CFF_Size           cffsize = (CFF_Size)size;
175    PSH_Globals_Funcs  funcs;
176
177
178    cffsize->strike_index = strike_index;
179
180    FT_Select_Metrics( size->face, strike_index );
181
182    funcs = cff_size_get_globals_funcs( cffsize );
183
184    if ( funcs )
185      funcs->set_scale( (PSH_Globals)size->internal,
186                        size->metrics.x_scale,
187                        size->metrics.y_scale,
188                        0, 0 );
189
190    return CFF_Err_Ok;
191  }
192
193#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
194
195
196  FT_LOCAL_DEF( FT_Error )
197  cff_size_request( FT_Size          size,
198                    FT_Size_Request  req )
199  {
200    CFF_Size           cffsize = (CFF_Size)size;
201    PSH_Globals_Funcs  funcs;
202
203
204#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
205
206    if ( FT_HAS_FIXED_SIZES( size->face ) )
207    {
208      CFF_Face      cffface = (CFF_Face)size->face;
209      SFNT_Service  sfnt    = (SFNT_Service)cffface->sfnt;
210      FT_ULong      index;
211
212
213      if ( sfnt->set_sbit_strike( cffface, req, &index ) )
214        cffsize->strike_index = 0xFFFFFFFFUL;
215      else
216        return cff_size_select( size, index );
217    }
218
219#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
220
221    FT_Request_Metrics( size->face, req );
222
223    funcs = cff_size_get_globals_funcs( cffsize );
224
225    if ( funcs )
226      funcs->set_scale( (PSH_Globals)size->internal,
227                        size->metrics.x_scale,
228                        size->metrics.y_scale,
229                        0, 0 );
230
231    return CFF_Err_Ok;
232  }
233
234
235  /*************************************************************************/
236  /*                                                                       */
237  /*                            SLOT  FUNCTIONS                            */
238  /*                                                                       */
239  /*************************************************************************/
240
241  FT_LOCAL_DEF( void )
242  cff_slot_done( FT_GlyphSlot  slot )
243  {
244    slot->internal->glyph_hints = 0;
245  }
246
247
248  FT_LOCAL_DEF( FT_Error )
249  cff_slot_init( FT_GlyphSlot  slot )
250  {
251    CFF_Face          face     = (CFF_Face)slot->face;
252    CFF_Font          font     = (CFF_FontRec *)face->extra.data;
253    PSHinter_Service  pshinter = (PSHinter_Service)font->pshinter;
254
255
256    if ( pshinter )
257    {
258      FT_Module  module;
259
260
261      module = FT_Get_Module( slot->face->driver->root.library,
262                              "pshinter" );
263      if ( module )
264      {
265        T2_Hints_Funcs  funcs;
266
267
268        funcs = pshinter->get_t2_funcs( module );
269        slot->internal->glyph_hints = (void*)funcs;
270      }
271    }
272
273    return 0;
274  }
275
276
277  /*************************************************************************/
278  /*                                                                       */
279  /*                           FACE  FUNCTIONS                             */
280  /*                                                                       */
281  /*************************************************************************/
282
283  static FT_String*
284  cff_strcpy( FT_Memory         memory,
285              const FT_String*  source )
286  {
287    FT_Error    error;
288    FT_String*  result = 0;
289    FT_Int      len = (FT_Int)ft_strlen( source );
290
291
292    if ( !FT_ALLOC( result, len + 1 ) )
293    {
294      FT_MEM_COPY( result, source, len );
295      result[len] = 0;
296    }
297
298    FT_UNUSED( error );
299
300    return result;
301  }
302
303
304  FT_LOCAL_DEF( FT_Error )
305  cff_face_init( FT_Stream      stream,
306                 FT_Face        cffface,        /* CFF_Face */
307                 FT_Int         face_index,
308                 FT_Int         num_params,
309                 FT_Parameter*  params )
310  {
311    CFF_Face            face = (CFF_Face)cffface;
312    FT_Error            error;
313    SFNT_Service        sfnt;
314    FT_Service_PsCMaps  psnames;
315    PSHinter_Service    pshinter;
316    FT_Bool             pure_cff    = 1;
317    FT_Bool             sfnt_format = 0;
318
319
320#if 0
321    FT_FACE_FIND_GLOBAL_SERVICE( face, sfnt,     SFNT );
322    FT_FACE_FIND_GLOBAL_SERVICE( face, psnames,  POSTSCRIPT_NAMES );
323    FT_FACE_FIND_GLOBAL_SERVICE( face, pshinter, POSTSCRIPT_HINTER );
324
325    if ( !sfnt )
326      goto Bad_Format;
327#else
328    sfnt = (SFNT_Service)FT_Get_Module_Interface(
329             cffface->driver->root.library, "sfnt" );
330    if ( !sfnt )
331      goto Bad_Format;
332
333    FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
334
335    pshinter = (PSHinter_Service)FT_Get_Module_Interface(
336                 cffface->driver->root.library, "pshinter" );
337#endif
338
339    /* create input stream from resource */
340    if ( FT_STREAM_SEEK( 0 ) )
341      goto Exit;
342
343    /* check whether we have a valid OpenType file */
344    error = sfnt->init_face( stream, face, face_index, num_params, params );
345    if ( !error )
346    {
347      if ( face->format_tag != 0x4F54544FL )  /* `OTTO'; OpenType/CFF font */
348      {
349        FT_TRACE2(( "[not a valid OpenType/CFF font]\n" ));
350        goto Bad_Format;
351      }
352
353      /* if we are performing a simple font format check, exit immediately */
354      if ( face_index < 0 )
355        return CFF_Err_Ok;
356
357      /* UNDOCUMENTED!  A CFF in an SFNT can have only a single font. */
358      if ( face_index > 0 )
359      {
360        FT_ERROR(( "cff_face_init: invalid face index\n" ));
361        error = CFF_Err_Invalid_Argument;
362        goto Exit;
363      }
364
365      sfnt_format = 1;
366
367      /* now, the font can be either an OpenType/CFF font, or an SVG CEF */
368      /* font; in the latter case it doesn't have a `head' table         */
369      error = face->goto_table( face, TTAG_head, stream, 0 );
370      if ( !error )
371      {
372        pure_cff = 0;
373
374        /* load font directory */
375        error = sfnt->load_face( stream, face,
376                                 face_index, num_params, params );
377        if ( error )
378          goto Exit;
379      }
380      else
381      {
382        /* load the `cmap' table explicitly */
383        error = sfnt->load_cmap( face, stream );
384        if ( error )
385          goto Exit;
386
387        /* XXX: we don't load the GPOS table, as OpenType Layout     */
388        /* support will be added later to a layout library on top of */
389        /* FreeType 2                                                */
390      }
391
392      /* now load the CFF part of the file */
393      error = face->goto_table( face, TTAG_CFF, stream, 0 );
394      if ( error )
395        goto Exit;
396    }
397    else
398    {
399      /* rewind to start of file; we are going to load a pure-CFF font */
400      if ( FT_STREAM_SEEK( 0 ) )
401        goto Exit;
402      error = CFF_Err_Ok;
403    }
404
405    /* now load and parse the CFF table in the file */
406    {
407      CFF_Font         cff;
408      CFF_FontRecDict  dict;
409      FT_Memory        memory = cffface->memory;
410      FT_Int32         flags;
411      FT_UInt          i;
412
413
414      if ( FT_NEW( cff ) )
415        goto Exit;
416
417      face->extra.data = cff;
418      error = cff_font_load( stream, face_index, cff );
419      if ( error )
420        goto Exit;
421
422      cff->pshinter = pshinter;
423      cff->psnames  = (void*)psnames;
424
425      /* Complement the root flags with some interesting information. */
426      /* Note that this is only necessary for pure CFF and CEF fonts; */
427      /* SFNT based fonts use the `name' table instead.               */
428
429      cffface->num_glyphs = cff->num_glyphs;
430
431      dict = &cff->top_font.font_dict;
432
433      /* we need the `PSNames' module for CFF and CEF formats */
434      /* which aren't CID-keyed                               */
435      if ( dict->cid_registry == 0xFFFFU && !psnames )
436      {
437        FT_ERROR(( "cff_face_init:" ));
438        FT_ERROR(( " cannot open CFF & CEF fonts\n" ));
439        FT_ERROR(( "              " ));
440        FT_ERROR(( " without the `PSNames' module\n" ));
441        goto Bad_Format;
442      }
443
444      if ( pure_cff )
445      {
446        char*  style_name = NULL;
447
448
449        /* set up num_faces */
450        cffface->num_faces = cff->num_faces;
451
452        /* compute number of glyphs */
453        if ( dict->cid_registry != 0xFFFFU )
454          cffface->num_glyphs = dict->cid_count;
455        else
456          cffface->num_glyphs = cff->charstrings_index.count;
457
458        /* set global bbox, as well as EM size */
459        cffface->bbox.xMin =   dict->font_bbox.xMin             >> 16;
460        cffface->bbox.yMin =   dict->font_bbox.yMin             >> 16;
461        cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFFU ) >> 16;
462        cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFFU ) >> 16;
463
464        if ( !dict->units_per_em )
465          dict->units_per_em = 1000;
466
467        cffface->units_per_EM = dict->units_per_em;
468
469        cffface->ascender  = (FT_Short)( cffface->bbox.yMax );
470        cffface->descender = (FT_Short)( cffface->bbox.yMin );
471
472        cffface->height = (FT_Short)( ( cffface->units_per_EM * 12 ) / 10 );
473        if ( cffface->height < cffface->ascender - cffface->descender )
474          cffface->height = (FT_Short)( cffface->ascender - cffface->descender );
475
476        cffface->underline_position  =
477          (FT_Short)( dict->underline_position >> 16 );
478        cffface->underline_thickness =
479          (FT_Short)( dict->underline_thickness >> 16 );
480
481        /* retrieve font family & style name */
482        cffface->family_name = cff_index_get_name( &cff->name_index,
483                                                   face_index );
484
485        if ( cffface->family_name )
486        {
487          char*  full   = cff_index_get_sid_string( &cff->string_index,
488                                                    dict->full_name,
489                                                    psnames );
490          char*  fullp  = full;
491          char*  family = cffface->family_name;
492          char*  family_name = 0;
493
494
495          if ( dict->family_name )
496          {
497            family_name = cff_index_get_sid_string( &cff->string_index,
498                                                    dict->family_name,
499                                                    psnames);
500            if ( family_name )
501              family = family_name;
502          }
503
504          /* We try to extract the style name from the full name.   */
505          /* We need to ignore spaces and dashes during the search. */
506          if ( full && family )
507          {
508            while ( *fullp )
509            {
510              /* skip common characters at the start of both strings */
511              if ( *fullp == *family )
512              {
513                family++;
514                fullp++;
515                continue;
516              }
517
518              /* ignore spaces and dashes in full name during comparison */
519              if ( *fullp == ' ' || *fullp == '-' )
520              {
521                fullp++;
522                continue;
523              }
524
525              /* ignore spaces and dashes in family name during comparison */
526              if ( *family == ' ' || *family == '-' )
527              {
528                family++;
529                continue;
530              }
531
532              if ( !*family && *fullp )
533              {
534                /* The full name begins with the same characters as the  */
535                /* family name, with spaces and dashes removed.  In this */
536                /* case, the remaining string in `fullp' will be used as */
537                /* the style name.                                       */
538                style_name = cff_strcpy( memory, fullp );
539              }
540              break;
541            }
542
543            if ( family_name )
544              FT_FREE( family_name );
545            FT_FREE( full );
546          }
547        }
548        else
549        {
550          char  *cid_font_name =
551                   cff_index_get_sid_string( &cff->string_index,
552                                             dict->cid_font_name,
553                                             psnames );
554
555
556          /* do we have a `/FontName' for a CID-keyed font? */
557          if ( cid_font_name )
558            cffface->family_name = cid_font_name;
559        }
560
561        if ( style_name )
562          cffface->style_name = style_name;
563        else
564          /* assume "Regular" style if we don't know better */
565          cffface->style_name = cff_strcpy( memory, (char *)"Regular" );
566
567        /*******************************************************************/
568        /*                                                                 */
569        /* Compute face flags.                                             */
570        /*                                                                 */
571        flags = FT_FACE_FLAG_SCALABLE   |       /* scalable outlines */
572                FT_FACE_FLAG_HORIZONTAL |       /* horizontal data   */
573                FT_FACE_FLAG_HINTER;            /* has native hinter */
574
575        if ( sfnt_format )
576          flags |= FT_FACE_FLAG_SFNT;
577
578        /* fixed width font? */
579        if ( dict->is_fixed_pitch )
580          flags |= FT_FACE_FLAG_FIXED_WIDTH;
581
582  /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */
583#if 0
584        /* kerning available? */
585        if ( face->kern_pairs )
586          flags |= FT_FACE_FLAG_KERNING;
587#endif
588
589        cffface->face_flags = flags;
590
591        /*******************************************************************/
592        /*                                                                 */
593        /* Compute style flags.                                            */
594        /*                                                                 */
595        flags = 0;
596
597        if ( dict->italic_angle )
598          flags |= FT_STYLE_FLAG_ITALIC;
599
600        {
601          char  *weight = cff_index_get_sid_string( &cff->string_index,
602                                                    dict->weight,
603                                                    psnames );
604
605
606          if ( weight )
607            if ( !ft_strcmp( weight, "Bold"  ) ||
608                 !ft_strcmp( weight, "Black" ) )
609              flags |= FT_STYLE_FLAG_BOLD;
610          FT_FREE( weight );
611        }
612
613        /* double check */
614        if ( !(flags & FT_STYLE_FLAG_BOLD) && cffface->style_name )
615          if ( !ft_strncmp( cffface->style_name, "Bold", 4 )  ||
616               !ft_strncmp( cffface->style_name, "Black", 5 ) )
617            flags |= FT_STYLE_FLAG_BOLD;
618
619        cffface->style_flags = flags;
620      }
621      else
622      {
623        if ( !dict->units_per_em )
624          dict->units_per_em = face->root.units_per_EM;
625      }
626
627      /* handle font matrix settings in subfonts (if any) */
628      for ( i = cff->num_subfonts; i > 0; i-- )
629      {
630        CFF_FontRecDict  sub = &cff->subfonts[i - 1]->font_dict;
631        CFF_FontRecDict  top = &cff->top_font.font_dict;
632
633
634        if ( sub->units_per_em )
635        {
636          FT_Matrix  scale;
637
638
639          scale.xx = scale.yy = (FT_Fixed)FT_DivFix( top->units_per_em,
640                                                     sub->units_per_em );
641          scale.xy = scale.yx = 0;
642
643          FT_Matrix_Multiply( &scale, &sub->font_matrix );
644          FT_Vector_Transform( &sub->font_offset, &scale );
645        }
646        else
647        {
648          sub->font_matrix = top->font_matrix;
649          sub->font_offset = top->font_offset;
650        }
651      }
652
653#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
654      /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */
655      /* has unset this flag because of the 3.0 `post' table           */
656      if ( dict->cid_registry == 0xFFFFU )
657        cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES;
658#endif
659
660      /*******************************************************************/
661      /*                                                                 */
662      /* Compute char maps.                                              */
663      /*                                                                 */
664
665      /* Try to synthetize a Unicode charmap if there is none available */
666      /* already.  If an OpenType font contains a Unicode "cmap", we    */
667      /* will use it, whatever be in the CFF part of the file.          */
668      {
669        FT_CharMapRec  cmaprec;
670        FT_CharMap     cmap;
671        FT_UInt        nn;
672        CFF_Encoding   encoding = &cff->encoding;
673
674
675        for ( nn = 0; nn < (FT_UInt)cffface->num_charmaps; nn++ )
676        {
677          cmap = cffface->charmaps[nn];
678
679          /* Windows Unicode (3,1)? */
680          if ( cmap->platform_id == 3 && cmap->encoding_id == 1 )
681            goto Skip_Unicode;
682
683          /* Deprecated Unicode platform id? */
684          if ( cmap->platform_id == 0 )
685            goto Skip_Unicode; /* Standard Unicode (deprecated) */
686        }
687
688        /* since CID-keyed fonts don't contain glyph names, we can't */
689        /* construct a cmap                                          */
690        if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU )
691          goto Exit;
692
693        /* we didn't find a Unicode charmap -- synthetize one */
694        cmaprec.face        = cffface;
695        cmaprec.platform_id = 3;
696        cmaprec.encoding_id = 1;
697        cmaprec.encoding    = FT_ENCODING_UNICODE;
698
699        nn = (FT_UInt)cffface->num_charmaps;
700
701        FT_CMap_New( &cff_cmap_unicode_class_rec, NULL, &cmaprec, NULL );
702
703        /* if no Unicode charmap was previously selected, select this one */
704        if ( cffface->charmap == NULL && nn != (FT_UInt)cffface->num_charmaps )
705          cffface->charmap = cffface->charmaps[nn];
706
707      Skip_Unicode:
708        if ( encoding->count > 0 )
709        {
710          FT_CMap_Class  clazz;
711
712
713          cmaprec.face        = cffface;
714          cmaprec.platform_id = 7;  /* Adobe platform id */
715
716          if ( encoding->offset == 0 )
717          {
718            cmaprec.encoding_id = TT_ADOBE_ID_STANDARD;
719            cmaprec.encoding    = FT_ENCODING_ADOBE_STANDARD;
720            clazz               = &cff_cmap_encoding_class_rec;
721          }
722          else if ( encoding->offset == 1 )
723          {
724            cmaprec.encoding_id = TT_ADOBE_ID_EXPERT;
725            cmaprec.encoding    = FT_ENCODING_ADOBE_EXPERT;
726            clazz               = &cff_cmap_encoding_class_rec;
727          }
728          else
729          {
730            cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM;
731            cmaprec.encoding    = FT_ENCODING_ADOBE_CUSTOM;
732            clazz               = &cff_cmap_encoding_class_rec;
733          }
734
735          FT_CMap_New( clazz, NULL, &cmaprec, NULL );
736        }
737      }
738    }
739
740  Exit:
741    return error;
742
743  Bad_Format:
744    error = CFF_Err_Unknown_File_Format;
745    goto Exit;
746  }
747
748
749  FT_LOCAL_DEF( void )
750  cff_face_done( FT_Face  cffface )         /* CFF_Face */
751  {
752    CFF_Face      face   = (CFF_Face)cffface;
753    FT_Memory     memory = cffface->memory;
754    SFNT_Service  sfnt   = (SFNT_Service)face->sfnt;
755
756
757    if ( sfnt )
758      sfnt->done_face( face );
759
760    {
761      CFF_Font  cff = (CFF_Font)face->extra.data;
762
763
764      if ( cff )
765      {
766        cff_font_done( cff );
767        FT_FREE( face->extra.data );
768      }
769    }
770  }
771
772
773  FT_LOCAL_DEF( FT_Error )
774  cff_driver_init( FT_Module  module )
775  {
776    FT_UNUSED( module );
777
778    return CFF_Err_Ok;
779  }
780
781
782  FT_LOCAL_DEF( void )
783  cff_driver_done( FT_Module  module )
784  {
785    FT_UNUSED( module );
786  }
787
788
789/* END */
Note: See TracBrowser for help on using the repository browser.