1 /***************************************************************************/
5 /* Experimental Type 1 objects manager (body). */
7 /* Copyright 1996-2000 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
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. */
16 /***************************************************************************/
19 #include <freetype/internal/ftdebug.h>
20 #include <freetype/internal/ftstream.h>
23 #ifdef FT_FLAT_COMPILE
31 #include <type1z/z1gload.h>
32 #include <type1z/z1load.h>
33 #include <type1z/z1afm.h>
38 #include <freetype/internal/psnames.h>
41 /*************************************************************************/
43 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
44 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
45 /* messages during execution. */
48 #define FT_COMPONENT trace_z1objs
51 /*************************************************************************/
55 /*************************************************************************/
58 /*************************************************************************/
64 /* The face object destructor. */
67 /* face :: A typeless pointer to the face object to destroy. */
70 void Z1_Done_Face( T1_Face face
)
73 T1_Font
* type1
= &face
->type1
;
78 memory
= face
->root
.memory
;
80 #ifndef Z1_CONFIG_OPTION_NO_MM_SUPPORT
81 /* release multiple masters information */
82 Z1_Done_Blend( face
);
86 /* release font info strings */
88 T1_FontInfo
* info
= &type1
->font_info
;
91 FREE( info
->version
);
93 FREE( info
->full_name
);
94 FREE( info
->family_name
);
98 /* release top dictionary */
99 FREE( type1
->charstrings_len
);
100 FREE( type1
->charstrings
);
101 FREE( type1
->glyph_names
);
103 FREE( type1
->subrs
);
104 FREE( type1
->subrs_len
);
106 FREE( type1
->subrs_block
);
107 FREE( type1
->charstrings_block
);
108 FREE( type1
->glyph_names_block
);
110 FREE( type1
->encoding
.char_index
);
111 FREE( type1
->font_name
);
113 #ifndef Z1_CONFIG_OPTION_NO_AFM
114 /* release afm data if present */
115 if ( face
->afm_data
)
116 Z1_Done_AFM( memory
, (Z1_AFM
*)face
->afm_data
);
119 /* release unicode map, if any */
120 FREE( face
->unicode_map
.maps
);
121 face
->unicode_map
.num_maps
= 0;
123 face
->root
.family_name
= 0;
124 face
->root
.style_name
= 0;
129 /*************************************************************************/
135 /* The face object constructor. */
138 /* stream :: input stream where to load font data. */
140 /* face_index :: The index of the font face in the resource. */
142 /* num_params :: Number of additional generic parameters. Ignored. */
144 /* params :: Additional generic parameters. Ignored. */
147 /* face :: The face record to build. */
150 /* FreeType error code. 0 means success. */
153 FT_Error
Z1_Init_Face( FT_Stream stream
,
157 FT_Parameter
* params
)
160 PSNames_Interface
* psnames
;
162 FT_UNUSED( num_params
);
164 FT_UNUSED( face_index
);
168 face
->root
.num_faces
= 1;
170 psnames
= (PSNames_Interface
*)face
->psnames
;
173 psnames
= (PSNames_Interface
*)
174 FT_Get_Module_Interface( FT_FACE_LIBRARY( face
), "psnames" );
176 face
->psnames
= psnames
;
179 /* open the tokenizer, this will also check the font format */
180 error
= Z1_Open_Face( face
);
184 /* if we just wanted to check the format, leave successfully now */
185 if ( face_index
< 0 )
188 /* check the face index */
189 if ( face_index
!= 0 )
191 FT_ERROR(( "Z1_Init_Face: invalid face index\n" ));
192 error
= T1_Err_Invalid_Argument
;
196 /* Now, load the font program into the face object */
198 /* Init the face object fields */
199 /* Now set up root face fields */
201 FT_Face root
= (FT_Face
)&face
->root
;
204 root
->num_glyphs
= face
->type1
.num_glyphs
;
205 root
->num_charmaps
= 1;
207 root
->face_index
= face_index
;
208 root
->face_flags
= FT_FACE_FLAG_SCALABLE
;
210 root
->face_flags
|= FT_FACE_FLAG_HORIZONTAL
;
212 root
->face_flags
|= FT_FACE_FLAG_GLYPH_NAMES
;
214 if ( face
->type1
.font_info
.is_fixed_pitch
)
215 root
->face_flags
|= FT_FACE_FLAG_FIXED_WIDTH
;
218 root
->face_flags
|= FT_FACE_FLAG_MULTIPLE_MASTERS
;
220 /* XXX: TODO -- add kerning with .afm support */
222 /* get style name -- be careful, some broken fonts only */
223 /* have a `/FontName' dictionary entry! */
224 root
->family_name
= face
->type1
.font_info
.family_name
;
225 if ( root
->family_name
)
227 char* full
= face
->type1
.font_info
.full_name
;
228 char* family
= root
->family_name
;
231 while ( *family
&& *full
== *family
)
237 root
->style_name
= ( *full
== ' ' ? full
+ 1
238 : (char *)"Regular" );
242 /* do we have a `/FontName'? */
243 if ( face
->type1
.font_name
)
245 root
->family_name
= face
->type1
.font_name
;
246 root
->style_name
= "Regular";
250 /* no embedded bitmap support */
251 root
->num_fixed_sizes
= 0;
252 root
->available_sizes
= 0;
254 root
->bbox
= face
->type1
.font_bbox
;
255 root
->units_per_EM
= 1000;
256 root
->ascender
= (FT_Short
)face
->type1
.font_bbox
.yMax
;
257 root
->descender
= -(FT_Short
)face
->type1
.font_bbox
.yMin
;
258 root
->height
= ( ( root
->ascender
+ root
->descender
) * 12 ) / 10;
260 /* now compute the maximum advance width */
262 root
->max_advance_width
= face
->type1
.private_dict
.standard_width
[0];
264 /* compute max advance width for proportional fonts */
265 if ( !face
->type1
.font_info
.is_fixed_pitch
)
270 error
= Z1_Compute_Max_Advance( face
, &max_advance
);
272 /* in case of error, keep the standard width */
274 root
->max_advance_width
= max_advance
;
276 error
= 0; /* clear error */
279 root
->max_advance_height
= root
->height
;
281 root
->underline_position
= face
->type1
.font_info
.underline_position
;
282 root
->underline_thickness
= face
->type1
.font_info
.underline_thickness
;
284 root
->max_points
= 0;
285 root
->max_contours
= 0;
288 /* charmap support -- synthetize unicode charmap if possible */
290 FT_Face root
= &face
->root
;
291 FT_CharMap charmap
= face
->charmaprecs
;
294 /* synthesize a Unicode charmap if there is support in the `PSNames' */
298 PSNames_Interface
* psnames
= (PSNames_Interface
*)face
->psnames
;
301 if ( psnames
->unicode_value
)
303 error
= psnames
->build_unicodes(
305 face
->type1
.num_glyphs
,
306 (const char**)face
->type1
.glyph_names
,
307 &face
->unicode_map
);
310 root
->charmap
= charmap
;
311 charmap
->face
= (FT_Face
)face
;
312 charmap
->encoding
= ft_encoding_unicode
;
313 charmap
->platform_id
= 3;
314 charmap
->encoding_id
= 1;
318 /* simply clear the error in case of failure (which really) */
319 /* means that out of memory or no unicode glyph names */
324 /* now, support either the standard, expert, or custom encoding */
325 charmap
->face
= (FT_Face
)face
;
326 charmap
->platform_id
= 7; /* a new platform id for Adobe fonts? */
328 switch ( face
->type1
.encoding_type
)
330 case t1_encoding_standard
:
331 charmap
->encoding
= ft_encoding_adobe_standard
;
332 charmap
->encoding_id
= 0;
335 case t1_encoding_expert
:
336 charmap
->encoding
= ft_encoding_adobe_expert
;
337 charmap
->encoding_id
= 1;
341 charmap
->encoding
= ft_encoding_adobe_custom
;
342 charmap
->encoding_id
= 2;
346 root
->charmaps
= face
->charmaps
;
347 root
->num_charmaps
= charmap
- face
->charmaprecs
+ 1;
348 face
->charmaps
[0] = &face
->charmaprecs
[0];
349 face
->charmaps
[1] = &face
->charmaprecs
[1];
357 /*************************************************************************/
363 /* Initializes a given Type 1 driver object. */
366 /* driver :: A handle to the target driver object. */
369 /* FreeType error code. 0 means success. */
372 FT_Error
Z1_Init_Driver( Z1_Driver driver
)
380 /*************************************************************************/
386 /* Finalizes a given Type 1 driver. */
389 /* driver :: A handle to the target Type 1 driver. */
392 void Z1_Done_Driver( Z1_Driver driver
)