1 /***************************************************************************/
5 /* Type 1 driver interface (body). */
7 /* Copyright 1996-2015 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 /***************************************************************************/
26 #ifndef T1_CONFIG_OPTION_NO_AFM
30 #include FT_INTERNAL_DEBUG_H
31 #include FT_INTERNAL_STREAM_H
33 #include FT_SERVICE_MULTIPLE_MASTERS_H
34 #include FT_SERVICE_GLYPH_DICT_H
35 #include FT_SERVICE_FONT_FORMAT_H
36 #include FT_SERVICE_POSTSCRIPT_NAME_H
37 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
38 #include FT_SERVICE_POSTSCRIPT_INFO_H
39 #include FT_SERVICE_KERNING_H
42 /*************************************************************************/
44 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
45 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
46 /* messages during execution. */
49 #define FT_COMPONENT trace_t1driver
57 t1_get_glyph_name( T1_Face face
,
62 FT_STRCPYN( buffer
, face
->type1
.glyph_names
[glyph_index
], buffer_max
);
69 t1_get_name_index( T1_Face face
,
70 FT_String
* glyph_name
)
75 for ( i
= 0; i
< face
->type1
.num_glyphs
; i
++ )
77 FT_String
* gname
= face
->type1
.glyph_names
[i
];
80 if ( !ft_strcmp( glyph_name
, gname
) )
88 static const FT_Service_GlyphDictRec t1_service_glyph_dict
=
90 (FT_GlyphDict_GetNameFunc
) t1_get_glyph_name
, /* get_name */
91 (FT_GlyphDict_NameIndexFunc
)t1_get_name_index
/* name_index */
96 * POSTSCRIPT NAME SERVICE
101 t1_get_ps_name( T1_Face face
)
103 return (const char*) face
->type1
.font_name
;
107 static const FT_Service_PsFontNameRec t1_service_ps_name
=
109 (FT_PsName_GetFunc
)t1_get_ps_name
/* get_ps_font_name */
114 * MULTIPLE MASTERS SERVICE
118 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
119 static const FT_Service_MultiMastersRec t1_service_multi_masters
=
121 (FT_Get_MM_Func
) T1_Get_Multi_Master
, /* get_mm */
122 (FT_Set_MM_Design_Func
) T1_Set_MM_Design
, /* set_mm_design */
123 (FT_Set_MM_Blend_Func
) T1_Set_MM_Blend
, /* set_mm_blend */
124 (FT_Get_MM_Var_Func
) T1_Get_MM_Var
, /* get_mm_var */
125 (FT_Set_Var_Design_Func
)T1_Set_Var_Design
/* set_var_design */
131 * POSTSCRIPT INFO SERVICE
136 t1_ps_get_font_info( FT_Face face
,
137 PS_FontInfoRec
* afont_info
)
139 *afont_info
= ((T1_Face
)face
)->type1
.font_info
;
146 t1_ps_get_font_extra( FT_Face face
,
147 PS_FontExtraRec
* afont_extra
)
149 *afont_extra
= ((T1_Face
)face
)->type1
.font_extra
;
156 t1_ps_has_glyph_names( FT_Face face
)
165 t1_ps_get_font_private( FT_Face face
,
166 PS_PrivateRec
* afont_private
)
168 *afont_private
= ((T1_Face
)face
)->type1
.private_dict
;
175 t1_ps_get_font_value( FT_Face face
,
181 FT_ULong retval
= 0; /* always >= 1 if valid */
182 FT_ULong value_len
= value_len_
< 0 ? 0 : (FT_ULong
)value_len_
;
184 T1_Face t1face
= (T1_Face
)face
;
185 T1_Font type1
= &t1face
->type1
;
190 case PS_DICT_FONT_TYPE
:
191 retval
= sizeof ( type1
->font_type
);
192 if ( value
&& value_len
>= retval
)
193 *((FT_Byte
*)value
) = type1
->font_type
;
196 case PS_DICT_FONT_MATRIX
:
197 if ( idx
< sizeof ( type1
->font_matrix
) /
198 sizeof ( type1
->font_matrix
.xx
) )
203 retval
= sizeof ( val
);
204 if ( value
&& value_len
>= retval
)
209 val
= type1
->font_matrix
.xx
;
212 val
= type1
->font_matrix
.xy
;
215 val
= type1
->font_matrix
.yx
;
218 val
= type1
->font_matrix
.yy
;
221 *((FT_Fixed
*)value
) = val
;
226 case PS_DICT_FONT_BBOX
:
227 if ( idx
< sizeof ( type1
->font_bbox
) /
228 sizeof ( type1
->font_bbox
.xMin
) )
233 retval
= sizeof ( val
);
234 if ( value
&& value_len
>= retval
)
239 val
= type1
->font_bbox
.xMin
;
242 val
= type1
->font_bbox
.yMin
;
245 val
= type1
->font_bbox
.xMax
;
248 val
= type1
->font_bbox
.yMax
;
251 *((FT_Fixed
*)value
) = val
;
256 case PS_DICT_PAINT_TYPE
:
257 retval
= sizeof ( type1
->paint_type
);
258 if ( value
&& value_len
>= retval
)
259 *((FT_Byte
*)value
) = type1
->paint_type
;
262 case PS_DICT_FONT_NAME
:
263 retval
= ft_strlen( type1
->font_name
) + 1;
264 if ( value
&& value_len
>= retval
)
265 ft_memcpy( value
, (void *)( type1
->font_name
), retval
);
268 case PS_DICT_UNIQUE_ID
:
269 retval
= sizeof ( type1
->private_dict
.unique_id
);
270 if ( value
&& value_len
>= retval
)
271 *((FT_Int
*)value
) = type1
->private_dict
.unique_id
;
274 case PS_DICT_NUM_CHAR_STRINGS
:
275 retval
= sizeof ( type1
->num_glyphs
);
276 if ( value
&& value_len
>= retval
)
277 *((FT_Int
*)value
) = type1
->num_glyphs
;
280 case PS_DICT_CHAR_STRING_KEY
:
281 if ( idx
< (FT_UInt
)type1
->num_glyphs
)
283 retval
= ft_strlen( type1
->glyph_names
[idx
] ) + 1;
284 if ( value
&& value_len
>= retval
)
286 ft_memcpy( value
, (void *)( type1
->glyph_names
[idx
] ), retval
);
287 ((FT_Char
*)value
)[retval
- 1] = (FT_Char
)'\0';
292 case PS_DICT_CHAR_STRING
:
293 if ( idx
< (FT_UInt
)type1
->num_glyphs
)
295 retval
= type1
->charstrings_len
[idx
] + 1;
296 if ( value
&& value_len
>= retval
)
298 ft_memcpy( value
, (void *)( type1
->charstrings
[idx
] ),
300 ((FT_Char
*)value
)[retval
- 1] = (FT_Char
)'\0';
305 case PS_DICT_ENCODING_TYPE
:
306 retval
= sizeof ( type1
->encoding_type
);
307 if ( value
&& value_len
>= retval
)
308 *((T1_EncodingType
*)value
) = type1
->encoding_type
;
311 case PS_DICT_ENCODING_ENTRY
:
312 if ( type1
->encoding_type
== T1_ENCODING_TYPE_ARRAY
&&
313 idx
< (FT_UInt
)type1
->encoding
.num_chars
)
315 retval
= ft_strlen( type1
->encoding
.char_name
[idx
] ) + 1;
316 if ( value
&& value_len
>= retval
)
318 ft_memcpy( value
, (void *)( type1
->encoding
.char_name
[idx
] ),
320 ((FT_Char
*)value
)[retval
- 1] = (FT_Char
)'\0';
325 case PS_DICT_NUM_SUBRS
:
326 retval
= sizeof ( type1
->num_subrs
);
327 if ( value
&& value_len
>= retval
)
328 *((FT_Int
*)value
) = type1
->num_subrs
;
332 if ( idx
< (FT_UInt
)type1
->num_subrs
)
334 retval
= type1
->subrs_len
[idx
] + 1;
335 if ( value
&& value_len
>= retval
)
337 ft_memcpy( value
, (void *)( type1
->subrs
[idx
] ), retval
- 1 );
338 ((FT_Char
*)value
)[retval
- 1] = (FT_Char
)'\0';
344 retval
= sizeof ( type1
->private_dict
.standard_width
[0] );
345 if ( value
&& value_len
>= retval
)
346 *((FT_UShort
*)value
) = type1
->private_dict
.standard_width
[0];
350 retval
= sizeof ( type1
->private_dict
.standard_height
[0] );
351 if ( value
&& value_len
>= retval
)
352 *((FT_UShort
*)value
) = type1
->private_dict
.standard_height
[0];
355 case PS_DICT_NUM_BLUE_VALUES
:
356 retval
= sizeof ( type1
->private_dict
.num_blue_values
);
357 if ( value
&& value_len
>= retval
)
358 *((FT_Byte
*)value
) = type1
->private_dict
.num_blue_values
;
361 case PS_DICT_BLUE_VALUE
:
362 if ( idx
< type1
->private_dict
.num_blue_values
)
364 retval
= sizeof ( type1
->private_dict
.blue_values
[idx
] );
365 if ( value
&& value_len
>= retval
)
366 *((FT_Short
*)value
) = type1
->private_dict
.blue_values
[idx
];
370 case PS_DICT_BLUE_SCALE
:
371 retval
= sizeof ( type1
->private_dict
.blue_scale
);
372 if ( value
&& value_len
>= retval
)
373 *((FT_Fixed
*)value
) = type1
->private_dict
.blue_scale
;
376 case PS_DICT_BLUE_FUZZ
:
377 retval
= sizeof ( type1
->private_dict
.blue_fuzz
);
378 if ( value
&& value_len
>= retval
)
379 *((FT_Int
*)value
) = type1
->private_dict
.blue_fuzz
;
382 case PS_DICT_BLUE_SHIFT
:
383 retval
= sizeof ( type1
->private_dict
.blue_shift
);
384 if ( value
&& value_len
>= retval
)
385 *((FT_Int
*)value
) = type1
->private_dict
.blue_shift
;
388 case PS_DICT_NUM_OTHER_BLUES
:
389 retval
= sizeof ( type1
->private_dict
.num_other_blues
);
390 if ( value
&& value_len
>= retval
)
391 *((FT_Byte
*)value
) = type1
->private_dict
.num_other_blues
;
394 case PS_DICT_OTHER_BLUE
:
395 if ( idx
< type1
->private_dict
.num_other_blues
)
397 retval
= sizeof ( type1
->private_dict
.other_blues
[idx
] );
398 if ( value
&& value_len
>= retval
)
399 *((FT_Short
*)value
) = type1
->private_dict
.other_blues
[idx
];
403 case PS_DICT_NUM_FAMILY_BLUES
:
404 retval
= sizeof ( type1
->private_dict
.num_family_blues
);
405 if ( value
&& value_len
>= retval
)
406 *((FT_Byte
*)value
) = type1
->private_dict
.num_family_blues
;
409 case PS_DICT_FAMILY_BLUE
:
410 if ( idx
< type1
->private_dict
.num_family_blues
)
412 retval
= sizeof ( type1
->private_dict
.family_blues
[idx
] );
413 if ( value
&& value_len
>= retval
)
414 *((FT_Short
*)value
) = type1
->private_dict
.family_blues
[idx
];
418 case PS_DICT_NUM_FAMILY_OTHER_BLUES
:
419 retval
= sizeof ( type1
->private_dict
.num_family_other_blues
);
420 if ( value
&& value_len
>= retval
)
421 *((FT_Byte
*)value
) = type1
->private_dict
.num_family_other_blues
;
424 case PS_DICT_FAMILY_OTHER_BLUE
:
425 if ( idx
< type1
->private_dict
.num_family_other_blues
)
427 retval
= sizeof ( type1
->private_dict
.family_other_blues
[idx
] );
428 if ( value
&& value_len
>= retval
)
429 *((FT_Short
*)value
) = type1
->private_dict
.family_other_blues
[idx
];
433 case PS_DICT_NUM_STEM_SNAP_H
:
434 retval
= sizeof ( type1
->private_dict
.num_snap_widths
);
435 if ( value
&& value_len
>= retval
)
436 *((FT_Byte
*)value
) = type1
->private_dict
.num_snap_widths
;
439 case PS_DICT_STEM_SNAP_H
:
440 if ( idx
< type1
->private_dict
.num_snap_widths
)
442 retval
= sizeof ( type1
->private_dict
.snap_widths
[idx
] );
443 if ( value
&& value_len
>= retval
)
444 *((FT_Short
*)value
) = type1
->private_dict
.snap_widths
[idx
];
448 case PS_DICT_NUM_STEM_SNAP_V
:
449 retval
= sizeof ( type1
->private_dict
.num_snap_heights
);
450 if ( value
&& value_len
>= retval
)
451 *((FT_Byte
*)value
) = type1
->private_dict
.num_snap_heights
;
454 case PS_DICT_STEM_SNAP_V
:
455 if ( idx
< type1
->private_dict
.num_snap_heights
)
457 retval
= sizeof ( type1
->private_dict
.snap_heights
[idx
] );
458 if ( value
&& value_len
>= retval
)
459 *((FT_Short
*)value
) = type1
->private_dict
.snap_heights
[idx
];
463 case PS_DICT_RND_STEM_UP
:
464 retval
= sizeof ( type1
->private_dict
.round_stem_up
);
465 if ( value
&& value_len
>= retval
)
466 *((FT_Bool
*)value
) = type1
->private_dict
.round_stem_up
;
469 case PS_DICT_FORCE_BOLD
:
470 retval
= sizeof ( type1
->private_dict
.force_bold
);
471 if ( value
&& value_len
>= retval
)
472 *((FT_Bool
*)value
) = type1
->private_dict
.force_bold
;
475 case PS_DICT_MIN_FEATURE
:
476 if ( idx
< sizeof ( type1
->private_dict
.min_feature
) /
477 sizeof ( type1
->private_dict
.min_feature
[0] ) )
479 retval
= sizeof ( type1
->private_dict
.min_feature
[idx
] );
480 if ( value
&& value_len
>= retval
)
481 *((FT_Short
*)value
) = type1
->private_dict
.min_feature
[idx
];
486 retval
= sizeof ( type1
->private_dict
.lenIV
);
487 if ( value
&& value_len
>= retval
)
488 *((FT_Int
*)value
) = type1
->private_dict
.lenIV
;
491 case PS_DICT_PASSWORD
:
492 retval
= sizeof ( type1
->private_dict
.password
);
493 if ( value
&& value_len
>= retval
)
494 *((FT_Long
*)value
) = type1
->private_dict
.password
;
497 case PS_DICT_LANGUAGE_GROUP
:
498 retval
= sizeof ( type1
->private_dict
.language_group
);
499 if ( value
&& value_len
>= retval
)
500 *((FT_Long
*)value
) = type1
->private_dict
.language_group
;
503 case PS_DICT_IS_FIXED_PITCH
:
504 retval
= sizeof ( type1
->font_info
.is_fixed_pitch
);
505 if ( value
&& value_len
>= retval
)
506 *((FT_Bool
*)value
) = type1
->font_info
.is_fixed_pitch
;
509 case PS_DICT_UNDERLINE_POSITION
:
510 retval
= sizeof ( type1
->font_info
.underline_position
);
511 if ( value
&& value_len
>= retval
)
512 *((FT_Short
*)value
) = type1
->font_info
.underline_position
;
515 case PS_DICT_UNDERLINE_THICKNESS
:
516 retval
= sizeof ( type1
->font_info
.underline_thickness
);
517 if ( value
&& value_len
>= retval
)
518 *((FT_UShort
*)value
) = type1
->font_info
.underline_thickness
;
521 case PS_DICT_FS_TYPE
:
522 retval
= sizeof ( type1
->font_extra
.fs_type
);
523 if ( value
&& value_len
>= retval
)
524 *((FT_UShort
*)value
) = type1
->font_extra
.fs_type
;
527 case PS_DICT_VERSION
:
528 retval
= ft_strlen( type1
->font_info
.version
) + 1;
529 if ( value
&& value_len
>= retval
)
530 ft_memcpy( value
, (void *)( type1
->font_info
.version
), retval
);
534 retval
= ft_strlen( type1
->font_info
.notice
) + 1;
535 if ( value
&& value_len
>= retval
)
536 ft_memcpy( value
, (void *)( type1
->font_info
.notice
), retval
);
539 case PS_DICT_FULL_NAME
:
540 retval
= ft_strlen( type1
->font_info
.full_name
) + 1;
541 if ( value
&& value_len
>= retval
)
542 ft_memcpy( value
, (void *)( type1
->font_info
.full_name
), retval
);
545 case PS_DICT_FAMILY_NAME
:
546 retval
= ft_strlen( type1
->font_info
.family_name
) + 1;
547 if ( value
&& value_len
>= retval
)
548 ft_memcpy( value
, (void *)( type1
->font_info
.family_name
), retval
);
552 retval
= ft_strlen( type1
->font_info
.weight
) + 1;
553 if ( value
&& value_len
>= retval
)
554 ft_memcpy( value
, (void *)( type1
->font_info
.weight
), retval
);
557 case PS_DICT_ITALIC_ANGLE
:
558 retval
= sizeof ( type1
->font_info
.italic_angle
);
559 if ( value
&& value_len
>= retval
)
560 *((FT_Long
*)value
) = type1
->font_info
.italic_angle
;
564 return retval
== 0 ? -1 : (FT_Long
)retval
;
568 static const FT_Service_PsInfoRec t1_service_ps_info
=
570 (PS_GetFontInfoFunc
) t1_ps_get_font_info
, /* ps_get_font_info */
571 (PS_GetFontExtraFunc
) t1_ps_get_font_extra
, /* ps_get_font_extra */
572 (PS_HasGlyphNamesFunc
) t1_ps_has_glyph_names
, /* ps_has_glyph_names */
573 (PS_GetFontPrivateFunc
)t1_ps_get_font_private
, /* ps_get_font_private */
574 (PS_GetFontValueFunc
) t1_ps_get_font_value
, /* ps_get_font_value */
578 #ifndef T1_CONFIG_OPTION_NO_AFM
579 static const FT_Service_KerningRec t1_service_kerning
=
581 T1_Get_Track_Kerning
, /* get_track */
591 static const FT_ServiceDescRec t1_services
[] =
593 { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME
, &t1_service_ps_name
},
594 { FT_SERVICE_ID_GLYPH_DICT
, &t1_service_glyph_dict
},
595 { FT_SERVICE_ID_FONT_FORMAT
, FT_FONT_FORMAT_TYPE_1
},
596 { FT_SERVICE_ID_POSTSCRIPT_INFO
, &t1_service_ps_info
},
598 #ifndef T1_CONFIG_OPTION_NO_AFM
599 { FT_SERVICE_ID_KERNING
, &t1_service_kerning
},
602 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
603 { FT_SERVICE_ID_MULTI_MASTERS
, &t1_service_multi_masters
},
609 FT_CALLBACK_DEF( FT_Module_Interface
)
610 Get_Interface( FT_Module module
,
611 const FT_String
* t1_interface
)
615 return ft_service_list_lookup( t1_services
, t1_interface
);
619 #ifndef T1_CONFIG_OPTION_NO_AFM
621 /*************************************************************************/
627 /* A driver method used to return the kerning vector between two */
628 /* glyphs of the same face. */
631 /* face :: A handle to the source face object. */
633 /* left_glyph :: The index of the left glyph in the kern pair. */
635 /* right_glyph :: The index of the right glyph in the kern pair. */
638 /* kerning :: The kerning vector. This is in font units for */
639 /* scalable formats, and in pixels for fixed-sizes */
643 /* FreeType error code. 0 means success. */
646 /* Only horizontal layouts (left-to-right & right-to-left) are */
647 /* supported by this function. Other layouts, or more sophisticated */
648 /* kernings are out of scope of this method (the basic driver */
649 /* interface is meant to be simple). */
651 /* They can be implemented by format-specific interfaces. */
654 Get_Kerning( FT_Face t1face
, /* T1_Face */
659 T1_Face face
= (T1_Face
)t1face
;
665 if ( face
->afm_data
)
666 T1_Get_Kerning( (AFM_FontInfo
)face
->afm_data
,
675 #endif /* T1_CONFIG_OPTION_NO_AFM */
678 FT_CALLBACK_TABLE_DEF
679 const FT_Driver_ClassRec t1_driver_class
=
682 FT_MODULE_FONT_DRIVER
|
683 FT_MODULE_DRIVER_SCALABLE
|
684 FT_MODULE_DRIVER_HAS_HINTER
,
686 sizeof ( FT_DriverRec
),
692 0, /* module-specific interface */
694 T1_Driver_Init
, /* FT_Module_Constructor module_init */
695 T1_Driver_Done
, /* FT_Module_Destructor module_done */
696 Get_Interface
, /* FT_Module_Requester get_interface */
699 sizeof ( T1_FaceRec
),
700 sizeof ( T1_SizeRec
),
701 sizeof ( T1_GlyphSlotRec
),
703 T1_Face_Init
, /* FT_Face_InitFunc init_face */
704 T1_Face_Done
, /* FT_Face_DoneFunc done_face */
705 T1_Size_Init
, /* FT_Size_InitFunc init_size */
706 T1_Size_Done
, /* FT_Size_DoneFunc done_size */
707 T1_GlyphSlot_Init
, /* FT_Slot_InitFunc init_slot */
708 T1_GlyphSlot_Done
, /* FT_Slot_DoneFunc done_slot */
710 T1_Load_Glyph
, /* FT_Slot_LoadFunc load_glyph */
712 #ifdef T1_CONFIG_OPTION_NO_AFM
713 0, /* FT_Face_GetKerningFunc get_kerning */
714 0, /* FT_Face_AttachFunc attach_file */
716 Get_Kerning
, /* FT_Face_GetKerningFunc get_kerning */
717 T1_Read_Metrics
, /* FT_Face_AttachFunc attach_file */
719 T1_Get_Advances
, /* FT_Face_GetAdvancesFunc get_advances */
721 T1_Size_Request
, /* FT_Size_RequestFunc request_size */
722 0 /* FT_Size_SelectFunc select_size */