3
FreeType font driver for pcf files
5
Copyright (C) 2000, 2001, 2002, 2003, 2004 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
30
#include FT_INTERNAL_DEBUG_H
31
#include FT_INTERNAL_STREAM_H
32
#include FT_INTERNAL_OBJECTS_H
46
#define FT_COMPONENT trace_pcfread
48
#include FT_SERVICE_BDF_H
49
#include FT_SERVICE_XFREE86_NAME_H
52
/*************************************************************************/
54
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
55
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
56
/* messages during execution. */
59
#define FT_COMPONENT trace_pcfdriver
62
typedef struct PCF_CMapRec_
65
FT_UInt num_encodings;
66
PCF_Encoding encodings;
68
} PCF_CMapRec, *PCF_CMap;
71
FT_CALLBACK_DEF( FT_Error )
72
pcf_cmap_init( FT_CMap pcfcmap, /* PCF_CMap */
73
FT_Pointer init_data )
75
PCF_CMap cmap = (PCF_CMap)pcfcmap;
76
PCF_Face face = (PCF_Face)FT_CMAP_FACE( pcfcmap );
78
FT_UNUSED( init_data );
81
cmap->num_encodings = (FT_UInt)face->nencodings;
82
cmap->encodings = face->encodings;
88
FT_CALLBACK_DEF( void )
89
pcf_cmap_done( FT_CMap pcfcmap ) /* PCF_CMap */
91
PCF_CMap cmap = (PCF_CMap)pcfcmap;
94
cmap->encodings = NULL;
95
cmap->num_encodings = 0;
99
FT_CALLBACK_DEF( FT_UInt )
100
pcf_cmap_char_index( FT_CMap pcfcmap, /* PCF_CMap */
103
PCF_CMap cmap = (PCF_CMap)pcfcmap;
104
PCF_Encoding encodings = cmap->encodings;
105
FT_UInt min, max, mid;
110
max = cmap->num_encodings;
117
mid = ( min + max ) >> 1;
118
code = encodings[mid].enc;
120
if ( charcode == code )
122
result = encodings[mid].glyph + 1;
126
if ( charcode < code )
136
FT_CALLBACK_DEF( FT_UInt )
137
pcf_cmap_char_next( FT_CMap pcfcmap, /* PCF_CMap */
138
FT_UInt32 *acharcode )
140
PCF_CMap cmap = (PCF_CMap)pcfcmap;
141
PCF_Encoding encodings = cmap->encodings;
142
FT_UInt min, max, mid;
143
FT_UInt32 charcode = *acharcode + 1;
148
max = cmap->num_encodings;
155
mid = ( min + max ) >> 1;
156
code = encodings[mid].enc;
158
if ( charcode == code )
160
result = encodings[mid].glyph + 1;
164
if ( charcode < code )
171
if ( min < cmap->num_encodings )
173
charcode = encodings[min].enc;
174
result = encodings[min].glyph + 1;
178
*acharcode = charcode;
183
FT_CALLBACK_TABLE_DEF
184
const FT_CMap_ClassRec pcf_cmap_class =
186
sizeof ( PCF_CMapRec ),
194
FT_CALLBACK_DEF( void )
195
PCF_Face_Done( FT_Face pcfface ) /* PCF_Face */
197
PCF_Face face = (PCF_Face)pcfface;
198
FT_Memory memory = FT_FACE_MEMORY( face );
201
FT_FREE( face->encodings );
202
FT_FREE( face->metrics );
204
/* free properties */
206
PCF_Property prop = face->properties;
210
for ( i = 0; i < face->nprops; i++ )
212
prop = &face->properties[i];
214
FT_FREE( prop->name );
215
if ( prop->isString )
216
FT_FREE( prop->value );
219
FT_FREE( face->properties );
222
FT_FREE( face->toc.tables );
223
FT_FREE( pcfface->family_name );
224
FT_FREE( pcfface->available_sizes );
225
FT_FREE( face->charset_encoding );
226
FT_FREE( face->charset_registry );
228
FT_TRACE4(( "PCF_Face_Done: done face\n" ));
230
/* close gzip/LZW stream if any */
231
if ( pcfface->stream == &face->gzip_stream )
233
FT_Stream_Close( &face->gzip_stream );
234
pcfface->stream = face->gzip_source;
239
FT_CALLBACK_DEF( FT_Error )
240
PCF_Face_Init( FT_Stream stream,
241
FT_Face pcfface, /* PCF_Face */
244
FT_Parameter* params )
246
PCF_Face face = (PCF_Face)pcfface;
247
FT_Error error = PCF_Err_Ok;
249
FT_UNUSED( num_params );
251
FT_UNUSED( face_index );
254
error = pcf_load_font( stream, face );
260
/* this didn't work, try gzip support! */
261
error2 = FT_Stream_OpenGzip( &face->gzip_stream, stream );
262
if ( FT_ERROR_BASE( error2 ) == FT_Err_Unimplemented_Feature )
271
/* this didn't work, try LZW support! */
272
error3 = FT_Stream_OpenLZW( &face->gzip_stream, stream );
273
if ( FT_ERROR_BASE( error3 ) == FT_Err_Unimplemented_Feature )
280
face->gzip_source = stream;
281
pcfface->stream = &face->gzip_stream;
283
stream = pcfface->stream;
285
error = pcf_load_font( stream, face );
291
face->gzip_source = stream;
292
pcfface->stream = &face->gzip_stream;
294
stream = pcfface->stream;
296
error = pcf_load_font( stream, face );
304
FT_String *charset_registry = face->charset_registry;
305
FT_String *charset_encoding = face->charset_encoding;
306
FT_Bool unicode_charmap = 0;
309
if ( charset_registry && charset_encoding )
311
char* s = charset_registry;
314
/* Uh, oh, compare first letters manually to avoid dependency
316
if ( ( s[0] == 'i' || s[0] == 'I' ) &&
317
( s[1] == 's' || s[1] == 'S' ) &&
318
( s[2] == 'o' || s[2] == 'O' ) )
321
if ( !ft_strcmp( s, "10646" ) ||
322
( !ft_strcmp( s, "8859" ) &&
323
!ft_strcmp( face->charset_encoding, "1" ) ) )
329
FT_CharMapRec charmap;
332
charmap.face = FT_FACE( face );
333
charmap.encoding = FT_ENCODING_NONE;
334
charmap.platform_id = 0;
335
charmap.encoding_id = 0;
337
if ( unicode_charmap )
339
charmap.encoding = FT_ENCODING_UNICODE;
340
charmap.platform_id = 3;
341
charmap.encoding_id = 1;
344
error = FT_CMap_New( &pcf_cmap_class, NULL, &charmap, NULL );
347
/* Select default charmap */
348
if ( pcfface->num_charmaps )
349
pcfface->charmap = pcfface->charmaps[0];
358
FT_TRACE2(( "[not a valid PCF file]\n" ));
359
error = PCF_Err_Unknown_File_Format; /* error */
364
FT_CALLBACK_DEF( FT_Error )
365
PCF_Set_Pixel_Size( FT_Size size,
367
FT_UInt pixel_height )
369
PCF_Face face = (PCF_Face)FT_SIZE_FACE( size );
371
FT_UNUSED( pixel_width );
372
FT_UNUSED( pixel_height );
375
FT_TRACE4(( "rec %d - pres %d\n", size->metrics.y_ppem,
376
face->root.available_sizes->y_ppem >> 6 ));
378
if ( size->metrics.y_ppem == face->root.available_sizes->y_ppem >> 6 )
380
size->metrics.ascender = face->accel.fontAscent << 6;
381
size->metrics.descender = face->accel.fontDescent * (-64);
383
size->metrics.height = face->accel.maxbounds.ascent << 6;
385
size->metrics.height = size->metrics.ascender -
386
size->metrics.descender;
388
size->metrics.max_advance = face->accel.maxbounds.characterWidth << 6;
394
FT_TRACE4(( "size WRONG\n" ));
395
return PCF_Err_Invalid_Pixel_Size;
400
FT_CALLBACK_DEF( FT_Error )
401
PCF_Set_Point_Size( FT_Size size,
402
FT_F26Dot6 char_width,
403
FT_F26Dot6 char_height,
404
FT_UInt horz_resolution,
405
FT_UInt vert_resolution )
407
FT_UNUSED( char_width );
408
FT_UNUSED( char_height );
409
FT_UNUSED( horz_resolution );
410
FT_UNUSED( vert_resolution );
412
return PCF_Set_Pixel_Size( size, 0, 0 );
416
FT_CALLBACK_DEF( FT_Error )
417
PCF_Glyph_Load( FT_GlyphSlot slot,
420
FT_Int32 load_flags )
422
PCF_Face face = (PCF_Face)FT_SIZE_FACE( size );
423
FT_Stream stream = face->root.stream;
424
FT_Error error = PCF_Err_Ok;
425
FT_Bitmap* bitmap = &slot->bitmap;
429
FT_UNUSED( load_flags );
432
FT_TRACE4(( "load_glyph %d ---", glyph_index ));
436
error = PCF_Err_Invalid_Argument;
440
if ( glyph_index > 0 )
443
metric = face->metrics + glyph_index;
445
bitmap->rows = metric->ascent + metric->descent;
446
bitmap->width = metric->rightSideBearing - metric->leftSideBearing;
447
bitmap->num_grays = 1;
448
bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
450
FT_TRACE6(( "BIT_ORDER %d ; BYTE_ORDER %d ; GLYPH_PAD %d\n",
451
PCF_BIT_ORDER( face->bitmapsFormat ),
452
PCF_BYTE_ORDER( face->bitmapsFormat ),
453
PCF_GLYPH_PAD( face->bitmapsFormat ) ));
455
switch ( PCF_GLYPH_PAD( face->bitmapsFormat ) )
458
bitmap->pitch = ( bitmap->width + 7 ) >> 3;
462
bitmap->pitch = ( ( bitmap->width + 15 ) >> 4 ) << 1;
466
bitmap->pitch = ( ( bitmap->width + 31 ) >> 5 ) << 2;
470
bitmap->pitch = ( ( bitmap->width + 63 ) >> 6 ) << 3;
474
return PCF_Err_Invalid_File_Format;
477
/* XXX: to do: are there cases that need repadding the bitmap? */
478
bytes = bitmap->pitch * bitmap->rows;
480
error = ft_glyphslot_alloc_bitmap( slot, bytes );
484
if ( FT_STREAM_SEEK( metric->bits ) ||
485
FT_STREAM_READ( bitmap->buffer, bytes ) )
488
if ( PCF_BIT_ORDER( face->bitmapsFormat ) != MSBFirst )
489
BitOrderInvert( bitmap->buffer, bytes );
491
if ( ( PCF_BYTE_ORDER( face->bitmapsFormat ) !=
492
PCF_BIT_ORDER( face->bitmapsFormat ) ) )
494
switch ( PCF_SCAN_UNIT( face->bitmapsFormat ) )
500
TwoByteSwap( bitmap->buffer, bytes );
504
FourByteSwap( bitmap->buffer, bytes );
509
slot->bitmap_left = metric->leftSideBearing;
510
slot->bitmap_top = metric->ascent;
512
slot->metrics.horiAdvance = metric->characterWidth << 6;
513
slot->metrics.horiBearingX = metric->leftSideBearing << 6;
514
slot->metrics.horiBearingY = metric->ascent << 6;
515
slot->metrics.width = ( metric->rightSideBearing -
516
metric->leftSideBearing ) << 6;
517
slot->metrics.height = bitmap->rows << 6;
519
slot->linearHoriAdvance = (FT_Fixed)bitmap->width << 16;
520
slot->format = FT_GLYPH_FORMAT_BITMAP;
522
FT_TRACE4(( " --- ok\n" ));
536
pcf_get_bdf_property( PCF_Face face,
537
const char* prop_name,
538
BDF_PropertyRec *aproperty )
543
prop = pcf_find_property( face, prop_name );
546
if ( prop->isString )
548
aproperty->type = BDF_PROPERTY_TYPE_ATOM;
549
aproperty->u.atom = prop->value.atom;
553
/* Apparently, the PCF driver loads all properties as signed integers!
554
* This really doesn't seem to be a problem, because this is
555
* sufficient for any meaningful values.
557
aproperty->type = BDF_PROPERTY_TYPE_INTEGER;
558
aproperty->u.integer = prop->value.integer;
563
return PCF_Err_Invalid_Argument;
568
pcf_get_charset_id( PCF_Face face,
569
const char* *acharset_encoding,
570
const char* *acharset_registry )
572
*acharset_encoding = face->charset_encoding;
573
*acharset_registry = face->charset_registry;
579
static const FT_Service_BDFRec pcf_service_bdf =
581
(FT_BDF_GetCharsetIdFunc)pcf_get_charset_id,
582
(FT_BDF_GetPropertyFunc) pcf_get_bdf_property
592
static const FT_ServiceDescRec pcf_services[] =
594
{ FT_SERVICE_ID_BDF, &pcf_service_bdf },
595
{ FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PCF },
600
FT_CALLBACK_DEF( FT_Module_Interface )
601
pcf_driver_requester( FT_Module module,
606
return ft_service_list_lookup( pcf_services, name );
610
FT_CALLBACK_TABLE_DEF
611
const FT_Driver_ClassRec pcf_driver_class =
614
FT_MODULE_FONT_DRIVER |
615
FT_MODULE_DRIVER_NO_OUTLINES,
616
sizeof ( FT_DriverRec ),
629
sizeof ( PCF_FaceRec ),
630
sizeof ( FT_SizeRec ),
631
sizeof ( FT_GlyphSlotRec ),
635
0, /* FT_Size_InitFunc */
636
0, /* FT_Size_DoneFunc */
637
0, /* FT_Slot_InitFunc */
638
0, /* FT_Slot_DoneFunc */
645
0, /* FT_Face_GetKerningFunc */
646
0, /* FT_Face_AttachFunc */
647
0 /* FT_Face_GetAdvancesFunc */