50#define FT_COMPONENT bdfdriver
56 FT_ULong num_encodings;
57 BDF_encoding_el* encodings;
59 } BDF_CMapRec, *BDF_CMap;
62 FT_CALLBACK_DEF( FT_Error )
63 bdf_cmap_init( FT_CMap bdfcmap,
64 FT_Pointer init_data )
66 BDF_CMap cmap = (BDF_CMap)bdfcmap;
67 BDF_Face face = (BDF_Face)FT_CMAP_FACE( cmap );
68 FT_UNUSED( init_data );
71 cmap->num_encodings = face->bdffont->glyphs_used;
72 cmap->encodings = face->en_table;
78 FT_CALLBACK_DEF(
void )
79 bdf_cmap_done( FT_CMap bdfcmap )
81 BDF_CMap cmap = (BDF_CMap)bdfcmap;
84 cmap->encodings = NULL;
85 cmap->num_encodings = 0;
89 FT_CALLBACK_DEF( FT_UInt )
90 bdf_cmap_char_index( FT_CMap bdfcmap,
93 BDF_CMap cmap = (BDF_CMap)bdfcmap;
94 BDF_encoding_el* encodings = cmap->encodings;
98 FT_ULong max = cmap->num_encodings;
99 FT_ULong mid = ( min + max ) >> 1;
104 FT_ULong
code = encodings[mid].enc;
107 if ( charcode ==
code )
111 result = encodings[mid].glyph + 1;
115 if ( charcode <
code )
121 mid += charcode -
code;
122 if ( mid >= max || mid < min )
123 mid = ( min + max ) >> 1;
130 FT_CALLBACK_DEF( FT_UInt )
131 bdf_cmap_char_next( FT_CMap bdfcmap,
132 FT_UInt32 *acharcode )
134 BDF_CMap cmap = (BDF_CMap)bdfcmap;
135 BDF_encoding_el* encodings = cmap->encodings;
136 FT_UShort result = 0;
137 FT_ULong charcode = *acharcode + 1;
140 FT_ULong max = cmap->num_encodings;
141 FT_ULong mid = ( min + max ) >> 1;
146 FT_ULong
code = encodings[mid].enc;
149 if ( charcode ==
code )
153 result = encodings[mid].glyph + 1;
157 if ( charcode <
code )
163 mid += charcode -
code;
164 if ( mid >= max || mid < min )
165 mid = ( min + max ) >> 1;
169 if ( min < cmap->num_encodings )
171 charcode = encodings[min].enc;
172 result = encodings[min].glyph + 1;
176 if ( charcode > 0xFFFFFFFFUL )
178 FT_TRACE1((
"bdf_cmap_char_next: charcode 0x%lx > 32bit API",
184 *acharcode = (FT_UInt32)charcode;
190 const FT_CMap_ClassRec bdf_cmap_class =
192 sizeof ( BDF_CMapRec ),
198 NULL, NULL, NULL, NULL, NULL
203 bdf_interpret_style( BDF_Face bdf )
205 FT_Error error = FT_Err_Ok;
206 FT_Face face = FT_FACE( bdf );
207 FT_Memory memory = face->memory;
208 bdf_font_t* font = bdf->bdffont;
209 bdf_property_t* prop;
211 const char* strings[4] = { NULL, NULL, NULL, NULL };
212 size_t lengths[4], nn, len;
215 face->style_flags = 0;
217 prop = bdf_get_font_property( font,
"SLANT" );
218 if ( prop && prop->format == BDF_ATOM &&
220 ( *(prop->value.atom) ==
'O' || *(prop->value.atom) ==
'o' ||
221 *(prop->value.atom) ==
'I' || *(prop->value.atom) ==
'i' ) )
223 face->style_flags |= FT_STYLE_FLAG_ITALIC;
224 strings[2] = ( *(prop->value.atom) ==
'O' || *(prop->value.atom) ==
'o' )
229 prop = bdf_get_font_property( font,
"WEIGHT_NAME" );
230 if ( prop && prop->format == BDF_ATOM &&
232 ( *(prop->value.atom) ==
'B' || *(prop->value.atom) ==
'b' ) )
234 face->style_flags |= FT_STYLE_FLAG_BOLD;
238 prop = bdf_get_font_property( font,
"SETWIDTH_NAME" );
239 if ( prop && prop->format == BDF_ATOM &&
240 prop->value.atom && *(prop->value.atom) &&
241 !( *(prop->value.atom) ==
'N' || *(prop->value.atom) ==
'n' ) )
242 strings[3] = (
const char *)(prop->value.atom);
244 prop = bdf_get_font_property( font,
"ADD_STYLE_NAME" );
245 if ( prop && prop->format == BDF_ATOM &&
246 prop->value.atom && *(prop->value.atom) &&
247 !( *(prop->value.atom) ==
'N' || *(prop->value.atom) ==
'n' ) )
248 strings[0] = (
const char *)(prop->value.atom);
250 for ( len = 0, nn = 0; nn < 4; nn++ )
255 lengths[nn] = ft_strlen( strings[nn] );
256 len += lengths[nn] + 1;
262 strings[0] =
"Regular";
263 lengths[0] = ft_strlen( strings[0] );
264 len = lengths[0] + 1;
271 if ( FT_QALLOC( face->style_name, len ) )
274 s = face->style_name;
276 for ( nn = 0; nn < 4; nn++ )
278 const char* src = strings[nn];
287 if ( s != face->style_name )
290 ft_memcpy( s, src, len );
294 if ( nn == 0 || nn == 3 )
299 for ( mm = 0; mm < len; mm++ )
313 FT_CALLBACK_DEF(
void )
314 BDF_Face_Done( FT_Face face )
316 BDF_Face bdfface = (BDF_Face)face;
323 memory = FT_FACE_MEMORY( face );
325 bdf_free_font( bdfface->bdffont );
327 FT_FREE( bdfface->en_table );
329 FT_FREE( bdfface->charset_encoding );
330 FT_FREE( bdfface->charset_registry );
331 FT_FREE( face->family_name );
332 FT_FREE( face->style_name );
334 FT_FREE( face->available_sizes );
336 FT_FREE( bdfface->bdffont );
340 FT_CALLBACK_DEF( FT_Error )
341 BDF_Face_Init( FT_Stream stream,
345 FT_Parameter* params )
347 FT_Error error = FT_Err_Ok;
348 BDF_Face bdfface = (BDF_Face)face;
349 FT_Memory memory = FT_FACE_MEMORY( face );
351 bdf_font_t* font = NULL;
353 FT_UNUSED( num_params );
357 FT_TRACE2((
"BDF driver\n" ));
359 if ( FT_STREAM_SEEK( 0 ) )
362 error = bdf_load_font( stream, memory,
363 BDF_CORRECT_METRICS | BDF_KEEP_UNENCODED, &font );
364 if ( FT_ERR_EQ( error, Missing_Startfont_Field ) )
366 FT_TRACE2((
" not a BDF file\n" ));
373 bdfface->bdffont = font;
381 if ( face_index > 0 && ( face_index & 0xFFFF ) > 0 )
383 FT_ERROR((
"BDF_Face_Init: invalid face index\n" ));
384 BDF_Face_Done( face );
385 return FT_THROW( Invalid_Argument );
389 bdf_property_t* prop = NULL;
392 FT_TRACE4((
" number of glyphs: allocated %lu (used %lu)\n",
394 font->glyphs_used ));
395 FT_TRACE4((
" number of unencoded glyphs: allocated %lu (used %lu)\n",
396 font->unencoded_size,
397 font->unencoded_used ));
400 face->face_index = 0;
402 face->face_flags |= FT_FACE_FLAG_FIXED_SIZES |
403 FT_FACE_FLAG_HORIZONTAL;
405 prop = bdf_get_font_property( font,
"SPACING" );
406 if ( prop && prop->value.atom )
408 if ( prop->value.atom[0] ==
'p' || prop->value.atom[0] ==
'P' )
409 font->spacing = BDF_PROPORTIONAL;
410 else if ( prop->value.atom[0] ==
'm' || prop->value.atom[0] ==
'M' )
411 font->spacing = BDF_MONOWIDTH;
412 else if ( prop->value.atom[0] ==
'c' || prop->value.atom[0] ==
'C' )
413 font->spacing = BDF_CHARCELL;
416 if ( font->spacing == BDF_MONOWIDTH ||
417 font->spacing == BDF_CHARCELL )
418 face->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
423 prop = bdf_get_font_property( font,
"FAMILY_NAME" );
424 if ( prop && prop->value.atom )
426 if ( FT_STRDUP( face->family_name, prop->value.atom ) )
430 face->family_name = NULL;
432 if ( FT_SET_ERROR( bdf_interpret_style( bdfface ) ) )
437 face->num_glyphs = (FT_Long)( font->glyphs_size + 1 );
439 face->num_fixed_sizes = 1;
440 if ( FT_NEW( face->available_sizes ) )
444 FT_Bitmap_Size* bsize = face->available_sizes;
445 FT_Short resolution_x = 0;
446 FT_Short resolution_y = 0;
450 prop = bdf_get_font_property( font,
"FONT_ASCENT" );
452 font->font_ascent = prop->value.l;
454 font->font_ascent = font->bbx.ascent;
455 if ( font->font_ascent > 0x7FFF )
456 font->font_ascent = 0x7FFF;
457 else if ( font->font_ascent < 0 )
458 font->font_ascent = 0;
460 prop = bdf_get_font_property( font,
"FONT_DESCENT" );
462 font->font_descent = prop->value.l;
464 font->font_descent = font->bbx.descent;
465 if ( font->font_descent > 0x7FFF )
466 font->font_descent = 0x7FFF;
467 else if ( font->font_descent < 0 )
468 font->font_descent = 0;
470 bsize->height = (FT_Short)( font->font_ascent + font->font_descent );
472 prop = bdf_get_font_property( font,
"AVERAGE_WIDTH" );
475#ifdef FT_DEBUG_LEVEL_TRACE
476 if ( prop->value.l < 0 )
477 FT_TRACE0((
"BDF_Face_Init: negative average width\n" ));
479 if ( prop->value.l > 0x7FFFL * 10 - 5 ||
480 prop->value.l < -( 0x7FFFL * 10 - 5 ) )
482 bsize->width = 0x7FFF;
483 FT_TRACE0((
"BDF_Face_Init: clamping average width to value %d\n",
487 bsize->width = FT_ABS( (FT_Short)( ( prop->value.l + 5 ) / 10 ) );
492 bsize->width = ( bsize->height * 2 + 1 ) / 3;
495 prop = bdf_get_font_property( font,
"POINT_SIZE" );
498#ifdef FT_DEBUG_LEVEL_TRACE
499 if ( prop->value.l < 0 )
500 FT_TRACE0((
"BDF_Face_Init: negative point size\n" ));
503 if ( prop->value.l > 0x504C2L ||
504 prop->value.l < -0x504C2L )
506 bsize->size = 0x7FFF;
507 FT_TRACE0((
"BDF_Face_Init: clamping point size to value %ld\n",
511 bsize->size = FT_MulDiv( FT_ABS( prop->value.l ),
515 else if ( font->point_size )
517 if ( font->point_size > 0x7FFF )
519 bsize->size = 0x7FFF;
520 FT_TRACE0((
"BDF_Face_Init: clamping point size to value %ld\n",
524 bsize->size = (FT_Pos)font->point_size << 6;
529 bsize->size = bsize->width * 64;
532 prop = bdf_get_font_property( font,
"PIXEL_SIZE" );
535#ifdef FT_DEBUG_LEVEL_TRACE
536 if ( prop->value.l < 0 )
537 FT_TRACE0((
"BDF_Face_Init: negative pixel size\n" ));
539 if ( prop->value.l > 0x7FFF || prop->value.l < -0x7FFF )
541 bsize->y_ppem = 0x7FFF << 6;
542 FT_TRACE0((
"BDF_Face_Init: clamping pixel size to value %ld\n",
546 bsize->y_ppem = FT_ABS( (FT_Short)prop->value.l ) << 6;
549 prop = bdf_get_font_property( font,
"RESOLUTION_X" );
551 value = prop->value.l;
553 value = (long)font->resolution_x;
556#ifdef FT_DEBUG_LEVEL_TRACE
558 FT_TRACE0((
"BDF_Face_Init: negative X resolution\n" ));
560 if ( value > 0x7FFF || value < -0x7FFF )
562 resolution_x = 0x7FFF;
563 FT_TRACE0((
"BDF_Face_Init: clamping X resolution to value %d\n",
567 resolution_x = FT_ABS( (FT_Short)value );
570 prop = bdf_get_font_property( font,
"RESOLUTION_Y" );
572 value = prop->value.l;
574 value = (long)font->resolution_y;
577#ifdef FT_DEBUG_LEVEL_TRACE
579 FT_TRACE0((
"BDF_Face_Init: negative Y resolution\n" ));
581 if ( value > 0x7FFF || value < -0x7FFF )
583 resolution_y = 0x7FFF;
584 FT_TRACE0((
"BDF_Face_Init: clamping Y resolution to value %d\n",
588 resolution_y = FT_ABS( (FT_Short)value );
591 if ( bsize->y_ppem == 0 )
593 bsize->y_ppem = bsize->size;
595 bsize->y_ppem = FT_MulDiv( bsize->y_ppem, resolution_y, 72 );
597 if ( resolution_x && resolution_y )
598 bsize->x_ppem = FT_MulDiv( bsize->y_ppem,
602 bsize->x_ppem = bsize->y_ppem;
604 prop = bdf_get_font_property( font,
"DEFAULT_CHAR" );
606 font->default_char = prop->value.ul;
608 font->default_char = ~0UL;
613 bdf_glyph_t* cur = font->glyphs;
617 if ( FT_QNEW_ARRAY( bdfface->en_table, font->glyphs_size ) )
620 bdfface->default_glyph = 0;
621 for ( n = 0; n < font->glyphs_size; n++ )
623 (bdfface->en_table[n]).enc = cur[n].encoding;
624 FT_TRACE4((
" idx %lu, val 0x%lX\n", n, cur[n].encoding ));
625 (bdfface->en_table[n]).glyph = (FT_UShort)n;
627 if ( cur[n].encoding == font->default_char )
629 if ( n < FT_UINT_MAX )
630 bdfface->default_glyph = (FT_UInt)n;
632 FT_TRACE1((
"BDF_Face_Init:"
633 " idx %lu is too large for this system\n", n ));
640 bdf_property_t *charset_registry, *charset_encoding;
641 FT_Bool unicode_charmap = 0;
645 bdf_get_font_property( font,
"CHARSET_REGISTRY" );
647 bdf_get_font_property( font,
"CHARSET_ENCODING" );
648 if ( charset_registry && charset_encoding )
650 if ( charset_registry->format == BDF_ATOM &&
651 charset_encoding->format == BDF_ATOM &&
652 charset_registry->value.atom &&
653 charset_encoding->value.atom )
658 if ( FT_STRDUP( bdfface->charset_encoding,
659 charset_encoding->value.atom ) ||
660 FT_STRDUP( bdfface->charset_registry,
661 charset_registry->value.atom ) )
666 s = bdfface->charset_registry;
667 if ( ( s[0] ==
'i' || s[0] ==
'I' ) &&
668 ( s[1] ==
's' || s[1] ==
'S' ) &&
669 ( s[2] ==
'o' || s[2] ==
'O' ) )
672 if ( !ft_strcmp( s,
"10646" ) ||
673 ( !ft_strcmp( s,
"8859" ) &&
674 !ft_strcmp( bdfface->charset_encoding,
"1" ) ) )
677 else if ( !ft_strcmp( s,
"646.1991" ) &&
678 !ft_strcmp( bdfface->charset_encoding,
"IRV" ) )
683 FT_CharMapRec charmap;
687 charmap.encoding = FT_ENCODING_NONE;
689 charmap.platform_id = TT_PLATFORM_APPLE_UNICODE;
690 charmap.encoding_id = TT_APPLE_ID_DEFAULT;
692 if ( unicode_charmap )
694 charmap.encoding = FT_ENCODING_UNICODE;
695 charmap.platform_id = TT_PLATFORM_MICROSOFT;
696 charmap.encoding_id = TT_MS_ID_UNICODE_CS;
699 error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL );
709 FT_CharMapRec charmap;
713 charmap.encoding = FT_ENCODING_ADOBE_STANDARD;
714 charmap.platform_id = TT_PLATFORM_ADOBE;
715 charmap.encoding_id = TT_ADOBE_ID_STANDARD;
717 error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL );
720 if ( face->num_charmaps )
721 face->charmap = face->charmaps[0];
730 BDF_Face_Done( face );
731 return FT_THROW( Unknown_File_Format );
735 FT_CALLBACK_DEF( FT_Error )
736 BDF_Size_Select( FT_Size size,
737 FT_ULong strike_index )
739 bdf_font_t* bdffont = ( (BDF_Face)size->face )->bdffont;
742 FT_Select_Metrics( size->face, strike_index );
744 size->metrics.ascender = bdffont->font_ascent * 64;
745 size->metrics.descender = -bdffont->font_descent * 64;
746 size->metrics.max_advance = bdffont->bbx.width * 64;
752 FT_CALLBACK_DEF( FT_Error )
753 BDF_Size_Request( FT_Size size,
754 FT_Size_Request req )
756 FT_Face face = size->face;
757 FT_Bitmap_Size* bsize = face->available_sizes;
758 bdf_font_t* bdffont = ( (BDF_Face)face )->bdffont;
759 FT_Error error = FT_ERR( Invalid_Pixel_Size );
763 height = FT_REQUEST_HEIGHT( req );
764 height = ( height + 32 ) >> 6;
768 case FT_SIZE_REQUEST_TYPE_NOMINAL:
769 if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) )
773 case FT_SIZE_REQUEST_TYPE_REAL_DIM:
774 if ( height == ( bdffont->font_ascent +
775 bdffont->font_descent ) )
780 error = FT_THROW( Unimplemented_Feature );
787 return BDF_Size_Select( size, 0 );
792 FT_CALLBACK_DEF( FT_Error )
793 BDF_Glyph_Load( FT_GlyphSlot slot,
796 FT_Int32 load_flags )
798 FT_Face face = size->face;
799 BDF_Face bdf = (BDF_Face)face;
800 FT_Error error = FT_Err_Ok;
801 FT_Bitmap* bitmap = &slot->bitmap;
803 int bpp = bdf->bdffont->bpp;
805 FT_UNUSED( load_flags );
810 error = FT_THROW( Invalid_Face_Handle );
814 if ( glyph_index >= (FT_UInt)face->num_glyphs )
816 error = FT_THROW( Invalid_Argument );
820 FT_TRACE1((
"BDF_Glyph_Load: glyph index %u\n", glyph_index ));
823 if ( glyph_index == 0 )
824 glyph_index = bdf->default_glyph;
829 glyph = bdf->bdffont->glyphs[glyph_index];
831 bitmap->rows = glyph.bbx.height;
832 bitmap->width = glyph.bbx.width;
833 if ( glyph.bpr > FT_INT_MAX )
834 FT_TRACE1((
"BDF_Glyph_Load: too large pitch %lu is truncated\n",
836 bitmap->pitch = (int)glyph.bpr;
840 ft_glyphslot_set_bitmap( slot, glyph.bitmap );
845 bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
848 bitmap->pixel_mode = FT_PIXEL_MODE_GRAY2;
851 bitmap->pixel_mode = FT_PIXEL_MODE_GRAY4;
854 bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;
855 bitmap->num_grays = 256;
859 slot->format = FT_GLYPH_FORMAT_BITMAP;
860 slot->bitmap_left = glyph.bbx.x_offset;
861 slot->bitmap_top = glyph.bbx.ascent;
863 slot->metrics.horiAdvance = (FT_Pos)( glyph.dwidth * 64 );
864 slot->metrics.horiBearingX = (FT_Pos)( glyph.bbx.x_offset * 64 );
865 slot->metrics.horiBearingY = (FT_Pos)( glyph.bbx.ascent * 64 );
866 slot->metrics.width = (FT_Pos)( bitmap->width * 64 );
867 slot->metrics.height = (FT_Pos)( bitmap->rows * 64 );
873 ft_synthesize_vertical_metrics( &slot->metrics,
874 bdf->bdffont->bbx.height * 64 );
887 FT_CALLBACK_DEF( FT_Error )
888 bdf_get_bdf_property( FT_Face face,
889 const char* prop_name,
890 BDF_PropertyRec *aproperty )
892 BDF_Face bdfface = (BDF_Face)face;
893 bdf_property_t* prop;
896 FT_ASSERT( bdfface && bdfface->bdffont );
898 prop = bdf_get_font_property( bdfface->bdffont, prop_name );
901 switch ( prop->format )
904 aproperty->type = BDF_PROPERTY_TYPE_ATOM;
905 aproperty->u.atom = prop->value.atom;
909 if ( prop->value.l > 0x7FFFFFFFL || prop->value.l < ( -1 - 0x7FFFFFFFL ) )
911 FT_TRACE1((
"bdf_get_bdf_property:"
912 " too large integer 0x%lx is truncated\n",
915 aproperty->type = BDF_PROPERTY_TYPE_INTEGER;
916 aproperty->u.integer = (FT_Int32)prop->value.l;
920 if ( prop->value.ul > 0xFFFFFFFFUL )
922 FT_TRACE1((
"bdf_get_bdf_property:"
923 " too large cardinal 0x%lx is truncated\n",
926 aproperty->type = BDF_PROPERTY_TYPE_CARDINAL;
927 aproperty->u.cardinal = (FT_UInt32)prop->value.ul;
937 return FT_THROW( Invalid_Argument );
941 FT_CALLBACK_DEF( FT_Error )
942 bdf_get_charset_id( FT_Face face,
943 const char* *acharset_encoding,
944 const char* *acharset_registry )
946 BDF_Face bdfface = (BDF_Face)face;
949 *acharset_encoding = bdfface->charset_encoding;
950 *acharset_registry = bdfface->charset_registry;
956 static const FT_Service_BDFRec bdf_service_bdf =
958 (FT_BDF_GetCharsetIdFunc)bdf_get_charset_id,
959 (FT_BDF_GetPropertyFunc) bdf_get_bdf_property
969 static const FT_ServiceDescRec bdf_services[] =
971 { FT_SERVICE_ID_BDF, &bdf_service_bdf },
972 { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_BDF },
977 FT_CALLBACK_DEF( FT_Module_Interface )
978 bdf_driver_requester( FT_Module module,
983 return ft_service_list_lookup( bdf_services, name );
987 FT_CALLBACK_TABLE_DEF
988 const FT_Driver_ClassRec bdf_driver_class =
991 FT_MODULE_FONT_DRIVER |
992 FT_MODULE_DRIVER_NO_OUTLINES,
993 sizeof ( FT_DriverRec ),
1003 bdf_driver_requester
1006 sizeof ( BDF_FaceRec ),
1007 sizeof ( FT_SizeRec ),
1008 sizeof ( FT_GlyphSlotRec ),