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