3 FreeType font driver for bdf files
5 Copyright (C) 2001-2008, 2011, 2013 by
6 Francesco Zappa Nardelli
8 Permission is hereby granted, free of charge, to any person obtaining a copy
9 of this software and associated documentation files (the "Software"), to deal
10 in the Software without restriction, including without limitation the rights
11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 copies of the Software, and to permit persons to whom the Software is
13 furnished to do so, subject to the following conditions:
15 The above copyright notice and this permission notice shall be included in
16 all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29 #include FT_INTERNAL_DEBUG_H
30 #include FT_INTERNAL_STREAM_H
31 #include FT_INTERNAL_OBJECTS_H
33 #include FT_TRUETYPE_IDS_H
35 #include FT_SERVICE_BDF_H
36 #include FT_SERVICE_XFREE86_NAME_H
44 /*************************************************************************/
46 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
47 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
48 /* messages during execution. */
51 #define FT_COMPONENT trace_bdfdriver
54 typedef struct BDF_CMapRec_
57 FT_ULong num_encodings
; /* ftobjs.h: FT_CMap->clazz->size */
58 BDF_encoding_el
* encodings
;
60 } BDF_CMapRec
, *BDF_CMap
;
63 FT_CALLBACK_DEF( FT_Error
)
64 bdf_cmap_init( FT_CMap bdfcmap
,
65 FT_Pointer init_data
)
67 BDF_CMap cmap
= (BDF_CMap
)bdfcmap
;
68 BDF_Face face
= (BDF_Face
)FT_CMAP_FACE( cmap
);
69 FT_UNUSED( init_data
);
72 cmap
->num_encodings
= face
->bdffont
->glyphs_used
;
73 cmap
->encodings
= face
->en_table
;
79 FT_CALLBACK_DEF( void )
80 bdf_cmap_done( FT_CMap bdfcmap
)
82 BDF_CMap cmap
= (BDF_CMap
)bdfcmap
;
85 cmap
->encodings
= NULL
;
86 cmap
->num_encodings
= 0;
90 FT_CALLBACK_DEF( FT_UInt
)
91 bdf_cmap_char_index( FT_CMap bdfcmap
,
94 BDF_CMap cmap
= (BDF_CMap
)bdfcmap
;
95 BDF_encoding_el
* encodings
= cmap
->encodings
;
96 FT_ULong min
, max
, mid
; /* num_encodings */
97 FT_UShort result
= 0; /* encodings->glyph */
101 max
= cmap
->num_encodings
;
108 mid
= ( min
+ max
) >> 1;
109 code
= encodings
[mid
].enc
;
111 if ( charcode
== code
)
113 /* increase glyph index by 1 -- */
114 /* we reserve slot 0 for the undefined glyph */
115 result
= encodings
[mid
].glyph
+ 1;
119 if ( charcode
< code
)
129 FT_CALLBACK_DEF( FT_UInt
)
130 bdf_cmap_char_next( FT_CMap bdfcmap
,
131 FT_UInt32
*acharcode
)
133 BDF_CMap cmap
= (BDF_CMap
)bdfcmap
;
134 BDF_encoding_el
* encodings
= cmap
->encodings
;
135 FT_ULong min
, max
, mid
; /* num_encodings */
136 FT_UShort result
= 0; /* encodings->glyph */
137 FT_ULong charcode
= *acharcode
+ 1;
141 max
= cmap
->num_encodings
;
145 FT_ULong code
; /* same as BDF_encoding_el.enc */
148 mid
= ( min
+ max
) >> 1;
149 code
= encodings
[mid
].enc
;
151 if ( charcode
== code
)
153 /* increase glyph index by 1 -- */
154 /* we reserve slot 0 for the undefined glyph */
155 result
= encodings
[mid
].glyph
+ 1;
159 if ( charcode
< code
)
166 if ( min
< cmap
->num_encodings
)
168 charcode
= encodings
[min
].enc
;
169 result
= encodings
[min
].glyph
+ 1;
173 if ( charcode
> 0xFFFFFFFFUL
)
175 FT_TRACE1(( "bdf_cmap_char_next: charcode 0x%x > 32bit API" ));
177 /* XXX: result should be changed to indicate an overflow error */
180 *acharcode
= (FT_UInt32
)charcode
;
185 FT_CALLBACK_TABLE_DEF
186 const FT_CMap_ClassRec bdf_cmap_class
=
188 sizeof ( BDF_CMapRec
),
194 NULL
, NULL
, NULL
, NULL
, NULL
199 bdf_interpret_style( BDF_Face bdf
)
201 FT_Error error
= FT_Err_Ok
;
202 FT_Face face
= FT_FACE( bdf
);
203 FT_Memory memory
= face
->memory
;
204 bdf_font_t
* font
= bdf
->bdffont
;
205 bdf_property_t
* prop
;
207 char* strings
[4] = { NULL
, NULL
, NULL
, NULL
};
208 size_t nn
, len
, lengths
[4];
211 face
->style_flags
= 0;
213 prop
= bdf_get_font_property( font
, (char *)"SLANT" );
214 if ( prop
&& prop
->format
== BDF_ATOM
&&
216 ( *(prop
->value
.atom
) == 'O' || *(prop
->value
.atom
) == 'o' ||
217 *(prop
->value
.atom
) == 'I' || *(prop
->value
.atom
) == 'i' ) )
219 face
->style_flags
|= FT_STYLE_FLAG_ITALIC
;
220 strings
[2] = ( *(prop
->value
.atom
) == 'O' || *(prop
->value
.atom
) == 'o' )
225 prop
= bdf_get_font_property( font
, (char *)"WEIGHT_NAME" );
226 if ( prop
&& prop
->format
== BDF_ATOM
&&
228 ( *(prop
->value
.atom
) == 'B' || *(prop
->value
.atom
) == 'b' ) )
230 face
->style_flags
|= FT_STYLE_FLAG_BOLD
;
231 strings
[1] = (char *)"Bold";
234 prop
= bdf_get_font_property( font
, (char *)"SETWIDTH_NAME" );
235 if ( prop
&& prop
->format
== BDF_ATOM
&&
236 prop
->value
.atom
&& *(prop
->value
.atom
) &&
237 !( *(prop
->value
.atom
) == 'N' || *(prop
->value
.atom
) == 'n' ) )
238 strings
[3] = (char *)(prop
->value
.atom
);
240 prop
= bdf_get_font_property( font
, (char *)"ADD_STYLE_NAME" );
241 if ( prop
&& prop
->format
== BDF_ATOM
&&
242 prop
->value
.atom
&& *(prop
->value
.atom
) &&
243 !( *(prop
->value
.atom
) == 'N' || *(prop
->value
.atom
) == 'n' ) )
244 strings
[0] = (char *)(prop
->value
.atom
);
248 for ( len
= 0, nn
= 0; nn
< 4; nn
++ )
253 lengths
[nn
] = ft_strlen( strings
[nn
] );
254 len
+= lengths
[nn
] + 1;
260 strings
[0] = (char *)"Regular";
261 lengths
[0] = ft_strlen( strings
[0] );
262 len
= lengths
[0] + 1;
269 if ( FT_ALLOC( face
->style_name
, len
) )
272 s
= face
->style_name
;
274 for ( nn
= 0; nn
< 4; nn
++ )
276 char* src
= strings
[nn
];
284 /* separate elements with a space */
285 if ( s
!= face
->style_name
)
288 ft_memcpy( s
, src
, len
);
290 /* need to convert spaces to dashes for */
291 /* add_style_name and setwidth_name */
292 if ( nn
== 0 || nn
== 3 )
297 for ( mm
= 0; mm
< len
; mm
++ )
311 FT_CALLBACK_DEF( void )
312 BDF_Face_Done( FT_Face bdfface
) /* BDF_Face */
314 BDF_Face face
= (BDF_Face
)bdfface
;
321 memory
= FT_FACE_MEMORY( face
);
323 bdf_free_font( face
->bdffont
);
325 FT_FREE( face
->en_table
);
327 FT_FREE( face
->charset_encoding
);
328 FT_FREE( face
->charset_registry
);
329 FT_FREE( bdfface
->family_name
);
330 FT_FREE( bdfface
->style_name
);
332 FT_FREE( bdfface
->available_sizes
);
334 FT_FREE( face
->bdffont
);
338 FT_CALLBACK_DEF( FT_Error
)
339 BDF_Face_Init( FT_Stream stream
,
340 FT_Face bdfface
, /* BDF_Face */
343 FT_Parameter
* params
)
345 FT_Error error
= FT_Err_Ok
;
346 BDF_Face face
= (BDF_Face
)bdfface
;
347 FT_Memory memory
= FT_FACE_MEMORY( face
);
349 bdf_font_t
* font
= NULL
;
350 bdf_options_t options
;
352 FT_UNUSED( num_params
);
356 FT_TRACE2(( "BDF driver\n" ));
358 if ( FT_STREAM_SEEK( 0 ) )
361 options
.correct_metrics
= 1; /* FZ XXX: options semantics */
362 options
.keep_unencoded
= 1;
363 options
.keep_comments
= 0;
364 options
.font_spacing
= BDF_PROPORTIONAL
;
366 error
= bdf_load_font( stream
, memory
, &options
, &font
);
367 if ( FT_ERR_EQ( error
, Missing_Startfont_Field
) )
369 FT_TRACE2(( " not a BDF file\n" ));
375 /* we have a bdf font: let's construct the face object */
376 face
->bdffont
= font
;
378 /* BDF could not have multiple face in single font file.
379 * XXX: non-zero face_index is already invalid argument, but
380 * Type1, Type42 driver has a convention to return
381 * an invalid argument error when the font could be
382 * opened by the specified driver.
384 if ( face_index
> 0 ) {
385 FT_ERROR(( "BDF_Face_Init: invalid face index\n" ));
386 BDF_Face_Done( bdfface
);
387 return FT_THROW( Invalid_Argument
);
391 bdf_property_t
* prop
= NULL
;
394 FT_TRACE4(( " number of glyphs: allocated %d (used %d)\n",
396 font
->glyphs_used
));
397 FT_TRACE4(( " number of unencoded glyphs: allocated %d (used %d)\n",
398 font
->unencoded_size
,
399 font
->unencoded_used
));
401 bdfface
->num_faces
= 1;
402 bdfface
->face_index
= 0;
403 bdfface
->face_flags
= FT_FACE_FLAG_FIXED_SIZES
|
404 FT_FACE_FLAG_HORIZONTAL
|
405 FT_FACE_FLAG_FAST_GLYPHS
;
407 prop
= bdf_get_font_property( font
, "SPACING" );
408 if ( prop
&& prop
->format
== BDF_ATOM
&&
410 ( *(prop
->value
.atom
) == 'M' || *(prop
->value
.atom
) == 'm' ||
411 *(prop
->value
.atom
) == 'C' || *(prop
->value
.atom
) == 'c' ) )
412 bdfface
->face_flags
|= FT_FACE_FLAG_FIXED_WIDTH
;
414 /* FZ XXX: TO DO: FT_FACE_FLAGS_VERTICAL */
415 /* FZ XXX: I need a font to implement this */
417 prop
= bdf_get_font_property( font
, "FAMILY_NAME" );
418 if ( prop
&& prop
->value
.atom
)
420 if ( FT_STRDUP( bdfface
->family_name
, prop
->value
.atom
) )
424 bdfface
->family_name
= 0;
426 if ( ( error
= bdf_interpret_style( face
) ) != 0 )
429 /* the number of glyphs (with one slot for the undefined glyph */
430 /* at position 0 and all unencoded glyphs) */
431 bdfface
->num_glyphs
= font
->glyphs_size
+ 1;
433 bdfface
->num_fixed_sizes
= 1;
434 if ( FT_NEW_ARRAY( bdfface
->available_sizes
, 1 ) )
438 FT_Bitmap_Size
* bsize
= bdfface
->available_sizes
;
439 FT_Short resolution_x
= 0, resolution_y
= 0;
442 FT_MEM_ZERO( bsize
, sizeof ( FT_Bitmap_Size
) );
444 bsize
->height
= (FT_Short
)( font
->font_ascent
+ font
->font_descent
);
446 prop
= bdf_get_font_property( font
, "AVERAGE_WIDTH" );
448 bsize
->width
= (FT_Short
)( ( prop
->value
.l
+ 5 ) / 10 );
450 bsize
->width
= (FT_Short
)( bsize
->height
* 2/3 );
452 prop
= bdf_get_font_property( font
, "POINT_SIZE" );
454 /* convert from 722.7 decipoints to 72 points per inch */
456 (FT_Pos
)( ( prop
->value
.l
* 64 * 7200 + 36135L ) / 72270L );
458 bsize
->size
= bsize
->width
<< 6;
460 prop
= bdf_get_font_property( font
, "PIXEL_SIZE" );
462 bsize
->y_ppem
= (FT_Short
)prop
->value
.l
<< 6;
464 prop
= bdf_get_font_property( font
, "RESOLUTION_X" );
466 resolution_x
= (FT_Short
)prop
->value
.l
;
468 prop
= bdf_get_font_property( font
, "RESOLUTION_Y" );
470 resolution_y
= (FT_Short
)prop
->value
.l
;
472 if ( bsize
->y_ppem
== 0 )
474 bsize
->y_ppem
= bsize
->size
;
476 bsize
->y_ppem
= bsize
->y_ppem
* resolution_y
/ 72;
478 if ( resolution_x
&& resolution_y
)
479 bsize
->x_ppem
= bsize
->y_ppem
* resolution_x
/ resolution_y
;
481 bsize
->x_ppem
= bsize
->y_ppem
;
486 bdf_glyph_t
* cur
= font
->glyphs
;
490 if ( FT_NEW_ARRAY( face
->en_table
, font
->glyphs_size
) )
493 face
->default_glyph
= 0;
494 for ( n
= 0; n
< font
->glyphs_size
; n
++ )
496 (face
->en_table
[n
]).enc
= cur
[n
].encoding
;
497 FT_TRACE4(( " idx %d, val 0x%lX\n", n
, cur
[n
].encoding
));
498 (face
->en_table
[n
]).glyph
= (FT_Short
)n
;
500 if ( cur
[n
].encoding
== font
->default_char
)
502 if ( n
< FT_UINT_MAX
)
503 face
->default_glyph
= (FT_UInt
)n
;
505 FT_TRACE1(( "BDF_Face_Init:"
506 " idx %d is too large for this system\n", n
));
513 bdf_property_t
*charset_registry
= 0, *charset_encoding
= 0;
514 FT_Bool unicode_charmap
= 0;
518 bdf_get_font_property( font
, "CHARSET_REGISTRY" );
520 bdf_get_font_property( font
, "CHARSET_ENCODING" );
521 if ( charset_registry
&& charset_encoding
)
523 if ( charset_registry
->format
== BDF_ATOM
&&
524 charset_encoding
->format
== BDF_ATOM
&&
525 charset_registry
->value
.atom
&&
526 charset_encoding
->value
.atom
)
531 if ( FT_STRDUP( face
->charset_encoding
,
532 charset_encoding
->value
.atom
) ||
533 FT_STRDUP( face
->charset_registry
,
534 charset_registry
->value
.atom
) )
537 /* Uh, oh, compare first letters manually to avoid dependency */
539 s
= face
->charset_registry
;
540 if ( ( s
[0] == 'i' || s
[0] == 'I' ) &&
541 ( s
[1] == 's' || s
[1] == 'S' ) &&
542 ( s
[2] == 'o' || s
[2] == 'O' ) )
545 if ( !ft_strcmp( s
, "10646" ) ||
546 ( !ft_strcmp( s
, "8859" ) &&
547 !ft_strcmp( face
->charset_encoding
, "1" ) ) )
552 FT_CharMapRec charmap
;
555 charmap
.face
= FT_FACE( face
);
556 charmap
.encoding
= FT_ENCODING_NONE
;
557 /* initial platform/encoding should indicate unset status? */
558 charmap
.platform_id
= TT_PLATFORM_APPLE_UNICODE
;
559 charmap
.encoding_id
= TT_APPLE_ID_DEFAULT
;
561 if ( unicode_charmap
)
563 charmap
.encoding
= FT_ENCODING_UNICODE
;
564 charmap
.platform_id
= TT_PLATFORM_MICROSOFT
;
565 charmap
.encoding_id
= TT_MS_ID_UNICODE_CS
;
568 error
= FT_CMap_New( &bdf_cmap_class
, NULL
, &charmap
, NULL
);
571 /* Select default charmap */
572 if ( bdfface
->num_charmaps
)
573 bdfface
->charmap
= bdfface
->charmaps
[0];
581 /* otherwise assume Adobe standard encoding */
584 FT_CharMapRec charmap
;
587 charmap
.face
= FT_FACE( face
);
588 charmap
.encoding
= FT_ENCODING_ADOBE_STANDARD
;
589 charmap
.platform_id
= TT_PLATFORM_ADOBE
;
590 charmap
.encoding_id
= TT_ADOBE_ID_STANDARD
;
592 error
= FT_CMap_New( &bdf_cmap_class
, NULL
, &charmap
, NULL
);
594 /* Select default charmap */
595 if ( bdfface
->num_charmaps
)
596 bdfface
->charmap
= bdfface
->charmaps
[0];
605 BDF_Face_Done( bdfface
);
606 return FT_THROW( Unknown_File_Format
);
610 FT_CALLBACK_DEF( FT_Error
)
611 BDF_Size_Select( FT_Size size
,
612 FT_ULong strike_index
)
614 bdf_font_t
* bdffont
= ( (BDF_Face
)size
->face
)->bdffont
;
617 FT_Select_Metrics( size
->face
, strike_index
);
619 size
->metrics
.ascender
= bdffont
->font_ascent
<< 6;
620 size
->metrics
.descender
= -bdffont
->font_descent
<< 6;
621 size
->metrics
.max_advance
= bdffont
->bbx
.width
<< 6;
627 FT_CALLBACK_DEF( FT_Error
)
628 BDF_Size_Request( FT_Size size
,
629 FT_Size_Request req
)
631 FT_Face face
= size
->face
;
632 FT_Bitmap_Size
* bsize
= face
->available_sizes
;
633 bdf_font_t
* bdffont
= ( (BDF_Face
)face
)->bdffont
;
634 FT_Error error
= FT_ERR( Invalid_Pixel_Size
);
638 height
= FT_REQUEST_HEIGHT( req
);
639 height
= ( height
+ 32 ) >> 6;
643 case FT_SIZE_REQUEST_TYPE_NOMINAL
:
644 if ( height
== ( ( bsize
->y_ppem
+ 32 ) >> 6 ) )
648 case FT_SIZE_REQUEST_TYPE_REAL_DIM
:
649 if ( height
== ( bdffont
->font_ascent
+
650 bdffont
->font_descent
) )
655 error
= FT_THROW( Unimplemented_Feature
);
662 return BDF_Size_Select( size
, 0 );
667 FT_CALLBACK_DEF( FT_Error
)
668 BDF_Glyph_Load( FT_GlyphSlot slot
,
671 FT_Int32 load_flags
)
673 BDF_Face bdf
= (BDF_Face
)FT_SIZE_FACE( size
);
674 FT_Face face
= FT_FACE( bdf
);
675 FT_Error error
= FT_Err_Ok
;
676 FT_Bitmap
* bitmap
= &slot
->bitmap
;
678 int bpp
= bdf
->bdffont
->bpp
;
680 FT_UNUSED( load_flags
);
683 if ( !face
|| glyph_index
>= (FT_UInt
)face
->num_glyphs
)
685 error
= FT_THROW( Invalid_Argument
);
689 FT_TRACE1(( "BDF_Glyph_Load: glyph index %d\n", glyph_index
));
691 /* index 0 is the undefined glyph */
692 if ( glyph_index
== 0 )
693 glyph_index
= bdf
->default_glyph
;
697 /* slot, bitmap => freetype, glyph => bdflib */
698 glyph
= bdf
->bdffont
->glyphs
[glyph_index
];
700 bitmap
->rows
= glyph
.bbx
.height
;
701 bitmap
->width
= glyph
.bbx
.width
;
702 if ( glyph
.bpr
> INT_MAX
)
703 FT_TRACE1(( "BDF_Glyph_Load: too large pitch %d is truncated\n",
705 bitmap
->pitch
= (int)glyph
.bpr
; /* same as FT_Bitmap.pitch */
707 /* note: we don't allocate a new array to hold the bitmap; */
708 /* we can simply point to it */
709 ft_glyphslot_set_bitmap( slot
, glyph
.bitmap
);
714 bitmap
->pixel_mode
= FT_PIXEL_MODE_MONO
;
717 bitmap
->pixel_mode
= FT_PIXEL_MODE_GRAY2
;
720 bitmap
->pixel_mode
= FT_PIXEL_MODE_GRAY4
;
723 bitmap
->pixel_mode
= FT_PIXEL_MODE_GRAY
;
724 bitmap
->num_grays
= 256;
728 slot
->format
= FT_GLYPH_FORMAT_BITMAP
;
729 slot
->bitmap_left
= glyph
.bbx
.x_offset
;
730 slot
->bitmap_top
= glyph
.bbx
.ascent
;
732 slot
->metrics
.horiAdvance
= glyph
.dwidth
<< 6;
733 slot
->metrics
.horiBearingX
= glyph
.bbx
.x_offset
<< 6;
734 slot
->metrics
.horiBearingY
= glyph
.bbx
.ascent
<< 6;
735 slot
->metrics
.width
= bitmap
->width
<< 6;
736 slot
->metrics
.height
= bitmap
->rows
<< 6;
739 * XXX DWIDTH1 and VVECTOR should be parsed and
740 * used here, provided such fonts do exist.
742 ft_synthesize_vertical_metrics( &slot
->metrics
,
743 bdf
->bdffont
->bbx
.height
<< 6 );
757 bdf_get_bdf_property( BDF_Face face
,
758 const char* prop_name
,
759 BDF_PropertyRec
*aproperty
)
761 bdf_property_t
* prop
;
764 FT_ASSERT( face
&& face
->bdffont
);
766 prop
= bdf_get_font_property( face
->bdffont
, prop_name
);
769 switch ( prop
->format
)
772 aproperty
->type
= BDF_PROPERTY_TYPE_ATOM
;
773 aproperty
->u
.atom
= prop
->value
.atom
;
777 if ( prop
->value
.l
> 0x7FFFFFFFL
|| prop
->value
.l
< ( -1 - 0x7FFFFFFFL
) )
779 FT_TRACE1(( "bdf_get_bdf_property:"
780 " too large integer 0x%x is truncated\n" ));
782 aproperty
->type
= BDF_PROPERTY_TYPE_INTEGER
;
783 aproperty
->u
.integer
= (FT_Int32
)prop
->value
.l
;
787 if ( prop
->value
.ul
> 0xFFFFFFFFUL
)
789 FT_TRACE1(( "bdf_get_bdf_property:"
790 " too large cardinal 0x%x is truncated\n" ));
792 aproperty
->type
= BDF_PROPERTY_TYPE_CARDINAL
;
793 aproperty
->u
.cardinal
= (FT_UInt32
)prop
->value
.ul
;
803 return FT_THROW( Invalid_Argument
);
808 bdf_get_charset_id( BDF_Face face
,
809 const char* *acharset_encoding
,
810 const char* *acharset_registry
)
812 *acharset_encoding
= face
->charset_encoding
;
813 *acharset_registry
= face
->charset_registry
;
819 static const FT_Service_BDFRec bdf_service_bdf
=
821 (FT_BDF_GetCharsetIdFunc
)bdf_get_charset_id
,
822 (FT_BDF_GetPropertyFunc
) bdf_get_bdf_property
832 static const FT_ServiceDescRec bdf_services
[] =
834 { FT_SERVICE_ID_BDF
, &bdf_service_bdf
},
835 { FT_SERVICE_ID_XF86_NAME
, FT_XF86_FORMAT_BDF
},
840 FT_CALLBACK_DEF( FT_Module_Interface
)
841 bdf_driver_requester( FT_Module module
,
846 return ft_service_list_lookup( bdf_services
, name
);
851 FT_CALLBACK_TABLE_DEF
852 const FT_Driver_ClassRec bdf_driver_class
=
855 FT_MODULE_FONT_DRIVER
|
856 FT_MODULE_DRIVER_NO_OUTLINES
,
857 sizeof ( FT_DriverRec
),
865 0, /* FT_Module_Constructor */
866 0, /* FT_Module_Destructor */
870 sizeof ( BDF_FaceRec
),
871 sizeof ( FT_SizeRec
),
872 sizeof ( FT_GlyphSlotRec
),
876 0, /* FT_Size_InitFunc */
877 0, /* FT_Size_DoneFunc */
878 0, /* FT_Slot_InitFunc */
879 0, /* FT_Slot_DoneFunc */
883 0, /* FT_Face_GetKerningFunc */
884 0, /* FT_Face_AttachFunc */
885 0, /* FT_Face_GetAdvancesFunc */