xref: /inferno-os/libfreetype/cidobjs.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1 /***************************************************************************/
2 /*                                                                         */
3 /*  cidobjs.c                                                              */
4 /*                                                                         */
5 /*    CID objects manager (body).                                          */
6 /*                                                                         */
7 /*  Copyright 1996-2001, 2002 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_STREAM_H
22 #include "cidgload.h"
23 #include "cidload.h"
24 #include FT_INTERNAL_POSTSCRIPT_NAMES_H
25 #include FT_INTERNAL_POSTSCRIPT_AUX_H
26 #include FT_INTERNAL_POSTSCRIPT_HINTS_H
27 
28 #include "ciderrs.h"
29 
30 
31   /*************************************************************************/
32   /*                                                                       */
33   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
34   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
35   /* messages during execution.                                            */
36   /*                                                                       */
37 #undef  FT_COMPONENT
38 #define FT_COMPONENT  trace_cidobjs
39 
40 
41   /*************************************************************************/
42   /*                                                                       */
43   /*                            SLOT  FUNCTIONS                            */
44   /*                                                                       */
45   /*************************************************************************/
46 
47   FT_LOCAL_DEF( void )
cid_slot_done(CID_GlyphSlot slot)48   cid_slot_done( CID_GlyphSlot  slot )
49   {
50     slot->root.internal->glyph_hints = 0;
51   }
52 
53 
54   FT_LOCAL_DEF( FT_Error )
cid_slot_init(CID_GlyphSlot slot)55   cid_slot_init( CID_GlyphSlot  slot )
56   {
57     CID_Face          face;
58     PSHinter_Service  pshinter;
59 
60 
61     face     = (CID_Face)slot->root.face;
62     pshinter = (PSHinter_Service)face->pshinter;
63 
64     if ( pshinter )
65     {
66       FT_Module  module;
67 
68 
69       module = FT_Get_Module( slot->root.face->driver->root.library,
70                               "pshinter" );
71       if ( module )
72       {
73         T1_Hints_Funcs  funcs;
74 
75 
76         funcs = pshinter->get_t1_funcs( module );
77         slot->root.internal->glyph_hints = (void*)funcs;
78       }
79     }
80 
81     return 0;
82   }
83 
84 
85   /*************************************************************************/
86   /*                                                                       */
87   /*                           SIZE  FUNCTIONS                             */
88   /*                                                                       */
89   /*************************************************************************/
90 
91 
92   static PSH_Globals_Funcs
cid_size_get_globals_funcs(CID_Size size)93   cid_size_get_globals_funcs( CID_Size  size )
94   {
95     CID_Face          face     = (CID_Face)size->root.face;
96     PSHinter_Service  pshinter = (PSHinter_Service)face->pshinter;
97     FT_Module         module;
98 
99 
100     module = FT_Get_Module( size->root.face->driver->root.library,
101                             "pshinter" );
102     return ( module && pshinter && pshinter->get_globals_funcs )
103            ? pshinter->get_globals_funcs( module )
104            : 0;
105   }
106 
107 
108   FT_LOCAL_DEF( void )
cid_size_done(CID_Size size)109   cid_size_done( CID_Size  size )
110   {
111     if ( size->root.internal )
112     {
113       PSH_Globals_Funcs  funcs;
114 
115 
116       funcs = cid_size_get_globals_funcs( size );
117       if ( funcs )
118         funcs->destroy( (PSH_Globals)size->root.internal );
119 
120       size->root.internal = 0;
121     }
122   }
123 
124 
125   FT_LOCAL_DEF( FT_Error )
cid_size_init(CID_Size size)126   cid_size_init( CID_Size  size )
127   {
128     FT_Error           error = 0;
129     PSH_Globals_Funcs  funcs = cid_size_get_globals_funcs( size );
130 
131 
132     if ( funcs )
133     {
134       PSH_Globals   globals;
135       CID_Face      face = (CID_Face)size->root.face;
136       CID_FaceDict  dict = face->cid.font_dicts + face->root.face_index;
137       PS_Private    priv = &dict->private_dict;
138 
139 
140       error = funcs->create( size->root.face->memory, priv, &globals );
141       if ( !error )
142         size->root.internal = (FT_Size_Internal)(void*)globals;
143     }
144 
145     return error;
146   }
147 
148 
149   FT_LOCAL_DEF( FT_Error )
cid_size_reset(CID_Size size)150   cid_size_reset( CID_Size  size )
151   {
152     PSH_Globals_Funcs  funcs = cid_size_get_globals_funcs( size );
153     FT_Error           error = 0;
154 
155 
156     if ( funcs )
157       error = funcs->set_scale( (PSH_Globals)size->root.internal,
158                                  size->root.metrics.x_scale,
159                                  size->root.metrics.y_scale,
160                                  0, 0 );
161     return error;
162   }
163 
164 
165   /*************************************************************************/
166   /*                                                                       */
167   /*                           FACE  FUNCTIONS                             */
168   /*                                                                       */
169   /*************************************************************************/
170 
171   /*************************************************************************/
172   /*                                                                       */
173   /* <Function>                                                            */
174   /*    cid_face_done                                                      */
175   /*                                                                       */
176   /* <Description>                                                         */
177   /*    Finalizes a given face object.                                     */
178   /*                                                                       */
179   /* <Input>                                                               */
180   /*    face :: A pointer to the face object to destroy.                   */
181   /*                                                                       */
182   FT_LOCAL_DEF( void )
cid_face_done(CID_Face face)183   cid_face_done( CID_Face  face )
184   {
185     FT_Memory  memory;
186 
187 
188     if ( face )
189     {
190       CID_FaceInfo  cid  = &face->cid;
191       PS_FontInfo   info = &cid->font_info;
192 
193 
194       memory = face->root.memory;
195 
196       /* release subrs */
197       if ( face->subrs )
198       {
199         FT_Int  n;
200 
201 
202         for ( n = 0; n < cid->num_dicts; n++ )
203         {
204           CID_Subrs  subr = face->subrs + n;
205 
206 
207           if ( subr->code )
208           {
209             FT_FREE( subr->code[0] );
210             FT_FREE( subr->code );
211           }
212         }
213 
214         FT_FREE( face->subrs );
215       }
216 
217       /* release FontInfo strings */
218       FT_FREE( info->version );
219       FT_FREE( info->notice );
220       FT_FREE( info->full_name );
221       FT_FREE( info->family_name );
222       FT_FREE( info->weight );
223 
224       /* release font dictionaries */
225       FT_FREE( cid->font_dicts );
226       cid->num_dicts = 0;
227 
228       /* release other strings */
229       FT_FREE( cid->cid_font_name );
230       FT_FREE( cid->registry );
231       FT_FREE( cid->ordering );
232 
233       face->root.family_name = 0;
234       face->root.style_name  = 0;
235     }
236   }
237 
238 
239   /*************************************************************************/
240   /*                                                                       */
241   /* <Function>                                                            */
242   /*    cid_face_init                                                      */
243   /*                                                                       */
244   /* <Description>                                                         */
245   /*    Initializes a given CID face object.                               */
246   /*                                                                       */
247   /* <Input>                                                               */
248   /*    stream     :: The source font stream.                              */
249   /*                                                                       */
250   /*    face_index :: The index of the font face in the resource.          */
251   /*                                                                       */
252   /*    num_params :: Number of additional generic parameters.  Ignored.   */
253   /*                                                                       */
254   /*    params     :: Additional generic parameters.  Ignored.             */
255   /*                                                                       */
256   /* <InOut>                                                               */
257   /*    face       :: The newly built face object.                         */
258   /*                                                                       */
259   /* <Return>                                                              */
260   /*    FreeType error code.  0 means success.                             */
261   /*                                                                       */
262   FT_LOCAL_DEF( FT_Error )
cid_face_init(FT_Stream stream,CID_Face face,FT_Int face_index,FT_Int num_params,FT_Parameter * params)263   cid_face_init( FT_Stream      stream,
264                  CID_Face       face,
265                  FT_Int         face_index,
266                  FT_Int         num_params,
267                  FT_Parameter*  params )
268   {
269     FT_Error          error;
270     PSNames_Service   psnames;
271     PSAux_Service     psaux;
272     PSHinter_Service  pshinter;
273 
274     FT_UNUSED( num_params );
275     FT_UNUSED( params );
276     FT_UNUSED( face_index );
277     FT_UNUSED( stream );
278 
279 
280     face->root.num_faces = 1;
281 
282     psnames = (PSNames_Service)face->psnames;
283     if ( !psnames )
284     {
285       psnames = (PSNames_Service)FT_Get_Module_Interface(
286                   FT_FACE_LIBRARY( face ), "psnames" );
287 
288       face->psnames = psnames;
289     }
290 
291     psaux = (PSAux_Service)face->psaux;
292     if ( !psaux )
293     {
294       psaux = (PSAux_Service)FT_Get_Module_Interface(
295                 FT_FACE_LIBRARY( face ), "psaux" );
296 
297       face->psaux = psaux;
298     }
299 
300     pshinter = (PSHinter_Service)face->pshinter;
301     if ( !pshinter )
302     {
303       pshinter = (PSHinter_Service)FT_Get_Module_Interface(
304                    FT_FACE_LIBRARY( face ), "pshinter" );
305 
306       face->pshinter = pshinter;
307     }
308 
309     /* open the tokenizer; this will also check the font format */
310     if ( FT_STREAM_SEEK( 0 ) )
311       goto Exit;
312 
313     error = cid_face_open( face );
314     if ( error )
315       goto Exit;
316 
317     /* if we just wanted to check the format, leave successfully now */
318     if ( face_index < 0 )
319       goto Exit;
320 
321     /* check the face index */
322     if ( face_index != 0 )
323     {
324       FT_ERROR(( "cid_face_init: invalid face index\n" ));
325       error = CID_Err_Invalid_Argument;
326       goto Exit;
327     }
328 
329     /* Now, load the font program into the face object */
330     {
331       /* Init the face object fields */
332       /* Now set up root face fields */
333       {
334         FT_Face  root = (FT_Face)&face->root;
335 
336 
337         root->num_glyphs   = face->cid.cid_count;
338         root->num_charmaps = 0;
339 
340         root->face_index = face_index;
341         root->face_flags = FT_FACE_FLAG_SCALABLE;
342 
343         root->face_flags |= FT_FACE_FLAG_HORIZONTAL;
344 
345         if ( face->cid.font_info.is_fixed_pitch )
346           root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
347 
348         /* XXX: TODO: add kerning with .afm support */
349 
350         /* get style name -- be careful, some broken fonts only */
351         /* have a /FontName dictionary entry!                   */
352         root->family_name = face->cid.font_info.family_name;
353         if ( root->family_name )
354         {
355           char*  full   = face->cid.font_info.full_name;
356           char*  family = root->family_name;
357 
358           while ( *family && *full == *family )
359           {
360             family++;
361             full++;
362           }
363 
364           root->style_name = ( *full == ' ' ) ? full + 1
365                                               : (char *)"Regular";
366         }
367         else
368         {
369           /* do we have a `/FontName'? */
370           if ( face->cid.cid_font_name )
371           {
372             root->family_name = face->cid.cid_font_name;
373             root->style_name  = (char *)"Regular";
374           }
375         }
376 
377         /* no embedded bitmap support */
378         root->num_fixed_sizes = 0;
379         root->available_sizes = 0;
380 
381         root->bbox.xMin =   face->cid.font_bbox.xMin             >> 16;
382         root->bbox.yMin =   face->cid.font_bbox.yMin             >> 16;
383         root->bbox.xMax = ( face->cid.font_bbox.xMax + 0xFFFFU ) >> 16;
384         root->bbox.yMax = ( face->cid.font_bbox.yMax + 0xFFFFU ) >> 16;
385 
386         if ( !root->units_per_EM )
387           root->units_per_EM  = 1000;
388 
389         root->ascender  = (FT_Short)( root->bbox.yMax );
390         root->descender = (FT_Short)( root->bbox.yMin );
391         root->height    = (FT_Short)(
392           ( ( root->ascender + root->descender ) * 12 ) / 10 );
393 
394         root->underline_position  = face->cid.font_info.underline_position;
395         root->underline_thickness = face->cid.font_info.underline_thickness;
396 
397         root->internal->max_points   = 0;
398         root->internal->max_contours = 0;
399       }
400     }
401 
402   Exit:
403     return error;
404   }
405 
406 
407   /*************************************************************************/
408   /*                                                                       */
409   /* <Function>                                                            */
410   /*    cid_driver_init                                                    */
411   /*                                                                       */
412   /* <Description>                                                         */
413   /*    Initializes a given CID driver object.                             */
414   /*                                                                       */
415   /* <Input>                                                               */
416   /*    driver :: A handle to the target driver object.                    */
417   /*                                                                       */
418   /* <Return>                                                              */
419   /*    FreeType error code.  0 means success.                             */
420   /*                                                                       */
421   FT_LOCAL_DEF( FT_Error )
cid_driver_init(CID_Driver driver)422   cid_driver_init( CID_Driver  driver )
423   {
424     FT_UNUSED( driver );
425 
426     return CID_Err_Ok;
427   }
428 
429 
430   /*************************************************************************/
431   /*                                                                       */
432   /* <Function>                                                            */
433   /*    cid_driver_done                                                    */
434   /*                                                                       */
435   /* <Description>                                                         */
436   /*    Finalizes a given CID driver.                                      */
437   /*                                                                       */
438   /* <Input>                                                               */
439   /*    driver :: A handle to the target CID driver.                       */
440   /*                                                                       */
441   FT_LOCAL_DEF( void )
cid_driver_done(CID_Driver driver)442   cid_driver_done( CID_Driver  driver )
443   {
444     FT_UNUSED( driver );
445   }
446 
447 
448 /* END */
449