3
FreeType font driver for bdf files
5
Copyright (C) 2001-2002 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
39
/*************************************************************************/
41
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
42
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
43
/* messages during execution. */
46
#define FT_COMPONENT trace_bdfdriver
49
FT_CALLBACK_DEF( FT_Error )
50
BDF_Face_Done( BDF_Face face )
52
FT_Memory memory = FT_FACE_MEMORY( face );
55
bdf_free_font( face->bdffont );
57
FT_FREE( face->en_table );
59
FT_FREE( face->charset_encoding );
60
FT_FREE( face->charset_registry );
61
FT_FREE( face->root.family_name );
63
FT_FREE( face->root.available_sizes );
65
FT_FREE( face->bdffont );
67
FT_TRACE4(( "BDF_Face_Done: done face\n" ));
73
FT_CALLBACK_DEF( FT_Error )
74
BDF_Face_Init( FT_Stream stream,
78
FT_Parameter* params )
80
FT_Error error = BDF_Err_Ok;
81
FT_Memory memory = FT_FACE_MEMORY( face );
84
bdf_options_t options;
86
FT_UNUSED( num_params );
88
FT_UNUSED( face_index );
91
if ( FT_STREAM_SEEK( 0 ) )
94
options.correct_metrics = 1; /* FZ XXX: options semantics */
95
options.keep_unencoded = 1;
96
options.keep_comments = 0;
97
options.font_spacing = BDF_PROPORTIONAL;
99
error = bdf_load_font( stream, memory, &options, &font );
100
if ( error == BDF_Err_Missing_Startfont_Field )
102
FT_TRACE2(( "[not a valid BDF file]\n" ));
108
/* we have a bdf font: let's construct the face object */
109
face->bdffont = font;
111
FT_Face root = FT_FACE( face );
112
bdf_property_t* prop = NULL;
115
FT_TRACE4(( "number of glyphs: %d (%d)\n",
117
font->glyphs_used ));
118
FT_TRACE4(( "number of unencoded glyphs: %d (%d)\n",
119
font->unencoded_size,
120
font->unencoded_used ));
123
root->face_index = 0;
124
root->face_flags = FT_FACE_FLAG_FIXED_SIZES |
125
FT_FACE_FLAG_HORIZONTAL |
126
FT_FACE_FLAG_FAST_GLYPHS;
128
prop = bdf_get_font_property( font, (char *)"SPACING" );
130
if ( prop->format == BDF_ATOM )
131
if ( prop->value.atom != NULL )
132
if ( ( *(prop->value.atom) == 'M' ) ||
133
( *(prop->value.atom) == 'C' ) )
134
root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
136
/* FZ XXX: TO DO: FT_FACE_FLAGS_VERTICAL */
137
/* FZ XXX: I need a font to implement this */
139
root->style_flags = 0;
140
prop = bdf_get_font_property( font, (char *)"SLANT" );
142
if ( prop->format == BDF_ATOM )
143
if ( prop->value.atom != NULL )
144
if ( ( *(prop->value.atom) == 'O' ) ||
145
( *(prop->value.atom) == 'I' ) )
146
root->style_flags |= FT_STYLE_FLAG_ITALIC;
148
prop = bdf_get_font_property( font, (char *)"WEIGHT_NAME" );
150
if ( prop->format == BDF_ATOM )
151
if ( prop->value.atom != NULL )
152
if ( *(prop->value.atom) == 'B' )
153
root->style_flags |= FT_STYLE_FLAG_BOLD;
155
prop = bdf_get_font_property( font, (char *)"FAMILY_NAME" );
156
if ( ( prop != NULL ) && ( prop->value.atom != NULL ) )
158
int l = ft_strlen( prop->value.atom ) + 1;
161
if ( FT_NEW_ARRAY( root->family_name, l ) )
163
ft_strcpy( root->family_name, prop->value.atom );
166
root->family_name = 0;
168
root->style_name = (char *)"Regular";
169
if ( root->style_flags & FT_STYLE_FLAG_BOLD )
171
if ( root->style_flags & FT_STYLE_FLAG_ITALIC )
172
root->style_name = (char *)"Bold Italic";
174
root->style_name = (char *)"Bold";
176
else if ( root->style_flags & FT_STYLE_FLAG_ITALIC )
177
root->style_name = (char *)"Italic";
179
root->num_glyphs = font->glyphs_size; /* unencoded included */
181
root->num_fixed_sizes = 1;
182
if ( FT_NEW_ARRAY( root->available_sizes, 1 ) )
185
prop = bdf_get_font_property( font, (char *)"PIXEL_SIZE" );
188
bdf_property_t *xres = 0, *yres = 0;
191
xres = bdf_get_font_property( font, (char *)"RESOLUTION_X" );
192
yres = bdf_get_font_property( font, (char *)"RESOLUTION_Y" );
193
if ( ( xres != NULL ) && ( yres != NULL ) )
195
FT_TRACE4(( "PIXEL_SIZE: %d RESOLUTION_X: %d RESOLUTION_Y: %d\n",
198
yres->value.int32 ));
199
root->available_sizes->width =
200
(FT_Short)( prop->value.int32 * 75 / xres->value.int32 );
202
root->available_sizes->height =
203
(FT_Short)( prop->value.int32 * 75 / yres->value.int32 );
208
/* some fonts have broken SIZE declaration (jiskan24.bdf) */
209
FT_ERROR(( "BDF_Face_Init: reading size\n" ));
210
root->available_sizes->width = (FT_Short)font->point_size ;
211
root->available_sizes->height = (FT_Short)font->point_size ;
216
bdf_glyph_t* cur = font->glyphs;
220
if ( FT_NEW_ARRAY( face->en_table, font->glyphs_size ) )
223
for ( n = 0; n < font->glyphs_size; n++ )
225
(face->en_table[n]).enc = cur[n].encoding;
226
FT_TRACE4(( "idx %d, val 0x%lX\n", n, cur[n].encoding ));
227
(face->en_table[n]).glyph = (FT_Short)n;
233
bdf_property_t *charset_registry = 0, *charset_encoding = 0;
237
bdf_get_font_property( font, (char *)"CHARSET_REGISTRY" );
239
bdf_get_font_property( font, (char *)"CHARSET_ENCODING" );
240
if ( ( charset_registry != NULL ) && ( charset_encoding != NULL ) )
242
if ( ( charset_registry->format == BDF_ATOM ) &&
243
( charset_encoding->format == BDF_ATOM ) &&
244
( charset_registry->value.atom != NULL ) &&
245
( charset_encoding->value.atom != NULL ) )
247
if ( FT_NEW_ARRAY( face->charset_encoding,
248
strlen( charset_encoding->value.atom ) + 1 ) )
250
if (FT_NEW_ARRAY( face->charset_registry,
251
strlen( charset_registry->value.atom ) + 1 ) )
253
ft_strcpy( face->charset_registry, charset_registry->value.atom );
254
ft_strcpy( face->charset_encoding, charset_encoding->value.atom );
256
face->charmap.encoding = ft_encoding_none;
257
face->charmap.platform_id = 0;
258
face->charmap.encoding_id = 0;
259
face->charmap.face = root;
260
face->charmap_handle = &face->charmap;
262
root->charmap = face->charmap_handle;
268
/* otherwise assume adobe standard encoding */
269
face->charmap.encoding = ft_encoding_adobe_standard;
270
face->charmap.platform_id = 7; /* taken from t1objs.c */
271
face->charmap.encoding_id = 0;
272
face->charmap.face = root;
273
face->charmap_handle = &face->charmap;
275
root->charmap = face->charmap_handle;
283
BDF_Face_Done( face );
284
return BDF_Err_Unknown_File_Format;
289
FT_Error BDF_Set_Pixel_Size( FT_Size size )
291
BDF_Face face = (BDF_Face)FT_SIZE_FACE( size );
292
FT_Face root = FT_FACE( face );
295
FT_TRACE4(( "rec %d - pres %d\n",
296
size->metrics.y_ppem, root->available_sizes->height ));
298
if ( size->metrics.y_ppem == root->available_sizes->height )
300
size->metrics.ascender = face->bdffont->bbx.ascent << 6;
301
size->metrics.descender = face->bdffont->bbx.descent * ( -64 );
302
size->metrics.height = face->bdffont->bbx.height << 6;
307
return BDF_Err_Invalid_Pixel_Size;
312
BDF_Glyph_Load( FT_GlyphSlot slot,
317
BDF_Face face = (BDF_Face)FT_SIZE_FACE( size );
318
FT_Error error = BDF_Err_Ok;
319
FT_Bitmap* bitmap = &slot->bitmap;
321
int bpp = face->bdffont->bpp;
323
unsigned char *p, *pp;
325
FT_Memory memory = face->bdffont->memory;
327
FT_UNUSED( load_flags );
332
error = BDF_Err_Invalid_Argument;
336
/* slot, bitmap => freetype, glyph => bdflib */
337
glyph = face->bdffont->glyphs[glyph_index];
339
bitmap->rows = glyph.bbx.height;
340
bitmap->width = glyph.bbx.width;
344
bitmap->pixel_mode = ft_pixel_mode_mono;
345
bitmap->pitch = glyph.bpr;
347
if ( FT_NEW_ARRAY( bitmap->buffer, glyph.bytes ) )
349
FT_MEM_COPY( bitmap->buffer, glyph.bitmap, glyph.bytes );
353
/* blow up pixmap to have 8 bits per pixel */
354
bitmap->pixel_mode = ft_pixel_mode_grays;
355
bitmap->pitch = bitmap->width;
357
if ( FT_NEW_ARRAY( bitmap->buffer, bitmap->rows * bitmap->pitch ) )
363
bitmap->num_grays = 4;
368
for ( i = 0; i < bitmap->rows; i++ )
372
/* get the full bytes */
373
for ( j = 0; j < ( bitmap->width >> 2 ); j++ )
375
bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0xC0 ) >> 6 );
376
bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0x30 ) >> 4 );
377
bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0x0C ) >> 2 );
378
bitmap->buffer[count++] = (FT_Byte)( *pp & 0x03 );
383
/* get remaining pixels (if any) */
384
switch ( bitmap->width & 3 )
387
bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0xC0 ) >> 6 );
390
bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0x30 ) >> 4 );
393
bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0x0C ) >> 2 );
404
bitmap->num_grays = 16;
409
for ( i = 0; i < bitmap->rows; i++ )
413
/* get the full bytes */
414
for ( j = 0; j < ( bitmap->width >> 1 ); j++ )
416
bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0xF0 ) >> 4 );
417
bitmap->buffer[count++] = (FT_Byte)( *pp & 0x0F );
422
/* get remaining pixel (if any) */
423
switch ( bitmap->width & 1 )
426
bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0xF0 ) >> 4 );
437
bitmap->num_grays = 256;
439
FT_MEM_COPY( bitmap->buffer, glyph.bitmap,
440
bitmap->rows * bitmap->pitch );
445
slot->bitmap_left = 0;
446
slot->bitmap_top = glyph.bbx.ascent;
448
/* FZ XXX: TODO: vertical metrics */
449
slot->metrics.horiAdvance = glyph.dwidth << 6;
450
slot->metrics.horiBearingX = glyph.bbx.x_offset << 6;
451
slot->metrics.horiBearingY = glyph.bbx.y_offset << 6;
452
slot->metrics.width = bitmap->width << 6;
453
slot->metrics.height = bitmap->rows << 6;
455
slot->linearHoriAdvance = (FT_Fixed)glyph.dwidth << 16;
456
slot->format = ft_glyph_format_bitmap;
457
slot->flags = FT_GLYPH_OWN_BITMAP;
465
FT_UInt BDF_Get_Char_Index( FT_CharMap charmap,
468
BDF_Face face = (BDF_Face)charmap->face;
469
BDF_encoding_el* en_table = face->en_table;
473
FT_TRACE4(( "BDF_Get_Char_Index %ld\n", char_code ));
476
high = face->bdffont->glyphs_used - 1;
478
while ( low <= high )
480
mid = ( low + high ) / 2;
481
if ( char_code < en_table[mid].enc )
483
else if ( char_code > en_table[mid].enc )
486
return en_table[mid].glyph;
489
return face->bdffont->default_glyph;
493
FT_CALLBACK_TABLE_DEF
494
const FT_Driver_ClassRec bdf_driver_class =
497
ft_module_font_driver,
498
sizeof ( FT_DriverRec ),
506
(FT_Module_Constructor)0,
507
(FT_Module_Destructor) 0,
508
(FT_Module_Requester) 0
511
sizeof( BDF_FaceRec ),
512
sizeof( FT_SizeRec ),
513
sizeof( FT_GlyphSlotRec ),
515
(FT_Face_InitFunc) BDF_Face_Init,
516
(FT_Face_DoneFunc) BDF_Face_Done,
517
(FT_Size_InitFunc) 0,
518
(FT_Size_DoneFunc) 0,
519
(FT_Slot_InitFunc) 0,
520
(FT_Slot_DoneFunc) 0,
522
(FT_Size_ResetPointsFunc) BDF_Set_Pixel_Size,
523
(FT_Size_ResetPixelsFunc) BDF_Set_Pixel_Size,
525
(FT_Slot_LoadFunc) BDF_Glyph_Load,
527
#ifndef FT_CONFIG_OPTION_USE_CMAPS
528
(FT_CharMap_CharIndexFunc)0,
530
(FT_CharMap_CharIndexFunc)BDF_Get_Char_Index,
533
(FT_Face_GetKerningFunc) 0,
534
(FT_Face_AttachFunc) 0,
535
(FT_Face_GetAdvancesFunc) 0,
537
#ifndef FT_CONFIG_OPTION_USE_CMAPS
538
(FT_CharMap_CharNextFunc) 0, /* BDF_Char_Get_Next,*/
540
(FT_CharMap_CharNextFunc) 0