The BIG graph update
[rrdtool.git] / libraries / freetype-2.0.5 / t1objs.c
1 /***************************************************************************/
2 /*                                                                         */
3 /*  t1objs.c                                                               */
4 /*                                                                         */
5 /*    Type 1 objects manager (body).                                       */
6 /*                                                                         */
7 /*  Copyright 1996-2001 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 <string.h>         /* strcmp() */
24
25 #include "t1gload.h"
26 #include "t1load.h"
27
28 #include "t1errors.h"
29
30 #ifndef T1_CONFIG_OPTION_NO_AFM
31 #include "t1afm.h"
32 #endif
33
34 #include FT_INTERNAL_POSTSCRIPT_NAMES_H
35 #include FT_INTERNAL_POSTSCRIPT_AUX_H
36
37
38   /*************************************************************************/
39   /*                                                                       */
40   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
41   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
42   /* messages during execution.                                            */
43   /*                                                                       */
44 #undef  FT_COMPONENT
45 #define FT_COMPONENT  trace_t1objs
46
47
48   /*************************************************************************/
49   /*                                                                       */
50   /*                            FACE  FUNCTIONS                            */
51   /*                                                                       */
52   /*************************************************************************/
53
54
55   /*************************************************************************/
56   /*                                                                       */
57   /* <Function>                                                            */
58   /*    T1_Done_Face                                                       */
59   /*                                                                       */
60   /* <Description>                                                         */
61   /*    The face object destructor.                                        */
62   /*                                                                       */
63   /* <Input>                                                               */
64   /*    face :: A typeless pointer to the face object to destroy.          */
65   /*                                                                       */
66   FT_LOCAL_DEF void
67   T1_Done_Face( T1_Face  face )
68   {
69     FT_Memory  memory;
70     T1_Font*   type1 = &face->type1;
71
72
73     if ( face )
74     {
75       memory = face->root.memory;
76
77 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
78       /* release multiple masters information */
79       T1_Done_Blend( face );
80       face->blend = 0;
81 #endif
82
83       /* release font info strings */
84       {
85         T1_FontInfo*  info = &type1->font_info;
86
87
88         FREE( info->version );
89         FREE( info->notice );
90         FREE( info->full_name );
91         FREE( info->family_name );
92         FREE( info->weight );
93       }
94
95       /* release top dictionary */
96       FREE( type1->charstrings_len );
97       FREE( type1->charstrings );
98       FREE( type1->glyph_names );
99
100       FREE( type1->subrs );
101       FREE( type1->subrs_len );
102
103       FREE( type1->subrs_block );
104       FREE( type1->charstrings_block );
105       FREE( type1->glyph_names_block );
106
107       FREE( type1->encoding.char_index );
108       FREE( type1->encoding.char_name );
109       FREE( type1->font_name );
110
111 #ifndef T1_CONFIG_OPTION_NO_AFM
112       /* release afm data if present */
113       if ( face->afm_data )
114         T1_Done_AFM( memory, (T1_AFM*)face->afm_data );
115 #endif
116
117       /* release unicode map, if any */
118       FREE( face->unicode_map.maps );
119       face->unicode_map.num_maps = 0;
120
121       face->root.family_name = 0;
122       face->root.style_name  = 0;
123     }
124   }
125
126
127   /*************************************************************************/
128   /*                                                                       */
129   /* <Function>                                                            */
130   /*    T1_Init_Face                                                       */
131   /*                                                                       */
132   /* <Description>                                                         */
133   /*    The face object constructor.                                       */
134   /*                                                                       */
135   /* <Input>                                                               */
136   /*    stream     ::  input stream where to load font data.               */
137   /*                                                                       */
138   /*    face_index :: The index of the font face in the resource.          */
139   /*                                                                       */
140   /*    num_params :: Number of additional generic parameters.  Ignored.   */
141   /*                                                                       */
142   /*    params     :: Additional generic parameters.  Ignored.             */
143   /*                                                                       */
144   /* <InOut>                                                               */
145   /*    face       :: The face record to build.                            */
146   /*                                                                       */
147   /* <Return>                                                              */
148   /*    FreeType error code.  0 means success.                             */
149   /*                                                                       */
150   FT_LOCAL_DEF FT_Error
151   T1_Init_Face( FT_Stream      stream,
152                 T1_Face        face,
153                 FT_Int         face_index,
154                 FT_Int         num_params,
155                 FT_Parameter*  params )
156   {
157     FT_Error            error;
158     PSNames_Interface*  psnames;
159     PSAux_Interface*    psaux;
160
161     FT_UNUSED( num_params );
162     FT_UNUSED( params );
163     FT_UNUSED( face_index );
164     FT_UNUSED( stream );
165
166
167     face->root.num_faces = 1;
168
169     psnames = (PSNames_Interface*)face->psnames;
170     if ( !psnames )
171     {
172       psnames = (PSNames_Interface*)
173                 FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), "psnames" );
174
175       face->psnames = psnames;
176     }
177
178     psaux = (PSAux_Interface*)face->psaux;
179     if ( !psaux )
180     {
181       psaux = (PSAux_Interface*)
182               FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), "psaux" );
183
184       face->psaux = psaux;
185     }
186
187     /* open the tokenizer, this will also check the font format */
188     error = T1_Open_Face( face );
189     if ( error )
190       goto Exit;
191
192     /* if we just wanted to check the format, leave successfully now */
193     if ( face_index < 0 )
194       goto Exit;
195
196     /* check the face index */
197     if ( face_index != 0 )
198     {
199       FT_ERROR(( "T1_Init_Face: invalid face index\n" ));
200       error = T1_Err_Invalid_Argument;
201       goto Exit;
202     }
203
204     /* Now, load the font program into the face object */
205
206     /* Init the face object fields */
207     /* Now set up root face fields */
208     {
209       FT_Face  root = (FT_Face)&face->root;
210
211
212       root->num_glyphs   = face->type1.num_glyphs;
213       root->num_charmaps = 1;
214
215       root->face_index = face_index;
216       root->face_flags = FT_FACE_FLAG_SCALABLE;
217
218       root->face_flags |= FT_FACE_FLAG_HORIZONTAL;
219
220       root->face_flags |= FT_FACE_FLAG_GLYPH_NAMES;
221
222       if ( face->type1.font_info.is_fixed_pitch )
223         root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
224
225       if ( face->blend )
226         root->face_flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;
227
228       /* XXX: TODO -- add kerning with .afm support */
229
230       /* get style name -- be careful, some broken fonts only */
231       /* have a `/FontName' dictionary entry!                 */
232       root->family_name = face->type1.font_info.family_name;
233       if ( root->family_name )
234       {
235         char*  full   = face->type1.font_info.full_name;
236         char*  family = root->family_name;
237
238
239         while ( *family && *full == *family )
240         {
241           family++;
242           full++;
243         }
244
245         root->style_name = ( *full == ' ' ? full + 1
246                                           : (char *)"Regular" );
247       }
248       else
249       {
250         /* do we have a `/FontName'? */
251         if ( face->type1.font_name )
252         {
253           root->family_name = face->type1.font_name;
254           root->style_name  = (char *)"Regular";
255         }
256       }
257
258       /* compute style flags */
259       root->style_flags = 0;
260       if ( face->type1.font_info.italic_angle )
261         root->style_flags |= FT_STYLE_FLAG_ITALIC;
262       if ( face->type1.font_info.weight )
263       {
264         if ( !strcmp( face->type1.font_info.weight, "Bold"  ) ||
265              !strcmp( face->type1.font_info.weight, "Black" ) )
266           root->style_flags |= FT_STYLE_FLAG_BOLD;
267       }
268
269       /* no embedded bitmap support */
270       root->num_fixed_sizes = 0;
271       root->available_sizes = 0;
272
273       root->bbox = face->type1.font_bbox;
274
275       /* Set units_per_EM if we didn't set it in parse_font_matrix. */
276       if ( !root->units_per_EM )
277         root->units_per_EM = 1000;
278
279       root->ascender  = (FT_Short)( face->type1.font_bbox.yMax >> 16 );
280       root->descender = (FT_Short)( face->type1.font_bbox.yMin >> 16 );
281       root->height    = (FT_Short)(
282                           ( ( root->ascender - root->descender ) * 12 ) / 10 );
283
284       /* now compute the maximum advance width */
285       root->max_advance_width =
286         (FT_Short)( face->type1.font_bbox.xMax >> 16 );
287       {
288         FT_Int  max_advance;
289
290
291         error = T1_Compute_Max_Advance( face, &max_advance );
292
293         /* in case of error, keep the standard width */
294         if ( !error )
295           root->max_advance_width = (FT_Short)max_advance;
296         else
297           error = 0;   /* clear error */
298       }
299
300       root->max_advance_height = root->height;
301
302       root->underline_position  = face->type1.font_info.underline_position;
303       root->underline_thickness = face->type1.font_info.underline_thickness;
304
305       root->internal->max_points   = 0;
306       root->internal->max_contours = 0;
307     }
308
309     /* charmap support -- synthetize unicode charmap if possible */
310     {
311       FT_Face     root    = &face->root;
312       FT_CharMap  charmap = face->charmaprecs;
313
314
315       /* synthesize a Unicode charmap if there is support in the `PSNames' */
316       /* module                                                            */
317       if ( psnames )
318       {
319         if ( psnames->unicode_value )
320         {
321           error = psnames->build_unicodes(
322                     root->memory,
323                     face->type1.num_glyphs,
324                     (const char**)face->type1.glyph_names,
325                     &face->unicode_map );
326           if ( !error )
327           {
328             root->charmap        = charmap;
329             charmap->face        = (FT_Face)face;
330             charmap->encoding    = ft_encoding_unicode;
331             charmap->platform_id = 3;
332             charmap->encoding_id = 1;
333             charmap++;
334           }
335
336           /* simply clear the error in case of failure (which really) */
337           /* means that out of memory or no unicode glyph names       */
338           error = T1_Err_Ok;
339         }
340       }
341
342       /* now, support either the standard, expert, or custom encoding */
343       charmap->face        = (FT_Face)face;
344       charmap->platform_id = 7;  /* a new platform id for Adobe fonts? */
345
346       switch ( face->type1.encoding_type )
347       {
348       case t1_encoding_standard:
349         charmap->encoding    = ft_encoding_adobe_standard;
350         charmap->encoding_id = 0;
351         break;
352
353       case t1_encoding_expert:
354         charmap->encoding    = ft_encoding_adobe_expert;
355         charmap->encoding_id = 1;
356         break;
357
358       default:
359         charmap->encoding    = ft_encoding_adobe_custom;
360         charmap->encoding_id = 2;
361         break;
362       }
363
364       root->charmaps     = face->charmaps;
365       root->num_charmaps = charmap - face->charmaprecs + 1;
366       face->charmaps[0]  = &face->charmaprecs[0];
367       face->charmaps[1]  = &face->charmaprecs[1];
368     }
369
370   Exit:
371     return error;
372   }
373
374
375   /*************************************************************************/
376   /*                                                                       */
377   /* <Function>                                                            */
378   /*    T1_Init_Driver                                                     */
379   /*                                                                       */
380   /* <Description>                                                         */
381   /*    Initializes a given Type 1 driver object.                          */
382   /*                                                                       */
383   /* <Input>                                                               */
384   /*    driver :: A handle to the target driver object.                    */
385   /*                                                                       */
386   /* <Return>                                                              */
387   /*    FreeType error code.  0 means success.                             */
388   /*                                                                       */
389   FT_LOCAL_DEF FT_Error
390   T1_Init_Driver( T1_Driver  driver )
391   {
392     FT_UNUSED( driver );
393
394     return T1_Err_Ok;
395   }
396
397
398   /*************************************************************************/
399   /*                                                                       */
400   /* <Function>                                                            */
401   /*    T1_Done_Driver                                                     */
402   /*                                                                       */
403   /* <Description>                                                         */
404   /*    Finalizes a given Type 1 driver.                                   */
405   /*                                                                       */
406   /* <Input>                                                               */
407   /*    driver  :: A handle to the target Type 1 driver.                   */
408   /*                                                                       */
409   FT_LOCAL_DEF void
410   T1_Done_Driver( T1_Driver  driver )
411   {
412     FT_UNUSED( driver );
413   }
414
415
416 /* END */