47#define FT_COMPONENT pcfread
62#define FT_COMPONENT pcfdriver
74 } PCF_CMapRec, *PCF_CMap;
77 FT_CALLBACK_DEF( FT_Error )
78 pcf_cmap_init( FT_CMap cmap,
79 FT_Pointer init_data )
81 PCF_CMap pcfcmap = (PCF_CMap)cmap;
82 PCF_Face face = (PCF_Face)FT_CMAP_FACE( cmap );
84 FT_UNUSED( init_data );
87 pcfcmap->enc = &face->enc;
93 FT_CALLBACK_DEF(
void )
94 pcf_cmap_done( FT_CMap cmap )
96 PCF_CMap pcfcmap = (PCF_CMap)cmap;
103 FT_CALLBACK_DEF( FT_UInt )
104 pcf_cmap_char_index( FT_CMap cmap,
107 PCF_Enc enc = ( (PCF_CMap)cmap )->enc;
109 FT_UInt32 i = ( charcode >> 8 ) - enc->firstRow;
110 FT_UInt32 j = ( charcode & 0xFF ) - enc->firstCol;
111 FT_UInt32 h = enc->lastRow - enc->firstRow + 1;
112 FT_UInt32 w = enc->lastCol - enc->firstCol + 1;
116 if ( i >= h || j >= w )
119 return (FT_UInt)enc->offset[i * w + j];
123 FT_CALLBACK_DEF( FT_UInt )
124 pcf_cmap_char_next( FT_CMap cmap,
125 FT_UInt32 *acharcode )
127 PCF_Enc enc = ( (PCF_CMap)cmap )->enc;
128 FT_UInt32 charcode = *acharcode + 1;
130 FT_UInt32 i = ( charcode >> 8 ) - enc->firstRow;
131 FT_UInt32 j = ( charcode & 0xFF ) - enc->firstCol;
132 FT_UInt32 h = enc->lastRow - enc->firstRow + 1;
133 FT_UInt32 w = enc->lastCol - enc->firstCol + 1;
139 if ( (FT_Int32)i < 0 )
141 if ( (FT_Int32)j < 0 )
144 for ( ; i < h; i++, j = 0 )
147 result = (FT_UInt)enc->offset[i * w + j];
148 if ( result != 0xFFFFU )
153 *acharcode = ( ( i + enc->firstRow ) << 8 ) | ( j + enc->firstCol );
160 const FT_CMap_ClassRec pcf_cmap_class =
162 sizeof ( PCF_CMapRec ),
168 NULL, NULL, NULL, NULL, NULL
172 FT_CALLBACK_DEF(
void )
173 PCF_Face_Done( FT_Face face )
175 PCF_Face pcfface = (PCF_Face)face;
182 memory = FT_FACE_MEMORY( face );
184 FT_FREE( pcfface->metrics );
185 FT_FREE( pcfface->enc.offset );
188 if ( pcfface->properties )
193 for ( i = 0; i < pcfface->nprops; i++ )
195 PCF_Property prop = &pcfface->properties[i];
200 FT_FREE( prop->name );
201 if ( prop->isString )
202 FT_FREE( prop->value.atom );
206 FT_FREE( pcfface->properties );
209 FT_FREE( pcfface->toc.tables );
210 FT_FREE( face->family_name );
211 FT_FREE( face->style_name );
212 FT_FREE( face->available_sizes );
213 FT_FREE( pcfface->charset_encoding );
214 FT_FREE( pcfface->charset_registry );
217 if ( face->stream == &pcfface->comp_stream )
219 FT_Stream_Close( &pcfface->comp_stream );
220 face->stream = pcfface->comp_source;
225 FT_CALLBACK_DEF( FT_Error )
226 PCF_Face_Init( FT_Stream stream,
230 FT_Parameter* params )
232 PCF_Face pcfface = (PCF_Face)face;
235 FT_UNUSED( num_params );
239 FT_TRACE2((
"PCF driver\n" ));
241 error = pcf_load_font( stream, pcfface, face_index );
244 PCF_Face_Done( face );
246#if defined( FT_CONFIG_OPTION_USE_ZLIB ) || \
247 defined( FT_CONFIG_OPTION_USE_LZW ) || \
248 defined( FT_CONFIG_OPTION_USE_BZIP2 )
250#ifdef FT_CONFIG_OPTION_USE_ZLIB
256 FT_TRACE2((
" ... try gzip stream\n" ));
257 error2 = FT_Stream_OpenGzip( &pcfface->comp_stream, stream );
258 if ( FT_ERR_EQ( error2, Unimplemented_Feature ) )
265#ifdef FT_CONFIG_OPTION_USE_LZW
272 FT_TRACE2((
" ... try LZW stream\n" ));
273 error3 = FT_Stream_OpenLZW( &pcfface->comp_stream, stream );
274 if ( FT_ERR_EQ( error3, Unimplemented_Feature ) )
281#ifdef FT_CONFIG_OPTION_USE_BZIP2
288 FT_TRACE2((
" ... try Bzip2 stream\n" ));
289 error4 = FT_Stream_OpenBzip2( &pcfface->comp_stream, stream );
290 if ( FT_ERR_EQ( error4, Unimplemented_Feature ) )
300 pcfface->comp_source = stream;
301 face->stream = &pcfface->comp_stream;
303 stream = face->stream;
305 error = pcf_load_font( stream, pcfface, face_index );
324 if ( face_index < 0 )
326 else if ( face_index > 0 && ( face_index & 0xFFFF ) > 0 )
328 FT_ERROR((
"PCF_Face_Init: invalid face index\n" ));
329 PCF_Face_Done( face );
330 return FT_THROW( Invalid_Argument );
335 FT_String *charset_registry = pcfface->charset_registry;
336 FT_String *charset_encoding = pcfface->charset_encoding;
337 FT_Bool unicode_charmap = 0;
340 if ( charset_registry && charset_encoding )
342 char* s = charset_registry;
347 if ( ( s[0] ==
'i' || s[0] ==
'I' ) &&
348 ( s[1] ==
's' || s[1] ==
'S' ) &&
349 ( s[2] ==
'o' || s[2] ==
'O' ) )
352 if ( !ft_strcmp( s,
"10646" ) ||
353 ( !ft_strcmp( s,
"8859" ) &&
354 !ft_strcmp( pcfface->charset_encoding,
"1" ) ) )
357 else if ( !ft_strcmp( s,
"646.1991" ) &&
358 !ft_strcmp( pcfface->charset_encoding,
"IRV" ) )
364 FT_CharMapRec charmap;
368 charmap.encoding = FT_ENCODING_NONE;
370 charmap.platform_id = TT_PLATFORM_APPLE_UNICODE;
371 charmap.encoding_id = TT_APPLE_ID_DEFAULT;
373 if ( unicode_charmap )
375 charmap.encoding = FT_ENCODING_UNICODE;
376 charmap.platform_id = TT_PLATFORM_MICROSOFT;
377 charmap.encoding_id = TT_MS_ID_UNICODE_CS;
380 error = FT_CMap_New( &pcf_cmap_class, NULL, &charmap, NULL );
388 FT_TRACE2((
" not a PCF file\n" ));
389 PCF_Face_Done( face );
390 error = FT_THROW( Unknown_File_Format );
395 FT_CALLBACK_DEF( FT_Error )
396 PCF_Size_Select( FT_Size size,
397 FT_ULong strike_index )
399 PCF_Accel accel = &( (PCF_Face)size->face )->accel;
402 FT_Select_Metrics( size->face, strike_index );
404 size->metrics.ascender = accel->fontAscent * 64;
405 size->metrics.descender = -accel->fontDescent * 64;
406 size->metrics.max_advance = accel->maxbounds.characterWidth * 64;
412 FT_CALLBACK_DEF( FT_Error )
413 PCF_Size_Request( FT_Size size,
414 FT_Size_Request req )
416 PCF_Face face = (PCF_Face)size->face;
417 FT_Bitmap_Size* bsize = size->face->available_sizes;
418 FT_Error error = FT_ERR( Invalid_Pixel_Size );
422 height = FT_REQUEST_HEIGHT( req );
423 height = ( height + 32 ) >> 6;
427 case FT_SIZE_REQUEST_TYPE_NOMINAL:
428 if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) )
432 case FT_SIZE_REQUEST_TYPE_REAL_DIM:
433 if ( height == ( face->accel.fontAscent +
434 face->accel.fontDescent ) )
439 error = FT_THROW( Unimplemented_Feature );
446 return PCF_Size_Select( size, 0 );
450 FT_CALLBACK_DEF( FT_Error )
451 PCF_Glyph_Load( FT_GlyphSlot slot,
454 FT_Int32 load_flags )
456 PCF_Face face = (PCF_Face)size->face;
458 FT_Error error = FT_Err_Ok;
459 FT_Bitmap* bitmap = &slot->bitmap;
464 FT_TRACE1((
"PCF_Glyph_Load: glyph index %u\n", glyph_index ));
468 error = FT_THROW( Invalid_Face_Handle );
472 if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
474 error = FT_THROW( Invalid_Argument );
478 stream = face->root.stream;
480 metric = face->metrics + glyph_index;
482 bitmap->rows = (
unsigned int)( metric->ascent +
484 bitmap->width = (
unsigned int)( metric->rightSideBearing -
485 metric->leftSideBearing );
486 bitmap->num_grays = 1;
487 bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
489 switch ( PCF_GLYPH_PAD( face->bitmapsFormat ) )
492 bitmap->pitch = (int)( ( bitmap->width + 7 ) >> 3 );
496 bitmap->pitch = (int)( ( ( bitmap->width + 15 ) >> 4 ) << 1 );
500 bitmap->pitch = (int)( ( ( bitmap->width + 31 ) >> 5 ) << 2 );
504 bitmap->pitch = (int)( ( ( bitmap->width + 63 ) >> 6 ) << 3 );
508 return FT_THROW( Invalid_File_Format );
511 slot->format = FT_GLYPH_FORMAT_BITMAP;
512 slot->bitmap_left = metric->leftSideBearing;
513 slot->bitmap_top = metric->ascent;
515 slot->metrics.horiAdvance = (FT_Pos)( metric->characterWidth * 64 );
516 slot->metrics.horiBearingX = (FT_Pos)( metric->leftSideBearing * 64 );
517 slot->metrics.horiBearingY = (FT_Pos)( metric->ascent * 64 );
518 slot->metrics.width = (FT_Pos)( ( metric->rightSideBearing -
519 metric->leftSideBearing ) * 64 );
520 slot->metrics.height = (FT_Pos)( bitmap->rows * 64 );
522 ft_synthesize_vertical_metrics( &slot->metrics,
523 ( face->accel.fontAscent +
524 face->accel.fontDescent ) * 64 );
526 if ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY )
530 bytes = (FT_ULong)bitmap->pitch * bitmap->rows;
532 error = ft_glyphslot_alloc_bitmap( slot, (FT_ULong)bytes );
536 if ( FT_STREAM_SEEK( metric->bits ) ||
537 FT_STREAM_READ( bitmap->buffer, bytes ) )
540 if ( PCF_BIT_ORDER( face->bitmapsFormat ) != MSBFirst )
541 BitOrderInvert( bitmap->buffer, bytes );
543 if ( ( PCF_BYTE_ORDER( face->bitmapsFormat ) !=
544 PCF_BIT_ORDER( face->bitmapsFormat ) ) )
546 switch ( PCF_SCAN_UNIT( face->bitmapsFormat ) )
552 TwoByteSwap( bitmap->buffer, bytes );
556 FourByteSwap( bitmap->buffer, bytes );
572 FT_CALLBACK_DEF( FT_Error )
573 pcf_get_bdf_property( FT_Face face,
574 const char* prop_name,
575 BDF_PropertyRec *aproperty )
577 PCF_Face pcfface = (PCF_Face)face;
581 prop = pcf_find_property( pcfface, prop_name );
584 if ( prop->isString )
586 aproperty->type = BDF_PROPERTY_TYPE_ATOM;
587 aproperty->u.atom = prop->value.atom;
591 if ( prop->value.l > 0x7FFFFFFFL ||
592 prop->value.l < ( -1 - 0x7FFFFFFFL ) )
594 FT_TRACE2((
"pcf_get_bdf_property:"
595 " too large integer 0x%lx is truncated\n",
604 aproperty->type = BDF_PROPERTY_TYPE_INTEGER;
605 aproperty->u.integer = (FT_Int32)prop->value.l;
611 return FT_THROW( Invalid_Argument );
615 FT_CALLBACK_DEF( FT_Error )
616 pcf_get_charset_id( FT_Face face,
617 const char* *acharset_encoding,
618 const char* *acharset_registry )
620 PCF_Face pcfface = (PCF_Face)face;
623 *acharset_encoding = pcfface->charset_encoding;
624 *acharset_registry = pcfface->charset_registry;
630 static const FT_Service_BDFRec pcf_service_bdf =
632 (FT_BDF_GetCharsetIdFunc)pcf_get_charset_id,
633 (FT_BDF_GetPropertyFunc) pcf_get_bdf_property
641 FT_CALLBACK_DEF( FT_Error )
642 pcf_property_set( FT_Module module,
643 const char* property_name,
645 FT_Bool value_is_string )
647#ifdef PCF_CONFIG_OPTION_LONG_FAMILY_NAMES
649 FT_Error error = FT_Err_Ok;
650 PCF_Driver driver = (PCF_Driver)module;
652#ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
653 FT_UNUSED( value_is_string );
657 if ( !ft_strcmp( property_name,
"no-long-family-names" ) )
659#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
660 if ( value_is_string )
662 const char* s = (
const char*)value;
663 long lfn = ft_strtol( s, NULL, 10 );
667 driver->no_long_family_names = 0;
669 driver->no_long_family_names = 1;
671 return FT_THROW( Invalid_Argument );
676 FT_Bool* no_long_family_names = (FT_Bool*)value;
679 driver->no_long_family_names = *no_long_family_names;
689 FT_UNUSED( value_is_string );
690#ifndef FT_DEBUG_LEVEL_TRACE
691 FT_UNUSED( property_name );
696 FT_TRACE2((
"pcf_property_set: missing property `%s'\n",
698 return FT_THROW( Missing_Property );
702 FT_CALLBACK_DEF( FT_Error )
703 pcf_property_get( FT_Module module,
704 const char* property_name,
707#ifdef PCF_CONFIG_OPTION_LONG_FAMILY_NAMES
709 FT_Error error = FT_Err_Ok;
710 PCF_Driver driver = (PCF_Driver)module;
713 if ( !ft_strcmp( property_name,
"no-long-family-names" ) )
715 FT_Bool no_long_family_names = driver->no_long_family_names;
716 FT_Bool* val = (FT_Bool*)value;
719 *val = no_long_family_names;
728#ifndef FT_DEBUG_LEVEL_TRACE
729 FT_UNUSED( property_name );
734 FT_TRACE2((
"pcf_property_get: missing property `%s'\n",
736 return FT_THROW( Missing_Property );
740 FT_DEFINE_SERVICE_PROPERTIESREC(
741 pcf_service_properties,
743 (FT_Properties_SetFunc)pcf_property_set,
744 (FT_Properties_GetFunc)pcf_property_get )
753 static const FT_ServiceDescRec pcf_services[] =
755 { FT_SERVICE_ID_BDF, &pcf_service_bdf },
756 { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_PCF },
757 { FT_SERVICE_ID_PROPERTIES, &pcf_service_properties },
762 FT_CALLBACK_DEF( FT_Module_Interface )
763 pcf_driver_requester( FT_Module module,
768 return ft_service_list_lookup( pcf_services, name );
772 FT_CALLBACK_DEF( FT_Error )
773 pcf_driver_init( FT_Module module )
775#ifdef PCF_CONFIG_OPTION_LONG_FAMILY_NAMES
776 PCF_Driver driver = (PCF_Driver)module;
779 driver->no_long_family_names = 0;
788 FT_CALLBACK_DEF(
void )
789 pcf_driver_done( FT_Module module )
795 FT_CALLBACK_TABLE_DEF
796 const FT_Driver_ClassRec pcf_driver_class =
799 FT_MODULE_FONT_DRIVER |
800 FT_MODULE_DRIVER_NO_OUTLINES,
802 sizeof ( PCF_DriverRec ),
814 sizeof ( PCF_FaceRec ),
815 sizeof ( FT_SizeRec ),
816 sizeof ( FT_GlyphSlotRec ),