1 /***************************************************************************/
5 /* 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
29 #ifndef T1_CONFIG_OPTION_DISABLE_HINTER
33 #else /* FT_FLAT_COMPILE */
35 #include <type1/t1gload.h>
36 #include <type1/t1load.h>
37 #include <type1/t1afm.h>
39 #ifndef T1_CONFIG_OPTION_DISABLE_HINTER
40 #include <type1/t1hinter.h>
43 #endif /* FT_FLAT_COMPILE */
46 #include <freetype/internal/psnames.h>
49 /*************************************************************************/
51 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
52 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
53 /* messages during execution. */
56 #define FT_COMPONENT trace_t1objs
59 /*************************************************************************/
63 /*************************************************************************/
66 /*************************************************************************/
72 /* The Type 1 size object destructor. Used to discard a given size */
76 /* size :: A handle to the target size object. */
79 void T1_Done_Size( T1_Size size
)
84 #ifndef T1_CONFIG_OPTION_DISABLE_HINTER
85 T1_Done_Size_Hinter( size
);
93 /*************************************************************************/
99 /* The size object initializer. */
102 /* size :: A handle to the target size object. */
105 /* FreeTrue error code. 0 means success. */
108 FT_Error
T1_Init_Size( T1_Size size
)
115 #ifndef T1_CONFIG_OPTION_DISABLE_HINTER
116 error
= T1_New_Size_Hinter( size
);
129 /*************************************************************************/
135 /* Resets an instance to a new pointsize/transform. This function is */
136 /* in charge of resetting the blue zones,a s well as the stem snap */
137 /* tables for a given size. */
140 /* size :: The target size object. */
143 /* FreeType error code. 0 means success. */
146 FT_Error
T1_Reset_Size( T1_Size size
)
148 /* recompute ascender, descender, etc. */
149 T1_Face face
= (T1_Face
)size
->root
.face
;
150 FT_Size_Metrics
* metrics
= &size
->root
.metrics
;
153 if ( metrics
->x_ppem
< 1 || metrics
->y_ppem
< 1 )
154 return FT_Err_Invalid_Argument
;
156 /* Compute root ascender, descender, test height, and max_advance */
157 metrics
->ascender
= ( FT_MulFix( face
->root
.ascender
,
158 metrics
->y_scale
) + 32 ) & -64;
159 metrics
->descender
= ( FT_MulFix( face
->root
.descender
,
160 metrics
->y_scale
) + 32 ) & -64;
161 metrics
->height
= ( FT_MulFix( face
->root
.height
,
162 metrics
->y_scale
) + 32 ) & -64;
163 metrics
->max_advance
= ( FT_MulFix( face
->root
.max_advance_width
,
164 metrics
->x_scale
) + 32 ) & -64;
166 #ifndef T1_CONFIG_OPTION_DISABLE_HINTER
167 return T1_Reset_Size_Hinter( size
);
174 /*************************************************************************/
178 /*************************************************************************/
181 /*************************************************************************/
187 /* The face object destructor. */
190 /* face :: A typeless pointer to the face object to destroy. */
193 void T1_Done_Face( T1_Face face
)
196 T1_Font
* type1
= &face
->type1
;
201 memory
= face
->root
.memory
;
203 /* release font info strings */
205 T1_FontInfo
* info
= &type1
->font_info
;
208 FREE( info
->version
);
209 FREE( info
->notice
);
210 FREE( info
->full_name
);
211 FREE( info
->family_name
);
212 FREE( info
->weight
);
215 /* release top dictionary */
216 FREE( type1
->charstrings_len
);
217 FREE( type1
->charstrings
);
218 FREE( type1
->glyph_names
);
220 FREE( type1
->subrs
);
221 FREE( type1
->subrs_len
);
223 FREE( type1
->subrs_block
);
224 FREE( type1
->charstrings_block
);
225 FREE( type1
->glyph_names_block
);
227 FREE( type1
->encoding
.char_index
);
228 FREE( type1
->font_name
);
230 #ifndef T1_CONFIG_OPTION_NO_AFM
231 /* release afm data if present */
232 if ( face
->afm_data
)
233 T1_Done_AFM( memory
, (T1_AFM
*)face
->afm_data
);
236 /* release unicode map, if any */
237 FREE( face
->unicode_map
.maps
);
238 face
->unicode_map
.num_maps
= 0;
240 face
->root
.family_name
= 0;
241 face
->root
.style_name
= 0;
246 /*************************************************************************/
252 /* The face object constructor. */
255 /* stream :: input stream where to load font data. */
257 /* face_index :: The index of the font face in the resource. */
259 /* num_params :: Number of additional generic parameters. Ignored. */
261 /* params :: Additional generic parameters. Ignored. */
264 /* face :: The face record to build. */
267 /* FreeType error code. 0 means success. */
270 FT_Error
T1_Init_Face( FT_Stream stream
,
274 FT_Parameter
* params
)
276 T1_Tokenizer tokenizer
;
278 PSNames_Interface
* psnames
;
280 FT_UNUSED( num_params
);
282 FT_UNUSED( face_index
);
286 face
->root
.num_faces
= 1;
288 psnames
= (PSNames_Interface
*)face
->psnames
;
291 psnames
= (PSNames_Interface
*)
292 FT_Get_Module_Interface( FT_FACE_LIBRARY( face
),
295 face
->psnames
= psnames
;
298 /* open the tokenizer, this will also check the font format */
299 error
= New_Tokenizer( stream
, &tokenizer
);
303 /* if we just wanted to check the format, leave successfully now */
304 if ( face_index
< 0 )
307 /* check the face index */
308 if ( face_index
!= 0 )
310 FT_ERROR(( "T1_Init_Face: invalid face index\n" ));
311 error
= T1_Err_Invalid_Argument
;
315 /* Now, load the font program into the face object */
320 Init_T1_Parser( &parser
, face
, tokenizer
);
321 error
= Parse_T1_FontProgram( &parser
);
325 /* Init the face object fields */
326 /* Now set up root face fields */
328 FT_Face root
= (FT_Face
)&face
->root
;
329 T1_Font
* type1
= &face
->type1
;
332 root
->num_glyphs
= type1
->num_glyphs
;
333 root
->num_charmaps
= 1;
335 root
->face_index
= face_index
;
336 root
->face_flags
= FT_FACE_FLAG_SCALABLE
;
338 root
->face_flags
|= FT_FACE_FLAG_HORIZONTAL
;
340 root
->face_flags
|= FT_FACE_FLAG_GLYPH_NAMES
;
342 if ( type1
->font_info
.is_fixed_pitch
)
343 root
->face_flags
|= FT_FACE_FLAG_FIXED_WIDTH
;
345 /* XXX: TODO -- add kerning with .afm support */
347 /* get style name - be careful, some broken fonts only */
348 /* have a `/FontName' dictionary entry! */
349 root
->family_name
= type1
->font_info
.family_name
;
350 if ( root
->family_name
)
352 char* full
= type1
->font_info
.full_name
;
353 char* family
= root
->family_name
;
356 while ( *family
&& *full
== *family
)
362 root
->style_name
= ( *full
== ' ' ? full
+ 1
363 : (char *)"Regular" );
367 /* do we have a `/FontName'? */
368 if (type1
->font_name
)
370 root
->family_name
= type1
->font_name
;
371 root
->style_name
= "Regular";
375 /* no embedded bitmap support */
376 root
->num_fixed_sizes
= 0;
377 root
->available_sizes
= 0;
379 root
->bbox
= type1
->font_bbox
;
380 root
->units_per_EM
= 1000;
381 root
->ascender
= (FT_Short
)type1
->font_bbox
.yMax
;
382 root
->descender
= -(FT_Short
)type1
->font_bbox
.yMin
;
383 root
->height
= ( ( root
->ascender
+ root
->descender
) * 12 )
386 /* now compute the maximum advance width */
388 root
->max_advance_width
= type1
->private_dict
.standard_width
[0];
390 /* compute max advance width for proportional fonts */
391 if ( !type1
->font_info
.is_fixed_pitch
)
396 error
= T1_Compute_Max_Advance( face
, &max_advance
);
398 /* in case of error, keep the standard width */
400 root
->max_advance_width
= max_advance
;
402 error
= 0; /* clear error */
405 root
->max_advance_height
= root
->height
;
407 root
->underline_position
= type1
->font_info
.underline_position
;
408 root
->underline_thickness
= type1
->font_info
.underline_thickness
;
410 root
->max_points
= 0;
411 root
->max_contours
= 0;
415 /* charmap support - synthetize unicode charmap when possible */
417 FT_Face root
= &face
->root
;
418 FT_CharMap charmap
= face
->charmaprecs
;
421 /* synthesize a Unicode charmap if there is support in the `PSNames' */
425 PSNames_Interface
* psnames
= (PSNames_Interface
*)face
->psnames
;
428 if ( psnames
->unicode_value
)
430 error
= psnames
->build_unicodes(
432 face
->type1
.num_glyphs
,
433 (const char**)face
->type1
.glyph_names
,
434 &face
->unicode_map
);
437 root
->charmap
= charmap
;
438 charmap
->face
= (FT_Face
)face
;
439 charmap
->encoding
= ft_encoding_unicode
;
440 charmap
->platform_id
= 3;
441 charmap
->encoding_id
= 1;
445 /* simply clear the error in case of failure (which really) */
446 /* means that out of memory or no unicode glyph names */
451 /* now, support either the standard, expert, or custom encodings */
452 charmap
->face
= (FT_Face
)face
;
453 charmap
->platform_id
= 7; /* a new platform id for Adobe fonts ?? */
455 switch ( face
->type1
.encoding_type
)
457 case t1_encoding_standard
:
458 charmap
->encoding
= ft_encoding_adobe_standard
;
459 charmap
->encoding_id
= 0;
462 case t1_encoding_expert
:
463 charmap
->encoding
= ft_encoding_adobe_expert
;
464 charmap
->encoding_id
= 1;
468 charmap
->encoding
= ft_encoding_adobe_custom
;
469 charmap
->encoding_id
= 2;
473 root
->charmaps
= face
->charmaps
;
474 root
->num_charmaps
= charmap
- face
->charmaprecs
+ 1;
475 face
->charmaps
[0] = &face
->charmaprecs
[0];
476 face
->charmaps
[1] = &face
->charmaprecs
[1];
480 Done_Tokenizer( tokenizer
);
487 /*************************************************************************/
490 /* T1_Done_GlyphSlot */
493 /* The glyph slot object destructor. */
496 /* glyph :: The glyph slot handle to destroy. */
499 void T1_Done_GlyphSlot( T1_GlyphSlot glyph
)
501 #ifndef T1_CONFIG_OPTION_DISABLE_HINTER
503 T1_Done_Glyph_Hinter( glyph
);
513 /*************************************************************************/
516 /* T1_Init_GlyphSlot */
519 /* The glyph slot object constructor. */
522 /* glyph :: The glyph slot handle to initialize. */
525 FT_Error
T1_Init_GlyphSlot( T1_GlyphSlot glyph
)
527 FT_Error error
= FT_Err_Ok
;
530 #ifndef T1_CONFIG_OPTION_DISABLE_HINTER
532 error
= T1_New_Glyph_Hinter( glyph
);