xref: /inferno-os/libfreetype/cffobjs.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsyth /***************************************************************************/
2*37da2899SCharles.Forsyth /*                                                                         */
3*37da2899SCharles.Forsyth /*  cffobjs.c                                                              */
4*37da2899SCharles.Forsyth /*                                                                         */
5*37da2899SCharles.Forsyth /*    OpenType objects manager (body).                                     */
6*37da2899SCharles.Forsyth /*                                                                         */
7*37da2899SCharles.Forsyth /*  Copyright 1996-2001, 2002 by                                           */
8*37da2899SCharles.Forsyth /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9*37da2899SCharles.Forsyth /*                                                                         */
10*37da2899SCharles.Forsyth /*  This file is part of the FreeType project, and may only be used,       */
11*37da2899SCharles.Forsyth /*  modified, and distributed under the terms of the FreeType project      */
12*37da2899SCharles.Forsyth /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13*37da2899SCharles.Forsyth /*  this file you indicate that you have read the license and              */
14*37da2899SCharles.Forsyth /*  understand and accept it fully.                                        */
15*37da2899SCharles.Forsyth /*                                                                         */
16*37da2899SCharles.Forsyth /***************************************************************************/
17*37da2899SCharles.Forsyth 
18*37da2899SCharles.Forsyth 
19*37da2899SCharles.Forsyth #include <ft2build.h>
20*37da2899SCharles.Forsyth #include FT_INTERNAL_DEBUG_H
21*37da2899SCharles.Forsyth #include FT_INTERNAL_CALC_H
22*37da2899SCharles.Forsyth #include FT_INTERNAL_STREAM_H
23*37da2899SCharles.Forsyth #include FT_ERRORS_H
24*37da2899SCharles.Forsyth #include FT_TRUETYPE_IDS_H
25*37da2899SCharles.Forsyth #include FT_TRUETYPE_TAGS_H
26*37da2899SCharles.Forsyth #include FT_INTERNAL_SFNT_H
27*37da2899SCharles.Forsyth #include FT_INTERNAL_POSTSCRIPT_NAMES_H
28*37da2899SCharles.Forsyth #include FT_INTERNAL_POSTSCRIPT_HINTS_H
29*37da2899SCharles.Forsyth #include "cffobjs.h"
30*37da2899SCharles.Forsyth #include "cffload.h"
31*37da2899SCharles.Forsyth #include "cffcmap.h"
32*37da2899SCharles.Forsyth #include "cfferrs.h"
33*37da2899SCharles.Forsyth 
34*37da2899SCharles.Forsyth 
35*37da2899SCharles.Forsyth   /*************************************************************************/
36*37da2899SCharles.Forsyth   /*                                                                       */
37*37da2899SCharles.Forsyth   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
38*37da2899SCharles.Forsyth   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
39*37da2899SCharles.Forsyth   /* messages during execution.                                            */
40*37da2899SCharles.Forsyth   /*                                                                       */
41*37da2899SCharles.Forsyth #undef  FT_COMPONENT
42*37da2899SCharles.Forsyth #define FT_COMPONENT  trace_cffobjs
43*37da2899SCharles.Forsyth 
44*37da2899SCharles.Forsyth 
45*37da2899SCharles.Forsyth   /*************************************************************************/
46*37da2899SCharles.Forsyth   /*                                                                       */
47*37da2899SCharles.Forsyth   /*                            SIZE FUNCTIONS                             */
48*37da2899SCharles.Forsyth   /*                                                                       */
49*37da2899SCharles.Forsyth   /*  Note that we store the global hints in the size's "internal" root    */
50*37da2899SCharles.Forsyth   /*  field.                                                               */
51*37da2899SCharles.Forsyth   /*                                                                       */
52*37da2899SCharles.Forsyth   /*************************************************************************/
53*37da2899SCharles.Forsyth 
54*37da2899SCharles.Forsyth 
55*37da2899SCharles.Forsyth   static PSH_Globals_Funcs
cff_size_get_globals_funcs(CFF_Size size)56*37da2899SCharles.Forsyth   cff_size_get_globals_funcs( CFF_Size  size )
57*37da2899SCharles.Forsyth   {
58*37da2899SCharles.Forsyth     CFF_Face          face     = (CFF_Face)size->face;
59*37da2899SCharles.Forsyth     CFF_Font          font     = (CFF_FontRec *)face->extra.data;
60*37da2899SCharles.Forsyth     PSHinter_Service  pshinter = (PSHinter_Service)font->pshinter;
61*37da2899SCharles.Forsyth     FT_Module         module;
62*37da2899SCharles.Forsyth 
63*37da2899SCharles.Forsyth 
64*37da2899SCharles.Forsyth     module = FT_Get_Module( size->face->driver->root.library,
65*37da2899SCharles.Forsyth                             "pshinter" );
66*37da2899SCharles.Forsyth     return ( module && pshinter && pshinter->get_globals_funcs )
67*37da2899SCharles.Forsyth            ? pshinter->get_globals_funcs( module )
68*37da2899SCharles.Forsyth            : 0;
69*37da2899SCharles.Forsyth   }
70*37da2899SCharles.Forsyth 
71*37da2899SCharles.Forsyth 
72*37da2899SCharles.Forsyth   FT_LOCAL_DEF( void )
cff_size_done(CFF_Size size)73*37da2899SCharles.Forsyth   cff_size_done( CFF_Size  size )
74*37da2899SCharles.Forsyth   {
75*37da2899SCharles.Forsyth     if ( size->internal )
76*37da2899SCharles.Forsyth     {
77*37da2899SCharles.Forsyth       PSH_Globals_Funcs  funcs;
78*37da2899SCharles.Forsyth 
79*37da2899SCharles.Forsyth 
80*37da2899SCharles.Forsyth       funcs = cff_size_get_globals_funcs( size );
81*37da2899SCharles.Forsyth       if ( funcs )
82*37da2899SCharles.Forsyth         funcs->destroy( (PSH_Globals)size->internal );
83*37da2899SCharles.Forsyth 
84*37da2899SCharles.Forsyth       size->internal = 0;
85*37da2899SCharles.Forsyth     }
86*37da2899SCharles.Forsyth   }
87*37da2899SCharles.Forsyth 
88*37da2899SCharles.Forsyth 
89*37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Error )
cff_size_init(CFF_Size size)90*37da2899SCharles.Forsyth   cff_size_init( CFF_Size  size )
91*37da2899SCharles.Forsyth   {
92*37da2899SCharles.Forsyth     FT_Error           error = 0;
93*37da2899SCharles.Forsyth     PSH_Globals_Funcs  funcs = cff_size_get_globals_funcs( size );
94*37da2899SCharles.Forsyth 
95*37da2899SCharles.Forsyth 
96*37da2899SCharles.Forsyth     if ( funcs )
97*37da2899SCharles.Forsyth     {
98*37da2899SCharles.Forsyth       PSH_Globals    globals;
99*37da2899SCharles.Forsyth       CFF_Face       face    = (CFF_Face)size->face;
100*37da2899SCharles.Forsyth       CFF_Font       font    = (CFF_FontRec *)face->extra.data;
101*37da2899SCharles.Forsyth       CFF_SubFont    subfont = &font->top_font;
102*37da2899SCharles.Forsyth 
103*37da2899SCharles.Forsyth       CFF_Private    cpriv   = &subfont->private_dict;
104*37da2899SCharles.Forsyth       PS_PrivateRec  priv;
105*37da2899SCharles.Forsyth 
106*37da2899SCharles.Forsyth 
107*37da2899SCharles.Forsyth       /* IMPORTANT: The CFF and Type1 private dictionaries have    */
108*37da2899SCharles.Forsyth       /*            slightly different structures; we need to      */
109*37da2899SCharles.Forsyth       /*            synthetize a type1 dictionary on the fly here. */
110*37da2899SCharles.Forsyth 
111*37da2899SCharles.Forsyth       {
112*37da2899SCharles.Forsyth         FT_UInt  n, count;
113*37da2899SCharles.Forsyth 
114*37da2899SCharles.Forsyth 
115*37da2899SCharles.Forsyth         FT_MEM_ZERO( &priv, sizeof ( priv ) );
116*37da2899SCharles.Forsyth 
117*37da2899SCharles.Forsyth         count = priv.num_blue_values = cpriv->num_blue_values;
118*37da2899SCharles.Forsyth         for ( n = 0; n < count; n++ )
119*37da2899SCharles.Forsyth           priv.blue_values[n] = (FT_Short)cpriv->blue_values[n];
120*37da2899SCharles.Forsyth 
121*37da2899SCharles.Forsyth         count = priv.num_other_blues = cpriv->num_other_blues;
122*37da2899SCharles.Forsyth         for ( n = 0; n < count; n++ )
123*37da2899SCharles.Forsyth           priv.other_blues[n] = (FT_Short)cpriv->other_blues[n];
124*37da2899SCharles.Forsyth 
125*37da2899SCharles.Forsyth         count = priv.num_family_blues = cpriv->num_family_blues;
126*37da2899SCharles.Forsyth         for ( n = 0; n < count; n++ )
127*37da2899SCharles.Forsyth           priv.family_blues[n] = (FT_Short)cpriv->family_blues[n];
128*37da2899SCharles.Forsyth 
129*37da2899SCharles.Forsyth         count = priv.num_family_other_blues = cpriv->num_family_other_blues;
130*37da2899SCharles.Forsyth         for ( n = 0; n < count; n++ )
131*37da2899SCharles.Forsyth           priv.family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n];
132*37da2899SCharles.Forsyth 
133*37da2899SCharles.Forsyth         priv.blue_scale = cpriv->blue_scale;
134*37da2899SCharles.Forsyth         priv.blue_shift = (FT_Int)cpriv->blue_shift;
135*37da2899SCharles.Forsyth         priv.blue_fuzz  = (FT_Int)cpriv->blue_fuzz;
136*37da2899SCharles.Forsyth 
137*37da2899SCharles.Forsyth         priv.standard_width[0]  = (FT_UShort)cpriv->standard_width;
138*37da2899SCharles.Forsyth         priv.standard_height[0] = (FT_UShort)cpriv->standard_height;
139*37da2899SCharles.Forsyth 
140*37da2899SCharles.Forsyth         count = priv.num_snap_widths = cpriv->num_snap_widths;
141*37da2899SCharles.Forsyth         for ( n = 0; n < count; n++ )
142*37da2899SCharles.Forsyth           priv.snap_widths[n] = (FT_Short)cpriv->snap_widths[n];
143*37da2899SCharles.Forsyth 
144*37da2899SCharles.Forsyth         count = priv.num_snap_heights = cpriv->num_snap_heights;
145*37da2899SCharles.Forsyth         for ( n = 0; n < count; n++ )
146*37da2899SCharles.Forsyth           priv.snap_heights[n] = (FT_Short)cpriv->snap_heights[n];
147*37da2899SCharles.Forsyth 
148*37da2899SCharles.Forsyth         priv.force_bold     = cpriv->force_bold;
149*37da2899SCharles.Forsyth         priv.language_group = cpriv->language_group;
150*37da2899SCharles.Forsyth         priv.lenIV          = cpriv->lenIV;
151*37da2899SCharles.Forsyth       }
152*37da2899SCharles.Forsyth 
153*37da2899SCharles.Forsyth       error = funcs->create( size->face->memory, &priv, &globals );
154*37da2899SCharles.Forsyth       if ( !error )
155*37da2899SCharles.Forsyth         size->internal = (FT_Size_Internal)(void*)globals;
156*37da2899SCharles.Forsyth     }
157*37da2899SCharles.Forsyth 
158*37da2899SCharles.Forsyth     return error;
159*37da2899SCharles.Forsyth   }
160*37da2899SCharles.Forsyth 
161*37da2899SCharles.Forsyth 
162*37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Error )
cff_size_reset(CFF_Size size)163*37da2899SCharles.Forsyth   cff_size_reset( CFF_Size  size )
164*37da2899SCharles.Forsyth   {
165*37da2899SCharles.Forsyth     PSH_Globals_Funcs  funcs = cff_size_get_globals_funcs( size );
166*37da2899SCharles.Forsyth     FT_Error           error = 0;
167*37da2899SCharles.Forsyth 
168*37da2899SCharles.Forsyth 
169*37da2899SCharles.Forsyth     if ( funcs )
170*37da2899SCharles.Forsyth       error = funcs->set_scale( (PSH_Globals)size->internal,
171*37da2899SCharles.Forsyth                                  size->metrics.x_scale,
172*37da2899SCharles.Forsyth                                  size->metrics.y_scale,
173*37da2899SCharles.Forsyth                                  0, 0 );
174*37da2899SCharles.Forsyth     return error;
175*37da2899SCharles.Forsyth   }
176*37da2899SCharles.Forsyth 
177*37da2899SCharles.Forsyth 
178*37da2899SCharles.Forsyth   /*************************************************************************/
179*37da2899SCharles.Forsyth   /*                                                                       */
180*37da2899SCharles.Forsyth   /*                            SLOT  FUNCTIONS                            */
181*37da2899SCharles.Forsyth   /*                                                                       */
182*37da2899SCharles.Forsyth   /*************************************************************************/
183*37da2899SCharles.Forsyth 
184*37da2899SCharles.Forsyth   FT_LOCAL_DEF( void )
cff_slot_done(CFF_GlyphSlot slot)185*37da2899SCharles.Forsyth   cff_slot_done( CFF_GlyphSlot  slot )
186*37da2899SCharles.Forsyth   {
187*37da2899SCharles.Forsyth     slot->root.internal->glyph_hints = 0;
188*37da2899SCharles.Forsyth   }
189*37da2899SCharles.Forsyth 
190*37da2899SCharles.Forsyth 
191*37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Error )
cff_slot_init(CFF_GlyphSlot slot)192*37da2899SCharles.Forsyth   cff_slot_init( CFF_GlyphSlot  slot )
193*37da2899SCharles.Forsyth   {
194*37da2899SCharles.Forsyth     CFF_Face          face     = (CFF_Face)slot->root.face;
195*37da2899SCharles.Forsyth     CFF_Font          font     = (CFF_FontRec *)face->extra.data;
196*37da2899SCharles.Forsyth     PSHinter_Service  pshinter = (PSHinter_Service)font->pshinter;
197*37da2899SCharles.Forsyth 
198*37da2899SCharles.Forsyth 
199*37da2899SCharles.Forsyth     if ( pshinter )
200*37da2899SCharles.Forsyth     {
201*37da2899SCharles.Forsyth       FT_Module  module;
202*37da2899SCharles.Forsyth 
203*37da2899SCharles.Forsyth 
204*37da2899SCharles.Forsyth       module = FT_Get_Module( slot->root.face->driver->root.library,
205*37da2899SCharles.Forsyth                               "pshinter" );
206*37da2899SCharles.Forsyth       if ( module )
207*37da2899SCharles.Forsyth       {
208*37da2899SCharles.Forsyth         T2_Hints_Funcs  funcs;
209*37da2899SCharles.Forsyth 
210*37da2899SCharles.Forsyth 
211*37da2899SCharles.Forsyth         funcs = pshinter->get_t2_funcs( module );
212*37da2899SCharles.Forsyth         slot->root.internal->glyph_hints = (void*)funcs;
213*37da2899SCharles.Forsyth       }
214*37da2899SCharles.Forsyth     }
215*37da2899SCharles.Forsyth 
216*37da2899SCharles.Forsyth     return 0;
217*37da2899SCharles.Forsyth   }
218*37da2899SCharles.Forsyth 
219*37da2899SCharles.Forsyth 
220*37da2899SCharles.Forsyth   /*************************************************************************/
221*37da2899SCharles.Forsyth   /*                                                                       */
222*37da2899SCharles.Forsyth   /*                           FACE  FUNCTIONS                             */
223*37da2899SCharles.Forsyth   /*                                                                       */
224*37da2899SCharles.Forsyth   /*************************************************************************/
225*37da2899SCharles.Forsyth 
226*37da2899SCharles.Forsyth   static FT_String*
cff_strcpy(FT_Memory memory,const FT_String * source)227*37da2899SCharles.Forsyth   cff_strcpy( FT_Memory         memory,
228*37da2899SCharles.Forsyth               const FT_String*  source )
229*37da2899SCharles.Forsyth   {
230*37da2899SCharles.Forsyth     FT_Error    error;
231*37da2899SCharles.Forsyth     FT_String*  result = 0;
232*37da2899SCharles.Forsyth     FT_Int      len = (FT_Int)ft_strlen( source );
233*37da2899SCharles.Forsyth 
234*37da2899SCharles.Forsyth 
235*37da2899SCharles.Forsyth     if ( !FT_ALLOC( result, len + 1 ) )
236*37da2899SCharles.Forsyth     {
237*37da2899SCharles.Forsyth       FT_MEM_COPY( result, source, len );
238*37da2899SCharles.Forsyth       result[len] = 0;
239*37da2899SCharles.Forsyth     }
240*37da2899SCharles.Forsyth 
241*37da2899SCharles.Forsyth     FT_UNUSED( error );
242*37da2899SCharles.Forsyth 
243*37da2899SCharles.Forsyth     return result;
244*37da2899SCharles.Forsyth   }
245*37da2899SCharles.Forsyth 
246*37da2899SCharles.Forsyth 
247*37da2899SCharles.Forsyth 
248*37da2899SCharles.Forsyth 
249*37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Error )
cff_face_init(FT_Stream stream,CFF_Face face,FT_Int face_index,FT_Int num_params,FT_Parameter * params)250*37da2899SCharles.Forsyth   cff_face_init( FT_Stream      stream,
251*37da2899SCharles.Forsyth                  CFF_Face       face,
252*37da2899SCharles.Forsyth                  FT_Int         face_index,
253*37da2899SCharles.Forsyth                  FT_Int         num_params,
254*37da2899SCharles.Forsyth                  FT_Parameter*  params )
255*37da2899SCharles.Forsyth   {
256*37da2899SCharles.Forsyth     FT_Error          error;
257*37da2899SCharles.Forsyth     SFNT_Service      sfnt;
258*37da2899SCharles.Forsyth     PSNames_Service   psnames;
259*37da2899SCharles.Forsyth     PSHinter_Service  pshinter;
260*37da2899SCharles.Forsyth     FT_Bool           pure_cff    = 1;
261*37da2899SCharles.Forsyth     FT_Bool           sfnt_format = 0;
262*37da2899SCharles.Forsyth 
263*37da2899SCharles.Forsyth 
264*37da2899SCharles.Forsyth     sfnt = (SFNT_Service)FT_Get_Module_Interface(
265*37da2899SCharles.Forsyth              face->root.driver->root.library, "sfnt" );
266*37da2899SCharles.Forsyth     if ( !sfnt )
267*37da2899SCharles.Forsyth       goto Bad_Format;
268*37da2899SCharles.Forsyth 
269*37da2899SCharles.Forsyth     psnames = (PSNames_Service)FT_Get_Module_Interface(
270*37da2899SCharles.Forsyth                 face->root.driver->root.library, "psnames" );
271*37da2899SCharles.Forsyth 
272*37da2899SCharles.Forsyth     pshinter = (PSHinter_Service)FT_Get_Module_Interface(
273*37da2899SCharles.Forsyth                  face->root.driver->root.library, "pshinter" );
274*37da2899SCharles.Forsyth 
275*37da2899SCharles.Forsyth     /* create input stream from resource */
276*37da2899SCharles.Forsyth     if ( FT_STREAM_SEEK( 0 ) )
277*37da2899SCharles.Forsyth       goto Exit;
278*37da2899SCharles.Forsyth 
279*37da2899SCharles.Forsyth     /* check that we have a valid OpenType file */
280*37da2899SCharles.Forsyth     error = sfnt->init_face( stream, face, face_index, num_params, params );
281*37da2899SCharles.Forsyth     if ( !error )
282*37da2899SCharles.Forsyth     {
283*37da2899SCharles.Forsyth       if ( face->format_tag != 0x4F54544FL )  /* `OTTO'; OpenType/CFF font */
284*37da2899SCharles.Forsyth       {
285*37da2899SCharles.Forsyth         FT_TRACE2(( "[not a valid OpenType/CFF font]\n" ));
286*37da2899SCharles.Forsyth         goto Bad_Format;
287*37da2899SCharles.Forsyth       }
288*37da2899SCharles.Forsyth 
289*37da2899SCharles.Forsyth       /* if we are performing a simple font format check, exit immediately */
290*37da2899SCharles.Forsyth       if ( face_index < 0 )
291*37da2899SCharles.Forsyth         return CFF_Err_Ok;
292*37da2899SCharles.Forsyth 
293*37da2899SCharles.Forsyth       sfnt_format = 1;
294*37da2899SCharles.Forsyth 
295*37da2899SCharles.Forsyth       /* now, the font can be either an OpenType/CFF font, or an SVG CEF */
296*37da2899SCharles.Forsyth       /* font in the later case; it doesn't have a `head' table          */
297*37da2899SCharles.Forsyth       error = face->goto_table( face, TTAG_head, stream, 0 );
298*37da2899SCharles.Forsyth       if ( !error )
299*37da2899SCharles.Forsyth       {
300*37da2899SCharles.Forsyth         pure_cff = 0;
301*37da2899SCharles.Forsyth 
302*37da2899SCharles.Forsyth         /* load font directory */
303*37da2899SCharles.Forsyth         error = sfnt->load_face( stream, face,
304*37da2899SCharles.Forsyth                                  face_index, num_params, params );
305*37da2899SCharles.Forsyth         if ( error )
306*37da2899SCharles.Forsyth           goto Exit;
307*37da2899SCharles.Forsyth       }
308*37da2899SCharles.Forsyth       else
309*37da2899SCharles.Forsyth       {
310*37da2899SCharles.Forsyth         /* load the `cmap' table by hand */
311*37da2899SCharles.Forsyth         error = sfnt->load_charmaps( face, stream );
312*37da2899SCharles.Forsyth         if ( error )
313*37da2899SCharles.Forsyth           goto Exit;
314*37da2899SCharles.Forsyth 
315*37da2899SCharles.Forsyth         /* XXX: we don't load the GPOS table, as OpenType Layout     */
316*37da2899SCharles.Forsyth         /* support will be added later to a layout library on top of */
317*37da2899SCharles.Forsyth         /* FreeType 2                                                */
318*37da2899SCharles.Forsyth       }
319*37da2899SCharles.Forsyth 
320*37da2899SCharles.Forsyth       /* now, load the CFF part of the file */
321*37da2899SCharles.Forsyth       error = face->goto_table( face, TTAG_CFF, stream, 0 );
322*37da2899SCharles.Forsyth       if ( error )
323*37da2899SCharles.Forsyth         goto Exit;
324*37da2899SCharles.Forsyth     }
325*37da2899SCharles.Forsyth     else
326*37da2899SCharles.Forsyth     {
327*37da2899SCharles.Forsyth       /* rewind to start of file; we are going to load a pure-CFF font */
328*37da2899SCharles.Forsyth       if ( FT_STREAM_SEEK( 0 ) )
329*37da2899SCharles.Forsyth         goto Exit;
330*37da2899SCharles.Forsyth       error = CFF_Err_Ok;
331*37da2899SCharles.Forsyth     }
332*37da2899SCharles.Forsyth 
333*37da2899SCharles.Forsyth     /* now load and parse the CFF table in the file */
334*37da2899SCharles.Forsyth     {
335*37da2899SCharles.Forsyth       CFF_Font   cff;
336*37da2899SCharles.Forsyth       FT_Memory  memory = face->root.memory;
337*37da2899SCharles.Forsyth       FT_Face    root;
338*37da2899SCharles.Forsyth       FT_Int32   flags;
339*37da2899SCharles.Forsyth 
340*37da2899SCharles.Forsyth 
341*37da2899SCharles.Forsyth       if ( FT_NEW( cff ) )
342*37da2899SCharles.Forsyth         goto Exit;
343*37da2899SCharles.Forsyth 
344*37da2899SCharles.Forsyth       face->extra.data = cff;
345*37da2899SCharles.Forsyth       error = cff_font_load( stream, face_index, cff );
346*37da2899SCharles.Forsyth       if ( error )
347*37da2899SCharles.Forsyth         goto Exit;
348*37da2899SCharles.Forsyth 
349*37da2899SCharles.Forsyth       cff->pshinter = pshinter;
350*37da2899SCharles.Forsyth       cff->psnames  = psnames;
351*37da2899SCharles.Forsyth 
352*37da2899SCharles.Forsyth       /* Complement the root flags with some interesting information. */
353*37da2899SCharles.Forsyth       /* Note that this is only necessary for pure CFF and CEF fonts. */
354*37da2899SCharles.Forsyth 
355*37da2899SCharles.Forsyth       root             = &face->root;
356*37da2899SCharles.Forsyth       root->num_glyphs = cff->num_glyphs;
357*37da2899SCharles.Forsyth 
358*37da2899SCharles.Forsyth       if ( pure_cff )
359*37da2899SCharles.Forsyth       {
360*37da2899SCharles.Forsyth         CFF_FontRecDict  dict = &cff->top_font.font_dict;
361*37da2899SCharles.Forsyth 
362*37da2899SCharles.Forsyth 
363*37da2899SCharles.Forsyth         /* we need the `PSNames' module for pure-CFF and CEF formats */
364*37da2899SCharles.Forsyth         if ( !psnames )
365*37da2899SCharles.Forsyth         {
366*37da2899SCharles.Forsyth           FT_ERROR(( "cff_face_init:" ));
367*37da2899SCharles.Forsyth           FT_ERROR(( " cannot open CFF & CEF fonts\n" ));
368*37da2899SCharles.Forsyth           FT_ERROR(( "              " ));
369*37da2899SCharles.Forsyth           FT_ERROR(( " without the `PSNames' module\n" ));
370*37da2899SCharles.Forsyth           goto Bad_Format;
371*37da2899SCharles.Forsyth         }
372*37da2899SCharles.Forsyth 
373*37da2899SCharles.Forsyth         /* Set up num_faces. */
374*37da2899SCharles.Forsyth         root->num_faces = cff->num_faces;
375*37da2899SCharles.Forsyth 
376*37da2899SCharles.Forsyth         /* compute number of glyphs */
377*37da2899SCharles.Forsyth         if ( dict->cid_registry )
378*37da2899SCharles.Forsyth           root->num_glyphs = dict->cid_count;
379*37da2899SCharles.Forsyth         else
380*37da2899SCharles.Forsyth           root->num_glyphs = cff->charstrings_index.count;
381*37da2899SCharles.Forsyth 
382*37da2899SCharles.Forsyth         /* set global bbox, as well as EM size */
383*37da2899SCharles.Forsyth         root->bbox.xMin =   dict->font_bbox.xMin             >> 16;
384*37da2899SCharles.Forsyth         root->bbox.yMin =   dict->font_bbox.yMin             >> 16;
385*37da2899SCharles.Forsyth         root->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFFU ) >> 16;
386*37da2899SCharles.Forsyth         root->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFFU ) >> 16;
387*37da2899SCharles.Forsyth 
388*37da2899SCharles.Forsyth 
389*37da2899SCharles.Forsyth         root->ascender  = (FT_Short)( root->bbox.yMax );
390*37da2899SCharles.Forsyth         root->descender = (FT_Short)( root->bbox.yMin );
391*37da2899SCharles.Forsyth         root->height    = (FT_Short)(
392*37da2899SCharles.Forsyth           ( ( root->ascender - root->descender ) * 12 ) / 10 );
393*37da2899SCharles.Forsyth 
394*37da2899SCharles.Forsyth         if ( dict->units_per_em )
395*37da2899SCharles.Forsyth           root->units_per_EM = dict->units_per_em;
396*37da2899SCharles.Forsyth         else
397*37da2899SCharles.Forsyth           root->units_per_EM = 1000;
398*37da2899SCharles.Forsyth 
399*37da2899SCharles.Forsyth         /* retrieve font family & style name */
400*37da2899SCharles.Forsyth         root->family_name  = cff_index_get_name( &cff->name_index, face_index );
401*37da2899SCharles.Forsyth         if ( dict->cid_registry )
402*37da2899SCharles.Forsyth           root->style_name = cff_strcpy( memory, "Regular" );  /* XXXX */
403*37da2899SCharles.Forsyth         else
404*37da2899SCharles.Forsyth           root->style_name = cff_index_get_sid_string( &cff->string_index,
405*37da2899SCharles.Forsyth                                                        dict->weight,
406*37da2899SCharles.Forsyth                                                        psnames );
407*37da2899SCharles.Forsyth 
408*37da2899SCharles.Forsyth         /*******************************************************************/
409*37da2899SCharles.Forsyth         /*                                                                 */
410*37da2899SCharles.Forsyth         /* Compute face flags.                                             */
411*37da2899SCharles.Forsyth         /*                                                                 */
412*37da2899SCharles.Forsyth         flags = FT_FACE_FLAG_SCALABLE  |    /* scalable outlines */
413*37da2899SCharles.Forsyth                 FT_FACE_FLAG_HORIZONTAL;    /* horizontal data   */
414*37da2899SCharles.Forsyth 
415*37da2899SCharles.Forsyth         if ( sfnt_format )
416*37da2899SCharles.Forsyth           flags |= FT_FACE_FLAG_SFNT;
417*37da2899SCharles.Forsyth 
418*37da2899SCharles.Forsyth         /* fixed width font? */
419*37da2899SCharles.Forsyth         if ( dict->is_fixed_pitch )
420*37da2899SCharles.Forsyth           flags |= FT_FACE_FLAG_FIXED_WIDTH;
421*37da2899SCharles.Forsyth 
422*37da2899SCharles.Forsyth   /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */
423*37da2899SCharles.Forsyth #if 0
424*37da2899SCharles.Forsyth         /* kerning available? */
425*37da2899SCharles.Forsyth         if ( face->kern_pairs )
426*37da2899SCharles.Forsyth           flags |= FT_FACE_FLAG_KERNING;
427*37da2899SCharles.Forsyth #endif
428*37da2899SCharles.Forsyth 
429*37da2899SCharles.Forsyth #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
430*37da2899SCharles.Forsyth         flags |= FT_FACE_FLAG_GLYPH_NAMES;
431*37da2899SCharles.Forsyth #endif
432*37da2899SCharles.Forsyth 
433*37da2899SCharles.Forsyth         root->face_flags = flags;
434*37da2899SCharles.Forsyth 
435*37da2899SCharles.Forsyth         /*******************************************************************/
436*37da2899SCharles.Forsyth         /*                                                                 */
437*37da2899SCharles.Forsyth         /* Compute style flags.                                            */
438*37da2899SCharles.Forsyth         /*                                                                 */
439*37da2899SCharles.Forsyth         flags = 0;
440*37da2899SCharles.Forsyth 
441*37da2899SCharles.Forsyth         if ( dict->italic_angle )
442*37da2899SCharles.Forsyth           flags |= FT_STYLE_FLAG_ITALIC;
443*37da2899SCharles.Forsyth 
444*37da2899SCharles.Forsyth         /* XXX: may not be correct */
445*37da2899SCharles.Forsyth         if ( cff->top_font.private_dict.force_bold )
446*37da2899SCharles.Forsyth           flags |= FT_STYLE_FLAG_BOLD;
447*37da2899SCharles.Forsyth 
448*37da2899SCharles.Forsyth         root->style_flags = flags;
449*37da2899SCharles.Forsyth       }
450*37da2899SCharles.Forsyth 
451*37da2899SCharles.Forsyth       /*******************************************************************/
452*37da2899SCharles.Forsyth       /*                                                                 */
453*37da2899SCharles.Forsyth       /* Compute char maps.                                              */
454*37da2899SCharles.Forsyth       /*                                                                 */
455*37da2899SCharles.Forsyth 
456*37da2899SCharles.Forsyth       /* Try to synthetize a Unicode charmap if there is none available */
457*37da2899SCharles.Forsyth       /* already.  If an OpenType font contains a Unicode "cmap", we    */
458*37da2899SCharles.Forsyth       /* will use it, whatever be in the CFF part of the file.          */
459*37da2899SCharles.Forsyth       {
460*37da2899SCharles.Forsyth         FT_CharMapRec  cmaprec;
461*37da2899SCharles.Forsyth         FT_CharMap     cmap;
462*37da2899SCharles.Forsyth         FT_UInt        nn;
463*37da2899SCharles.Forsyth         CFF_Encoding   encoding = &cff->encoding;
464*37da2899SCharles.Forsyth 
465*37da2899SCharles.Forsyth 
466*37da2899SCharles.Forsyth         for ( nn = 0; nn < (FT_UInt) root->num_charmaps; nn++ )
467*37da2899SCharles.Forsyth         {
468*37da2899SCharles.Forsyth           cmap = root->charmaps[nn];
469*37da2899SCharles.Forsyth 
470*37da2899SCharles.Forsyth           /* Windows Unicode (3,1)? */
471*37da2899SCharles.Forsyth           if ( cmap->platform_id == 3 && cmap->encoding_id == 1 )
472*37da2899SCharles.Forsyth             goto Skip_Unicode;
473*37da2899SCharles.Forsyth 
474*37da2899SCharles.Forsyth           /* Deprecated Unicode platform id? */
475*37da2899SCharles.Forsyth           if ( cmap->platform_id == 0 )
476*37da2899SCharles.Forsyth             goto Skip_Unicode; /* Standard Unicode (deprecated) */
477*37da2899SCharles.Forsyth         }
478*37da2899SCharles.Forsyth 
479*37da2899SCharles.Forsyth         /* we didn't find a Unicode charmap, synthetize one */
480*37da2899SCharles.Forsyth         cmaprec.face        = root;
481*37da2899SCharles.Forsyth         cmaprec.platform_id = 3;
482*37da2899SCharles.Forsyth         cmaprec.encoding_id = 1;
483*37da2899SCharles.Forsyth         cmaprec.encoding    = FT_ENCODING_UNICODE;
484*37da2899SCharles.Forsyth 
485*37da2899SCharles.Forsyth         nn = (FT_UInt) root->num_charmaps;
486*37da2899SCharles.Forsyth 
487*37da2899SCharles.Forsyth         FT_CMap_New( &cff_cmap_unicode_class_rec, NULL, &cmaprec, NULL );
488*37da2899SCharles.Forsyth 
489*37da2899SCharles.Forsyth         /* if no Unicode charmap was previously selected, select this one */
490*37da2899SCharles.Forsyth         if ( root->charmap == NULL && nn != (FT_UInt) root->num_charmaps )
491*37da2899SCharles.Forsyth           root->charmap = root->charmaps[nn];
492*37da2899SCharles.Forsyth 
493*37da2899SCharles.Forsyth       Skip_Unicode:
494*37da2899SCharles.Forsyth         if ( encoding->count > 0 )
495*37da2899SCharles.Forsyth         {
496*37da2899SCharles.Forsyth           FT_CMap_Class  clazz;
497*37da2899SCharles.Forsyth 
498*37da2899SCharles.Forsyth 
499*37da2899SCharles.Forsyth           cmaprec.face        = root;
500*37da2899SCharles.Forsyth           cmaprec.platform_id = 7;  /* Adobe platform id */
501*37da2899SCharles.Forsyth 
502*37da2899SCharles.Forsyth           if ( encoding->offset == 0 )
503*37da2899SCharles.Forsyth           {
504*37da2899SCharles.Forsyth             cmaprec.encoding_id = 0;
505*37da2899SCharles.Forsyth             cmaprec.encoding    = FT_ENCODING_ADOBE_STANDARD;
506*37da2899SCharles.Forsyth             clazz               = &cff_cmap_encoding_class_rec;
507*37da2899SCharles.Forsyth           }
508*37da2899SCharles.Forsyth           else if ( encoding->offset == 1 )
509*37da2899SCharles.Forsyth           {
510*37da2899SCharles.Forsyth             cmaprec.encoding_id = 1;
511*37da2899SCharles.Forsyth             cmaprec.encoding    = FT_ENCODING_ADOBE_EXPERT;
512*37da2899SCharles.Forsyth             clazz               = &cff_cmap_encoding_class_rec;
513*37da2899SCharles.Forsyth           }
514*37da2899SCharles.Forsyth           else
515*37da2899SCharles.Forsyth           {
516*37da2899SCharles.Forsyth             cmaprec.encoding_id = 3;
517*37da2899SCharles.Forsyth             cmaprec.encoding    = FT_ENCODING_ADOBE_CUSTOM;
518*37da2899SCharles.Forsyth             clazz               = &cff_cmap_encoding_class_rec;
519*37da2899SCharles.Forsyth           }
520*37da2899SCharles.Forsyth 
521*37da2899SCharles.Forsyth           FT_CMap_New( clazz, NULL, &cmaprec, NULL );
522*37da2899SCharles.Forsyth         }
523*37da2899SCharles.Forsyth 
524*37da2899SCharles.Forsyth       }
525*37da2899SCharles.Forsyth     }
526*37da2899SCharles.Forsyth 
527*37da2899SCharles.Forsyth   Exit:
528*37da2899SCharles.Forsyth     return error;
529*37da2899SCharles.Forsyth 
530*37da2899SCharles.Forsyth   Bad_Format:
531*37da2899SCharles.Forsyth     error = CFF_Err_Unknown_File_Format;
532*37da2899SCharles.Forsyth     goto Exit;
533*37da2899SCharles.Forsyth   }
534*37da2899SCharles.Forsyth 
535*37da2899SCharles.Forsyth 
536*37da2899SCharles.Forsyth   FT_LOCAL_DEF( void )
cff_face_done(CFF_Face face)537*37da2899SCharles.Forsyth   cff_face_done( CFF_Face  face )
538*37da2899SCharles.Forsyth   {
539*37da2899SCharles.Forsyth     FT_Memory     memory = face->root.memory;
540*37da2899SCharles.Forsyth     SFNT_Service  sfnt   = (SFNT_Service)face->sfnt;
541*37da2899SCharles.Forsyth 
542*37da2899SCharles.Forsyth 
543*37da2899SCharles.Forsyth     if ( sfnt )
544*37da2899SCharles.Forsyth       sfnt->done_face( face );
545*37da2899SCharles.Forsyth 
546*37da2899SCharles.Forsyth     {
547*37da2899SCharles.Forsyth       CFF_Font  cff = (CFF_Font)face->extra.data;
548*37da2899SCharles.Forsyth 
549*37da2899SCharles.Forsyth 
550*37da2899SCharles.Forsyth       if ( cff )
551*37da2899SCharles.Forsyth       {
552*37da2899SCharles.Forsyth         cff_font_done( cff );
553*37da2899SCharles.Forsyth         FT_FREE( face->extra.data );
554*37da2899SCharles.Forsyth       }
555*37da2899SCharles.Forsyth     }
556*37da2899SCharles.Forsyth   }
557*37da2899SCharles.Forsyth 
558*37da2899SCharles.Forsyth 
559*37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Error )
cff_driver_init(CFF_Driver driver)560*37da2899SCharles.Forsyth   cff_driver_init( CFF_Driver  driver )
561*37da2899SCharles.Forsyth   {
562*37da2899SCharles.Forsyth     FT_UNUSED( driver );
563*37da2899SCharles.Forsyth 
564*37da2899SCharles.Forsyth     return CFF_Err_Ok;
565*37da2899SCharles.Forsyth   }
566*37da2899SCharles.Forsyth 
567*37da2899SCharles.Forsyth 
568*37da2899SCharles.Forsyth   FT_LOCAL_DEF( void )
cff_driver_done(CFF_Driver driver)569*37da2899SCharles.Forsyth   cff_driver_done( CFF_Driver  driver )
570*37da2899SCharles.Forsyth   {
571*37da2899SCharles.Forsyth     FT_UNUSED( driver );
572*37da2899SCharles.Forsyth   }
573*37da2899SCharles.Forsyth 
574*37da2899SCharles.Forsyth 
575*37da2899SCharles.Forsyth /* END */
576