ref: f28b7bfaea2264a9db7de97decca6568ecdf6b24
parent: 6b76663625fce26634e2d6c72e2a0da90f1616ac
author: Werner Lemberg <[email protected]>
date: Mon Jan 1 12:24:31 EST 2001
Initial revision
--- /dev/null
+++ b/src/pcf/module.mk
@@ -1,0 +1,32 @@
+#
+# FreeType 2 PCF module definition
+#
+
+# Copyright 2000 by
+# Francesco Zappa Nardelli
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+make_module_list: add_pcf_driver
+
+add_pcf_driver:
+ $(OPEN_DRIVER)pcf_driver_class$(CLOSE_DRIVER)
+ $(ECHO_DRIVER)pcf $(ECHO_DRIVER_DESC)pcf bitmap fonts$(ECHO_DRIVER_DONE)
+
+# EOF
--- /dev/null
+++ b/src/pcf/pcf.c
@@ -1,0 +1,36 @@
+/* pcf.c
+
+ FreeType font driver for pcf fonts
+
+ Copyright 2000 by
+ Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+
+#define FT_MAKE_OPTION_SINGLE_OBJECT
+
+
+#include <ft2build.h>
+#include FT_SOURCE_FILE(pcf,pcfutil.c)
+#include FT_SOURCE_FILE(pcf,pcfread.c)
+#include FT_SOURCE_FILE(pcf,pcfdriver.c)
+
+/* END */
--- /dev/null
+++ b/src/pcf/pcf.h
@@ -1,0 +1,239 @@
+/* pcf.h
+
+ FreeType font driver for pcf fonts
+
+ Copyright (C) 2000 by
+ Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+
+#ifndef __PCF_H__
+#define __PCF_H__
+
+
+#include <ft2build.h>
+#include FT_INTERNAL_DRIVER_H
+
+
+FT_BEGIN_HEADER
+
+ typedef struct PCF_TableRec_
+ {
+ FT_ULong type;
+ FT_ULong format;
+ FT_ULong size;
+ FT_ULong offset;
+
+ } PCF_TableRec, *PCF_Table;
+
+
+ typedef struct PCF_TocRec_
+ {
+ FT_ULong version;
+ FT_ULong count;
+ PCF_Table tables;
+
+ } PCF_TocRec, *PCF_Toc;
+
+
+ typedef struct PCF_ParseProperty_
+ {
+ FT_Long name;
+ FT_Byte isString;
+ FT_Long value;
+
+ } PCF_ParsePropertyRec, *PCF_ParseProperty;
+
+
+ typedef struct PCF_Property_
+ {
+ FT_String* name;
+ FT_Byte isString;
+
+ union
+ {
+ FT_String* atom;
+ FT_Long integer;
+ FT_ULong cardinal;
+
+ } value;
+
+ } PCF_PropertyRec, *PCF_Property;
+
+
+ typedef struct PCF_Compressed_Metric_
+ {
+ FT_Byte leftSideBearing;
+ FT_Byte rightSideBearing;
+ FT_Byte characterWidth;
+ FT_Byte ascent;
+ FT_Byte descent;
+
+ } PCF_Compressed_MetricRec, *PCF_Compressed_Metric;
+
+
+ typedef struct PCF_Metric_
+ {
+ FT_Short leftSideBearing;
+ FT_Short rightSideBearing;
+ FT_Short characterWidth;
+ FT_Short ascent;
+ FT_Short descent;
+ FT_Short attributes;
+ FT_ULong bits;
+
+ } PCF_MetricRec, *PCF_Metric;
+
+
+ typedef struct PCF_AccelRec_
+ {
+ FT_Byte noOverlap;
+ FT_Byte constantMetrics;
+ FT_Byte terminalFont;
+ FT_Byte constantWidth;
+ FT_Byte inkInside;
+ FT_Byte inkMetrics;
+ FT_Byte drawDirection;
+ FT_Long fontAscent;
+ FT_Long fontDescent;
+ FT_Long maxOverlap;
+ PCF_MetricRec minbounds;
+ PCF_MetricRec maxbounds;
+ PCF_MetricRec ink_minbounds;
+ PCF_MetricRec ink_maxbounds;
+
+ } PCF_AccelRec, *PCF_Accel;
+
+
+ typedef struct PCD_Encoding_
+ {
+ FT_Long enc;
+ FT_Short glyph;
+
+ } PCF_EncodingRec, *PCF_Encoding;
+
+
+ typedef struct PCF_FaceRec_
+ {
+ FT_FaceRec root;
+
+ char* charset_encoding;
+ char* charset_registry;
+
+ PCF_TocRec toc;
+ PCF_AccelRec accel;
+
+ int nprops;
+ PCF_Property properties;
+
+ FT_Long nmetrics;
+ PCF_Metric metrics;
+ FT_Long nencodings;
+ PCF_Encoding encodings;
+
+ FT_Short defaultChar;
+
+ FT_ULong bitmapsFormat;
+
+ FT_CharMap charmap_handle;
+ FT_CharMapRec charmap; /* a single charmap per face */
+
+ } PCF_FaceRec, *PCF_Face;
+
+
+ /* XXX hack */
+ static
+ FT_Error PCF_Done_Face( PCF_Face face );
+
+
+ /* macros for pcf font format */
+
+#define LSBFirst 0
+#define MSBFirst 1
+
+#define PCF_FILE_VERSION ( ( 'p' << 24 ) | \
+ ( 'c' << 16 ) | \
+ ( 'f' << 8 ) | 1 )
+#define PCF_FORMAT_MASK 0xFFFFFF00L
+
+#define PCF_DEFAULT_FORMAT 0x00000000L
+#define PCF_INKBOUNDS 0x00000200L
+#define PCF_ACCEL_W_INKBOUNDS 0x00000100L
+#define PCF_COMPRESSED_METRICS 0x00000100L
+
+#define PCF_FORMAT_MATCH( a, b ) \
+ ( ( (a) & PCF_FORMAT_MASK ) == ( (b) & PCF_FORMAT_MASK ) )
+
+#define PCF_GLYPH_PAD_MASK ( 3 << 0 )
+#define PCF_BYTE_MASK ( 1 << 2 )
+#define PCF_BIT_MASK ( 1 << 3 )
+#define PCF_SCAN_UNIT_MASK ( 3 << 4 )
+
+#define PCF_BYTE_ORDER( f ) \
+ ( ( (f) & PCF_BYTE_MASK ) ? MSBFirst : LSBFirst )
+#define PCF_BIT_ORDER( f ) \
+ ( ( (f) & PCF_BIT_MASK ) ? MSBFirst : LSBFirst )
+#define PCF_GLYPH_PAD_INDEX( f ) \
+ ( (f) & PCF_GLYPH_PAD_MASK )
+#define PCF_GLYPH_PAD( f ) \
+ ( 1 << PCF_GLYPH_PAD_INDEX( f ) )
+#define PCF_SCAN_UNIT_INDEX( f ) \
+ ( ( (f) & PCF_SCAN_UNIT_MASK ) >> 4 )
+#define PCF_SCAN_UNIT( f ) \
+ ( 1 << PCF_SCAN_UNIT_INDEX( f ) )
+#define PCF_FORMAT_BITS( f ) \
+ ( (f) & ( PCF_GLYPH_PAD_MASK | \
+ PCF_BYTE_MASK | \
+ PCF_BIT_MASK | \
+ PCF_SCAN_UNIT_MASK ) )
+
+#define PCF_SIZE_TO_INDEX( s ) ( (s) == 4 ? 2 : (s) == 2 ? 1 : 0 )
+#define PCF_INDEX_TO_SIZE( b ) ( 1 << b )
+
+#define PCF_FORMAT( bit, byte, glyph, scan ) \
+ ( ( PCF_SIZE_TO_INDEX( scan ) << 4 ) | \
+ ( ( (bit) == MSBFirst ? 1 : 0 ) << 3 ) | \
+ ( ( (byte) == MSBFirst ? 1 : 0 ) << 2 ) | \
+ ( PCF_SIZE_TO_INDEX( glyph ) << 0 ) )
+
+#define PCF_PROPERTIES ( 1 << 0 )
+#define PCF_ACCELERATORS ( 1 << 1 )
+#define PCF_METRICS ( 1 << 2 )
+#define PCF_BITMAPS ( 1 << 3 )
+#define PCF_INK_METRICS ( 1 << 4 )
+#define PCF_BDF_ENCODINGS ( 1 << 5 )
+#define PCF_SWIDTHS ( 1 << 6 )
+#define PCF_GLYPH_NAMES ( 1 << 7 )
+#define PCF_BDF_ACCELERATORS ( 1 << 8 )
+
+#define GLYPHPADOPTIONS 4 /* I'm not sure about this */
+
+ static
+ FT_Error pcf_load_font( FT_Stream,
+ PCF_Face );
+
+
+FT_END_HEADER
+
+#endif /* __PCF_H__ */
+
+
+/* END */
--- /dev/null
+++ b/src/pcf/pcfdriver.c
@@ -1,0 +1,343 @@
+/* pcfdriver.c
+
+ FreeType font driver for pcf files
+
+ Copyright (C) 2000 by
+ Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+
+#include <ft2build.h>
+
+#include FT_ERRORS_H
+#include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_STREAM_H
+#include FT_INTERNAL_OBJECTS_H
+
+#include FT_SOURCE_FILE(pcf,pcf.h)
+#include FT_SOURCE_FILE(pcf,pcfdriver.h)
+#include FT_SOURCE_FILE(pcf,pcfutil.h)
+
+
+ /*************************************************************************/
+ /* */
+ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+ /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
+ /* messages during execution. */
+ /* */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_pcfdriver
+
+
+ static
+ FT_Error PCF_Done_Face( PCF_Face face )
+ {
+ FT_Memory memory = FT_FACE_MEMORY( face );
+ PCF_Property tmp = face->properties;
+ int i;
+
+
+ FREE( face->encodings );
+ FREE( face->metrics );
+
+ for ( i = 0; i < face->nprops; i++ )
+ {
+ FREE( tmp->name );
+ if ( tmp->isString )
+ FREE( tmp->value );
+ }
+ FREE( face->properties );
+
+ FT_TRACE4(( "DONE_FACE!!!\n" ));
+
+ return FT_Err_Ok;
+ }
+
+
+ static
+ FT_Error PCF_Init_Face( FT_Stream stream,
+ PCF_Face face,
+ FT_Int face_index,
+ FT_Int num_params,
+ FT_Parameter* params )
+ {
+ FT_Error error = FT_Err_Ok;
+
+ FT_UNUSED( num_params );
+ FT_UNUSED( params );
+ FT_UNUSED( face_index );
+
+
+ error = pcf_load_font( stream, face );
+ if ( error )
+ goto Fail;
+
+ return FT_Err_Ok;
+
+ Fail:
+ FT_TRACE2(( "[not a valid PCF file]\n" ));
+ PCF_Done_Face( face );
+
+ return FT_Err_Unknown_File_Format; /* error */
+ }
+
+
+ static
+ FT_Error PCF_Set_Pixel_Size( FT_Size size )
+ {
+ PCF_Face face = (PCF_Face)FT_SIZE_FACE( size );
+
+
+ FT_TRACE4(( "rec %d - pres %d\n", size->metrics.y_ppem,
+ face->root.available_sizes->height ));
+
+ if ( size->metrics.y_ppem == face->root.available_sizes->height )
+ {
+ size->metrics.ascender = face->accel.fontAscent << 6;
+ size->metrics.descender = face->accel.fontDescent * (-64);
+#if 0
+ size->metrics.height = face->accel.maxbounds.ascent << 6;
+#endif
+ size->metrics.height = size->metrics.ascender -
+ size->metrics.descender;
+
+ return FT_Err_Ok;
+ }
+ else
+ {
+ FT_TRACE4(( "size WRONG\n" ));
+ return FT_Err_Invalid_Pixel_Size;
+ }
+ }
+
+
+ static
+ FT_Error PCF_Load_Glyph( FT_GlyphSlot slot,
+ FT_Size size,
+ FT_UInt glyph_index,
+ FT_Int load_flags )
+ {
+ PCF_Face face = (PCF_Face)FT_SIZE_FACE( size );
+ FT_Error error = FT_Err_Ok;
+ FT_Memory memory = FT_FACE(face)->memory;
+ FT_Bitmap* bitmap = &slot->bitmap;
+ PCF_Metric metric;
+ int bytes;
+
+ FT_Stream stream = face->root.stream;
+
+ FT_UNUSED( load_flags );
+
+
+ FT_TRACE4(( "load_glyph %d ---", glyph_index ));
+
+ if ( !face )
+ {
+ error = FT_Err_Invalid_Argument;
+ goto Exit;
+ }
+
+ metric = face->metrics + glyph_index;
+
+ bitmap->rows = metric->ascent + metric->descent;
+ bitmap->width = metric->characterWidth;
+ bitmap->num_grays = 1;
+ bitmap->pixel_mode = ft_pixel_mode_mono;
+
+ FT_TRACE6(( "BIT_ORDER %d ; BYTE_ORDER %d ; GLYPH_PAD %d\n",
+ PCF_BIT_ORDER( face->bitmapsFormat ),
+ PCF_BYTE_ORDER( face->bitmapsFormat ),
+ PCF_GLYPH_PAD( face->bitmapsFormat ) ));
+
+ switch ( PCF_GLYPH_PAD( face->bitmapsFormat ) )
+ {
+ case 1:
+ bitmap->pitch = ( bitmap->width + 7 ) >> 3;
+ break;
+
+ case 2:
+ bitmap->pitch = ( ( bitmap->width + 15 ) >> 4 ) << 1;
+ break;
+
+ case 4:
+ bitmap->pitch = ( ( bitmap->width + 31 ) >> 5 ) << 2;
+ break;
+
+ case 8:
+ bitmap->pitch = ( ( bitmap->width + 63 ) >> 6 ) << 3;
+ break;
+
+ default:
+ return FT_Err_Invalid_File_Format;
+ }
+
+ /* XXX: to do: are there cases that need repadding the bitmap? */
+ bytes = bitmap->pitch * bitmap->rows;
+
+ if ( ALLOC( bitmap->buffer, bytes ) )
+ goto Exit;
+
+ if ( FILE_Seek( metric->bits ) ||
+ FILE_Read( bitmap->buffer, bytes ) )
+ goto Exit;
+
+ if ( PCF_BIT_ORDER( face->bitmapsFormat ) != MSBFirst )
+ BitOrderInvert( bitmap->buffer,bytes );
+
+ if ( ( PCF_BYTE_ORDER( face->bitmapsFormat ) !=
+ PCF_BIT_ORDER( face->bitmapsFormat ) ) )
+ {
+ switch ( PCF_SCAN_UNIT( face->bitmapsFormat ) )
+ {
+ case 1:
+ break;
+
+ case 2:
+ TwoByteSwap( bitmap->buffer, bytes );
+ break;
+
+ case 4:
+ FourByteSwap( bitmap->buffer, bytes );
+ break;
+ }
+ }
+
+ slot->bitmap_left = 0;
+ slot->bitmap_top = metric->ascent;
+
+ slot->metrics.horiAdvance = metric->characterWidth << 6 ;
+ slot->metrics.horiBearingX = metric->rightSideBearing << 6 ;
+ slot->metrics.horiBearingY = metric->ascent << 6 ;
+ slot->metrics.width = metric->characterWidth << 6 ;
+ slot->metrics.height = bitmap->rows << 6;
+
+ slot->linearHoriAdvance = (FT_Fixed)bitmap->width << 16;
+ slot->format = ft_glyph_format_bitmap;
+ slot->flags = ft_glyph_own_bitmap;
+
+ FT_TRACE4(( " --- ok\n" ));
+
+ Exit:
+ return error;
+ }
+
+
+ static
+ FT_UInt PCF_Get_Char_Index( FT_CharMap charmap,
+ FT_Long char_code )
+ {
+ PCF_Face face = (PCF_Face)charmap->face;
+ PCF_Encoding en_table = face->encodings;
+ int low, high, mid;
+
+
+ FT_TRACE4(( "get_char_index %ld\n", char_code ));
+
+ low = 0;
+ high = face->nencodings - 1;
+ while ( low <= high )
+ {
+ mid = ( low + high ) / 2;
+ if ( char_code < en_table[mid].enc )
+ high = mid - 1;
+ else if ( char_code > en_table[mid].enc )
+ low = mid + 1;
+ else
+ return en_table[mid].glyph;
+ }
+
+ return face->defaultChar;
+ }
+
+
+ FT_CALLBACK_TABLE_DEF
+ const FT_Driver_Class pcf_driver_class =
+ {
+ {
+ ft_module_font_driver,
+ sizeof ( FT_DriverRec ),
+
+ "pcf",
+ 0x10000L,
+ 0x20000L,
+
+ 0,
+
+ (FT_Module_Constructor)0,
+ (FT_Module_Destructor) 0,
+ (FT_Module_Requester) 0
+ },
+
+ sizeof( PCF_FaceRec ),
+ sizeof( FT_SizeRec ),
+ sizeof( FT_GlyphSlotRec ),
+
+ (FTDriver_initFace) PCF_Init_Face,
+ (FTDriver_doneFace) PCF_Done_Face,
+ (FTDriver_initSize) 0,
+ (FTDriver_doneSize) 0,
+ (FTDriver_initGlyphSlot)0,
+ (FTDriver_doneGlyphSlot)0,
+
+ (FTDriver_setCharSizes) PCF_Set_Pixel_Size,
+ (FTDriver_setPixelSizes)PCF_Set_Pixel_Size,
+
+ (FTDriver_loadGlyph) PCF_Load_Glyph,
+ (FTDriver_getCharIndex) PCF_Get_Char_Index,
+
+ (FTDriver_getKerning) 0,
+ (FTDriver_attachFile) 0,
+ (FTDriver_getAdvances) 0
+ };
+
+
+#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* getDriverClass */
+ /* */
+ /* <Description> */
+ /* This function is used when compiling the TrueType driver as a */
+ /* shared library (`.DLL' or `.so'). It will be used by the */
+ /* high-level library of FreeType to retrieve the address of the */
+ /* driver's generic interface. */
+ /* */
+ /* It shouldn't be implemented in a static build, as each driver must */
+ /* have the same function as an exported entry point. */
+ /* */
+ /* <Return> */
+ /* The address of the TrueType's driver generic interface. The */
+ /* format-specific interface can then be retrieved through the method */
+ /* interface->get_format_interface. */
+ /* */
+ FT_EXPORT_DEF( const FT_Driver_Class* ) getDriverClass( void )
+ {
+ return &pcf_driver_class;
+ }
+
+
+#endif /* FT_CONFIG_OPTION_DYNAMIC_DRIVERS */
+
+
+/* END */
--- /dev/null
+++ b/src/pcf/pcfdriver.h
@@ -1,0 +1,44 @@
+/* pcfdriver.h
+
+ FreeType font driver for pcf fonts
+
+ Copyright 2000 by
+ Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+
+#ifndef __PCFDRIVER_H__
+#define __PCFDRIVER_H__
+
+#include <ft2build.h>
+#include FT_INTERNAL_DRIVER_H
+
+FT_BEGIN_HEADER
+
+ FT_EXPORT_VAR( const FT_Driver_Class ) pcf_driver_class;
+
+FT_END_HEADER
+
+
+#endif /* __PCFDRIVER_H__ */
+
+
+/* END */
--- /dev/null
+++ b/src/pcf/pcfread.c
@@ -1,0 +1,1051 @@
+/* pcfread.c
+
+ FreeType font driver for pcf fonts
+
+ Copyright 2000 by
+ Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+
+#include <ft2build.h>
+
+#include FT_ERRORS_H
+#include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_STREAM_H
+#include FT_INTERNAL_OBJECTS_H
+
+#include FT_SOURCE_FILE(pcf,pcf.h)
+#include FT_SOURCE_FILE(pcf,pcfdriver.h)
+
+#include <string.h> /* strlen(), strcpy() */
+
+ /*************************************************************************/
+ /* */
+ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+ /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
+ /* messages during execution. */
+ /* */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_pcfread
+
+
+#if defined( FT_DEBUG_LEVEL_TRACE )
+ static char* tableNames[] =
+ {
+ "prop", "accl", "mtrcs", "bmps", "imtrcs",
+ "enc", "swidth", "names", "accel"
+ };
+#endif
+
+
+ static
+ const FT_Frame_Field pcf_toc_header[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE PCF_TocRec
+
+ FT_FRAME_START( 8 ),
+ FT_FRAME_ULONG_LE( version ),
+ FT_FRAME_ULONG_LE( count ),
+ FT_FRAME_END
+ };
+
+
+ static
+ const FT_Frame_Field pcf_table_header[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE PCF_TableRec
+
+ FT_FRAME_START( 16 ),
+ FT_FRAME_ULONG_LE( type ),
+ FT_FRAME_ULONG_LE( format ),
+ FT_FRAME_ULONG_LE( size ),
+ FT_FRAME_ULONG_LE( offset ),
+ FT_FRAME_END
+ };
+
+
+ static
+ FT_Error pcf_read_TOC( FT_Stream stream,
+ PCF_Face face )
+ {
+ FT_Error error;
+ PCF_Toc toc = &face->toc;
+ PCF_Table tables;
+
+ FT_Memory memory = FT_FACE(face)->memory;
+ unsigned int i;
+
+
+ if ( FILE_Seek ( 0 ) ||
+ READ_Fields ( pcf_toc_header, toc ) )
+ return FT_Err_Cannot_Open_Resource;
+
+ if ( toc->version != PCF_FILE_VERSION )
+ return FT_Err_Invalid_File_Format;
+
+ if ( ALLOC( face->toc.tables, toc->count * sizeof ( PCF_TableRec ) ) )
+ return FT_Err_Out_Of_Memory;
+
+ tables = face->toc.tables;
+ for ( i = 0; i < toc->count; i++ )
+ {
+ if ( READ_Fields( pcf_table_header, tables ) )
+ goto Exit;
+ tables++;
+ }
+
+#if defined( FT_DEBUG_LEVEL_TRACE )
+
+ {
+ int i,j;
+ char* name;
+
+
+ FT_TRACE4(( "Tables count: %ld\n", face->toc.count ));
+ tables = face->toc.tables;
+ for ( i = 0; i < toc->count; i++ )
+ {
+ for( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] ); j++ )
+ if ( tables[i].type == ( 1 << j ) )
+ name=tableNames[j];
+ FT_TRACE4(( "Table %d: type=%-6s format=0x%04lX "
+ "size=0x%06lX (%8ld) offset=0x%04lX\n",
+ i, name,
+ tables[i].format,
+ tables[i].size, tables[i].size,
+ tables[i].offset ));
+ }
+ }
+
+#endif
+
+ return FT_Err_Ok;
+
+ Exit:
+ FREE( face->toc.tables );
+ return error;
+ }
+
+
+ static
+ const FT_Frame_Field pcf_metric_header[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE PCF_MetricRec
+
+ FT_FRAME_START( 12 ),
+ FT_FRAME_SHORT_LE( leftSideBearing ),
+ FT_FRAME_SHORT_LE( rightSideBearing ),
+ FT_FRAME_SHORT_LE( characterWidth ),
+ FT_FRAME_SHORT_LE( ascent ),
+ FT_FRAME_SHORT_LE( descent ),
+ FT_FRAME_SHORT_LE( attributes ),
+ FT_FRAME_END
+ };
+
+
+ static
+ const FT_Frame_Field pcf_metric_msb_header[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE PCF_MetricRec
+
+ FT_FRAME_START( 12 ),
+ FT_FRAME_SHORT( leftSideBearing ),
+ FT_FRAME_SHORT( rightSideBearing ),
+ FT_FRAME_SHORT( characterWidth ),
+ FT_FRAME_SHORT( ascent ),
+ FT_FRAME_SHORT( descent ),
+ FT_FRAME_SHORT( attributes ),
+ FT_FRAME_END
+ };
+
+
+ static
+ const FT_Frame_Field pcf_compressed_metric_header[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE PCF_Compressed_MetricRec
+
+ FT_FRAME_START( 5 ),
+ FT_FRAME_BYTE( leftSideBearing ),
+ FT_FRAME_BYTE( rightSideBearing ),
+ FT_FRAME_BYTE( characterWidth ),
+ FT_FRAME_BYTE( ascent ),
+ FT_FRAME_BYTE( descent ),
+ FT_FRAME_END
+ };
+
+
+ static
+ FT_Error pcf_parse_metric( FT_Stream stream,
+ const FT_Frame_Field* header,
+ PCF_Metric metric )
+ {
+ FT_Error error = FT_Err_Ok;
+
+
+ (void)READ_Fields( header, metric );
+
+ return error;
+ }
+
+
+ static
+ FT_Error pcf_parse_compressed_metric( FT_Stream stream,
+ PCF_Metric metric )
+ {
+ PCF_Compressed_MetricRec compr_metric;
+ FT_Error error = FT_Err_Ok;
+
+
+ (void)READ_Fields( pcf_compressed_metric_header, &compr_metric );
+
+ metric->leftSideBearing = (FT_Short)compr_metric.leftSideBearing - 0x80;
+ metric->rightSideBearing = (FT_Short)compr_metric.rightSideBearing - 0x80;
+ metric->characterWidth = (FT_Short)compr_metric.characterWidth - 0x80;
+ metric->ascent = (FT_Short)compr_metric.ascent - 0x80;
+ metric->descent = (FT_Short)compr_metric.descent - 0x80;
+ metric->attributes = 0;
+
+ return error;
+ }
+
+
+ static
+ FT_Error pcf_get_metric( FT_Stream stream,
+ FT_ULong format,
+ PCF_Metric metric )
+ {
+ FT_Error error = FT_Err_Ok;
+
+
+ if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
+ {
+ if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+ error = pcf_parse_metric( stream, pcf_metric_msb_header, metric );
+ else
+ error = pcf_parse_metric( stream, pcf_metric_header, metric );
+ }
+ else
+ error = pcf_parse_compressed_metric( stream, metric );
+
+ return error;
+ }
+
+
+ static
+ FT_Error pcfSeekToType( FT_Stream stream,
+ PCF_Table tables,
+ int ntables,
+ FT_ULong type,
+ FT_ULong* formatp,
+ FT_ULong* sizep )
+ {
+ FT_Error error;
+ int i;
+
+
+ for ( i = 0; i < ntables; i++ )
+ if ( tables[i].type == type )
+ {
+ if ( stream->pos > tables[i].offset )
+ return FT_Err_Invalid_Stream_Skip;
+ if ( FILE_Skip( tables[i].offset - stream->pos ) )
+ return FT_Err_Invalid_Stream_Skip;
+ *sizep = tables[i].size; /* unused - to be removed */
+ *formatp = tables[i].format;
+ return FT_Err_Ok;
+ }
+
+ return FT_Err_Invalid_File_Format;
+ }
+
+
+ static
+ FT_Bool pcfHasType( PCF_Table tables,
+ int ntables,
+ FT_ULong type )
+ {
+ int i;
+
+
+ for ( i = 0; i < ntables; i++ )
+ if ( tables[i].type == type )
+ return TRUE;
+
+ return FALSE;
+ }
+
+
+ static
+ const FT_Frame_Field pcf_property_header[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE PCF_ParsePropertyRec
+
+ FT_FRAME_START( 9 ),
+ FT_FRAME_LONG_LE( name ),
+ FT_FRAME_BYTE ( isString ),
+ FT_FRAME_LONG_LE( value ),
+ FT_FRAME_END
+ };
+
+
+ static
+ const FT_Frame_Field pcf_property_msb_header[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE PCF_ParsePropertyRec
+
+ FT_FRAME_START( 9 ),
+ FT_FRAME_LONG( name ),
+ FT_FRAME_BYTE( isString ),
+ FT_FRAME_LONG( value ),
+ FT_FRAME_END
+ };
+
+
+ static
+ PCF_Property find_property( PCF_Face face,
+ const FT_String* prop )
+ {
+ PCF_Property properties = face->properties;
+ FT_Bool found = 0;
+ int i;
+
+
+ for ( i = 0 ; i < face->nprops && !found; i++ )
+ {
+ if ( !strcmp( properties[i].name, prop ) )
+ found = 1;
+ }
+
+ if ( found )
+ return properties + i - 1;
+ else
+ return NULL;
+ }
+
+
+ static
+ FT_Error pcf_get_properties( FT_Stream stream,
+ PCF_Face face )
+ {
+ PCF_ParseProperty props = 0;
+ PCF_Property properties = 0;
+ int nprops, i;
+ FT_ULong format, size;
+ FT_Error error;
+ FT_Memory memory = FT_FACE(face)->memory;
+ FT_ULong string_size;
+ FT_String* strings = 0;
+
+
+ error = pcfSeekToType( stream,
+ face->toc.tables,
+ face->toc.count,
+ PCF_PROPERTIES,
+ &format,
+ &size );
+ if ( error )
+ goto Bail;
+
+ if ( READ_ULongLE( format ) )
+ goto Bail;
+
+ FT_TRACE4(( "get_prop: format = %ld\n", format ));
+
+ if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
+ goto Bail;
+
+ if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+ (void)READ_ULong( nprops );
+ else
+ (void)READ_ULongLE( nprops );
+ if ( error )
+ goto Bail;
+
+ FT_TRACE4(( "get_prop: nprop = %d\n", nprops ));
+
+ if ( ALLOC( props, nprops * sizeof ( PCF_ParsePropertyRec ) ) )
+ goto Bail;
+
+ for ( i = 0; i < nprops; i++ )
+ {
+ if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+ (void)READ_Fields( pcf_property_msb_header, props + i );
+ else
+ (void)READ_Fields( pcf_property_header, props + i );
+ if ( error )
+ goto Bail;
+ }
+
+ /* pad the property array */
+ /* */
+ /* clever here - nprops is the same as the number of odd-units read, */
+ /* as only isStringProp are odd length (Keith Packard) */
+ /* */
+ if ( nprops & 3 )
+ {
+ i = 4 - ( nprops & 3 );
+ FT_Skip_Stream( stream, i );
+ }
+
+ if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+ (void)READ_ULong( string_size );
+ else
+ (void)READ_ULongLE( string_size );
+ if ( error )
+ goto Bail;
+
+ FT_TRACE4(( "get_prop: string_size = %ld\n", string_size ));
+
+ if ( ALLOC( strings, string_size * sizeof ( char ) ) )
+ goto Bail;
+
+ error = FT_Read_Stream( stream, (FT_Byte*)strings, string_size );
+ if ( error )
+ goto Bail;
+
+ if ( ALLOC( properties, nprops * sizeof ( PCF_PropertyRec ) ) )
+ goto Bail;
+
+ for ( i = 0; i < nprops; i++ )
+ {
+ /* XXX: make atom */
+ error = ALLOC( properties[i].name,
+ ( strlen( strings + props[i].name ) + 1 ) *
+ sizeof ( char ) );
+ if ( error )
+ goto Bail;
+ strcpy( properties[i].name,strings + props[i].name );
+
+ properties[i].isString = props[i].isString;
+
+ if ( props[i].isString )
+ {
+ error = ALLOC( properties[i].value.atom,
+ ( strlen( strings + props[i].value ) + 1 ) *
+ sizeof ( char ) );
+ if ( error )
+ goto Bail;
+ strcpy( properties[i].value.atom, strings + props[i].value );
+ }
+ else
+ properties[i].value.integer = props[i].value;
+ }
+
+ face->properties = properties;
+ face->nprops = nprops;
+
+ FREE( props );
+ FREE( strings );
+
+ return FT_Err_Ok;
+
+ Bail:
+ FREE( props );
+ FREE( strings );
+
+ return error;
+ }
+
+
+ static
+ FT_Error pcf_get_metrics( FT_Stream stream,
+ PCF_Face face )
+ {
+ FT_Error error = FT_Err_Ok;
+ FT_Memory memory = FT_FACE(face)->memory;
+ FT_ULong format = 0;
+ FT_ULong size = 0;
+ PCF_Metric metrics = 0;
+ int i;
+ int nmetrics = -1;
+
+
+ error = pcfSeekToType( stream,
+ face->toc.tables,
+ face->toc.count,
+ PCF_METRICS,
+ &format,
+ &size );
+ if ( error )
+ return error;
+
+ error = READ_ULongLE( format );
+
+ if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) &&
+ !PCF_FORMAT_MATCH( format, PCF_COMPRESSED_METRICS ) )
+ return FT_Err_Invalid_File_Format;
+
+ if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
+ {
+ if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+ (void)READ_ULong( nmetrics );
+ else
+ (void)READ_ULongLE( nmetrics );
+ }
+ else
+ {
+ if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+ (void)READ_UShort( nmetrics );
+ else
+ (void)READ_UShortLE( nmetrics );
+ }
+ if ( error || nmetrics == -1 )
+ return FT_Err_Invalid_File_Format;
+
+ face->nmetrics = nmetrics;
+
+ error = ALLOC( face->metrics, nmetrics * sizeof ( PCF_MetricRec ) );
+ if ( error )
+ return FT_Err_Out_Of_Memory;
+
+ metrics = face->metrics;
+ for ( i = 0; i < nmetrics; i++ )
+ {
+ pcf_get_metric( stream, format, metrics + i );
+
+ metrics[i].bits = 0;
+
+ FT_TRACE4(( "%d : width=%d, "
+ "lsb=%d, rsb=%d, ascent=%d, descent=%d, swidth=%d\n",
+ i,
+ ( metrics + i )->characterWidth,
+ ( metrics + i )->leftSideBearing,
+ ( metrics + i )->rightSideBearing,
+ ( metrics + i )->ascent,
+ ( metrics + i )->descent,
+ ( metrics + i )->attributes ));
+
+ if ( error )
+ break;
+ }
+
+ if ( error )
+ FREE( face->metrics );
+ return error;
+ }
+
+
+ static
+ FT_Error pcf_get_bitmaps( FT_Stream stream,
+ PCF_Face face )
+ {
+ FT_Error error = FT_Err_Ok;
+ FT_Memory memory = FT_FACE(face)->memory;
+ FT_Long* offsets;
+ FT_Long bitmapSizes[GLYPHPADOPTIONS];
+ FT_ULong format, size;
+ int nbitmaps, i, sizebitmaps;
+ char* bitmaps;
+
+
+ error = pcfSeekToType( stream,
+ face->toc.tables,
+ face->toc.count,
+ PCF_BITMAPS,
+ &format,
+ &size );
+ if ( error )
+ return error;
+
+ error = FT_Access_Frame( stream, 8 );
+ if ( error )
+ return error;
+ format = GET_ULongLE();
+ if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
+ return FT_Err_Invalid_File_Format;
+
+ if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+ nbitmaps = GET_ULong();
+ else
+ nbitmaps = GET_ULongLE();
+ FT_Forget_Frame( stream );
+ if ( nbitmaps != face->nmetrics )
+ return FT_Err_Invalid_File_Format;
+
+ error = ALLOC( offsets, nbitmaps * sizeof ( FT_ULong ) );
+ if ( error )
+ return error;
+
+ if ( error )
+ goto Bail;
+ for ( i = 0; i < nbitmaps; i++ )
+ {
+ if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+ (void)READ_Long( offsets[i] );
+ else
+ (void)READ_LongLE( offsets[i] );
+
+ FT_TRACE4(( "bitmap %d is at offset %ld\n", i, offsets[i] ));
+ }
+ if ( error )
+ goto Bail;
+
+ if ( error )
+ goto Bail;
+ for ( i = 0; i < GLYPHPADOPTIONS; i++ )
+ {
+ if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+ (void)READ_Long( bitmapSizes[i] );
+ else
+ (void)READ_LongLE( bitmapSizes[i] );
+ if ( error )
+ goto Bail;
+
+ sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX( format )];
+
+ FT_TRACE4(( "padding %d implies a size of %ld\n", i, bitmapSizes[i] ));
+ }
+
+ FT_TRACE4(( " %d bitmaps, padding index %ld\n",
+ nbitmaps,
+ PCF_GLYPH_PAD_INDEX( format ) ));
+ FT_TRACE4(( "bitmap size = %d\n", sizebitmaps ));
+
+ for ( i = 0; i < nbitmaps; i++ )
+ face->metrics[i].bits = stream->pos + offsets[i];
+
+ face->bitmapsFormat = format;
+
+ FREE ( offsets );
+ return error;
+
+ Bail:
+ FREE ( offsets );
+ FREE ( bitmaps );
+ return error;
+ }
+
+
+ static
+ FT_Error pcf_get_encodings( FT_Stream stream,
+ PCF_Face face )
+ {
+ FT_Error error = FT_Err_Ok;
+ FT_Memory memory = FT_FACE(face)->memory;
+ FT_ULong format, size;
+ int firstCol, lastCol;
+ int firstRow, lastRow;
+ int nencoding, encodingOffset;
+ int i, j;
+ PCF_Encoding tmpEncoding, encoding = 0;
+
+
+ error = pcfSeekToType( stream,
+ face->toc.tables,
+ face->toc.count,
+ PCF_BDF_ENCODINGS,
+ &format,
+ &size );
+ if ( error )
+ return error;
+
+ error = FT_Access_Frame( stream, 14 );
+ if ( error )
+ return error;
+ format = GET_ULongLE();
+ if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
+ return FT_Err_Invalid_File_Format;
+
+ if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+ {
+ firstCol = GET_Short();
+ lastCol = GET_Short();
+ firstRow = GET_Short();
+ lastRow = GET_Short();
+ face->defaultChar = GET_Short();
+ }
+ else
+ {
+ firstCol = GET_ShortLE();
+ lastCol = GET_ShortLE();
+ firstRow = GET_ShortLE();
+ lastRow = GET_ShortLE();
+ face->defaultChar = GET_ShortLE();
+ }
+
+ FT_Forget_Frame( stream );
+
+ FT_TRACE4(( "enc: firstCol %d, lastCol %d, firstRow %d, lastRow %d\n",
+ firstCol, lastCol, firstRow, lastRow ));
+
+ nencoding = ( lastCol - firstCol + 1 ) * ( lastRow - firstRow + 1 );
+
+ if ( ALLOC( tmpEncoding, nencoding * sizeof ( PCF_EncodingRec ) ) )
+ return FT_Err_Out_Of_Memory;
+
+ error = FT_Access_Frame( stream, 2 * nencoding );
+ if ( error )
+ goto Bail;
+
+ for ( i = 0, j = 0 ; i < nencoding; i++ )
+ {
+ if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+ encodingOffset = GET_Short();
+ else
+ encodingOffset = GET_ShortLE();
+
+ if ( encodingOffset != 0xFFFF )
+ {
+ tmpEncoding[j].enc = ( ( ( i / ( lastCol - firstCol + 1 ) ) +
+ firstRow ) * 256 ) +
+ ( ( i % ( lastCol - firstCol + 1 ) ) +
+ firstCol );
+
+ tmpEncoding[j].glyph = encodingOffset;
+ j++;
+ }
+
+ FT_TRACE4(( "enc n. %d ; Uni %ld ; Glyph %d\n",
+ i, tmpEncoding[j - 1].enc, encodingOffset ));
+ }
+ FT_Forget_Frame( stream );
+
+ if ( ALLOC( encoding, (--j) * sizeof ( PCF_EncodingRec ) ) )
+ goto Bail;
+
+ for ( i = 0; i < j; i++ )
+ {
+ encoding[i].enc = tmpEncoding[i].enc;
+ encoding[i].glyph = tmpEncoding[i].glyph;
+ }
+
+ face->nencodings = j;
+ face->encodings = encoding;
+ FREE( tmpEncoding );
+
+ return error;
+
+ Bail:
+ FREE( encoding );
+ FREE( tmpEncoding );
+ return error;
+ }
+
+
+ static
+ const FT_Frame_Field pcf_accel_header[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE PCF_AccelRec
+
+ FT_FRAME_START( 20 ),
+ FT_FRAME_BYTE ( noOverlap ),
+ FT_FRAME_BYTE ( constantMetrics ),
+ FT_FRAME_BYTE ( terminalFont ),
+ FT_FRAME_BYTE ( constantWidth ),
+ FT_FRAME_BYTE ( inkInside ),
+ FT_FRAME_BYTE ( inkMetrics ),
+ FT_FRAME_BYTE ( drawDirection ),
+ FT_FRAME_SKIP_BYTES( 1 ),
+ FT_FRAME_LONG_LE ( fontAscent ),
+ FT_FRAME_LONG_LE ( fontDescent ),
+ FT_FRAME_LONG_LE ( maxOverlap ),
+ FT_FRAME_END
+ };
+
+
+ static
+ const FT_Frame_Field pcf_accel_msb_header[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE PCF_AccelRec
+
+ FT_FRAME_START( 20 ),
+ FT_FRAME_BYTE ( noOverlap ),
+ FT_FRAME_BYTE ( constantMetrics ),
+ FT_FRAME_BYTE ( terminalFont ),
+ FT_FRAME_BYTE ( constantWidth ),
+ FT_FRAME_BYTE ( inkInside ),
+ FT_FRAME_BYTE ( inkMetrics ),
+ FT_FRAME_BYTE ( drawDirection ),
+ FT_FRAME_SKIP_BYTES( 1 ),
+ FT_FRAME_LONG ( fontAscent ),
+ FT_FRAME_LONG ( fontDescent ),
+ FT_FRAME_LONG ( maxOverlap ),
+ FT_FRAME_END
+ };
+
+
+ static
+ FT_Error pcf_get_accel( FT_Stream stream,
+ PCF_Face face,
+ FT_ULong type )
+ {
+ FT_ULong format, size;
+ FT_Error error = FT_Err_Ok;
+ PCF_Accel accel = &face->accel;
+
+
+ error = pcfSeekToType( stream,
+ face->toc.tables,
+ face->toc.count,
+ type,
+ &format,
+ &size );
+ if ( error )
+ goto Bail;
+
+ error = READ_ULongLE( format );
+ if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) &&
+ !PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) )
+ goto Bail;
+
+ if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+ (void)READ_Fields( pcf_accel_msb_header , accel );
+ else
+ (void)READ_Fields( pcf_accel_header, accel );
+ if ( error )
+ goto Bail;
+
+ error = pcf_get_metric( stream, format, &(accel->minbounds) );
+ if ( error )
+ goto Bail;
+ error = pcf_get_metric( stream, format, &(accel->maxbounds) );
+ if ( error )
+ goto Bail;
+
+ if ( PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) )
+ {
+ error = pcf_get_metric( stream, format, &(accel->ink_minbounds) );
+ if ( error )
+ goto Bail;
+ error = pcf_get_metric( stream, format, &(accel->ink_maxbounds) );
+ if ( error )
+ goto Bail;
+ }
+ else
+ {
+ accel->ink_minbounds = accel->minbounds; /* I'm not sure about this */
+ accel->ink_maxbounds = accel->maxbounds;
+ }
+ return error;
+
+ Bail:
+ return error;
+ }
+
+
+ FT_Error pcf_load_font( FT_Stream stream,
+ PCF_Face face )
+ {
+ FT_Error error = FT_Err_Ok;
+ FT_Memory memory = FT_FACE(face)->memory;
+ FT_Bool hasBDFAccelerators;
+
+
+ error = pcf_read_TOC( stream, face );
+ if ( error )
+ return error;
+
+ error = pcf_get_properties( stream, face );
+ if ( error )
+ return error;;
+
+ /* Use the old accelerators if no BDF accelerators are in the file. */
+ hasBDFAccelerators = pcfHasType( face->toc.tables,
+ face->toc.count,
+ PCF_BDF_ACCELERATORS );
+ if ( !hasBDFAccelerators )
+ {
+ error = pcf_get_accel( stream, face, PCF_ACCELERATORS );
+ if ( error )
+ goto Bail;
+ }
+
+ /* metrics */
+ error = pcf_get_metrics( stream, face );
+ if ( error )
+ goto Bail;
+
+ /* bitmaps */
+ error = pcf_get_bitmaps( stream, face );
+ if ( error )
+ goto Bail;
+
+ /* encodings */
+ error = pcf_get_encodings( stream, face );
+ if ( error )
+ goto Bail;
+
+ /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
+ if ( hasBDFAccelerators )
+ {
+ error = pcf_get_accel( stream, face, PCF_BDF_ACCELERATORS );
+ if ( error )
+ goto Bail;
+ }
+
+ /* XXX: TO DO: inkmetrics and glyph_names are missing */
+
+ /* now construct the face object */
+ {
+ FT_Face root = FT_FACE( face );
+ PCF_Property prop;
+
+
+ root->num_faces = 1;
+ root->face_index = 0;
+ root->face_flags = FT_FACE_FLAG_FIXED_SIZES |
+ FT_FACE_FLAG_HORIZONTAL |
+ FT_FACE_FLAG_FAST_GLYPHS;
+
+ if ( face->accel.constantWidth )
+ root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
+
+ root->style_flags = 0;
+ prop = find_property( face, "SLANT" );
+ if ( prop != NULL )
+ if ( prop->isString )
+ if ( ( *(prop->value.atom) == 'O' ) ||
+ ( *(prop->value.atom) == 'I' ) )
+ root->style_flags |= FT_STYLE_FLAG_ITALIC;
+
+ prop = find_property( face, "WEIGHT_NAME" );
+ if ( prop != NULL )
+ if ( prop->isString )
+ if ( *(prop->value.atom) == 'B' )
+ root->style_flags |= FT_STYLE_FLAG_BOLD;
+
+ root->style_name = (char *)"Regular";
+
+ if ( root->style_flags & FT_STYLE_FLAG_BOLD ) {
+ if ( root->style_flags & FT_STYLE_FLAG_ITALIC )
+ root->style_name = (char *)"Bold Italic";
+ else
+ root->style_name = (char *)"Bold";
+ }
+ else if ( root->style_flags & FT_STYLE_FLAG_ITALIC )
+ root->style_name = (char *)"Italic";
+
+ prop = find_property( face, "FAMILY_NAME" );
+ if ( prop != NULL )
+ {
+ if ( prop->isString )
+ {
+ int l = strlen( prop->value.atom ) + 1;
+
+
+ if ( ALLOC( root->family_name, l * sizeof ( char ) ) )
+ goto Bail;
+ strcpy( root->family_name, prop->value.atom );
+ }
+ }
+ else
+ root->family_name = 0;
+
+ root->num_glyphs = face->nmetrics;
+
+ root->num_fixed_sizes = 1;
+ if ( ALLOC_ARRAY( root->available_sizes, 1, FT_Bitmap_Size ) )
+ goto Bail;
+
+ prop = find_property( face, "PIXEL_SIZE" );
+ if ( prop != NULL )
+ {
+ PCF_Property xres = 0, yres = 0;
+
+
+ xres = find_property( face, "RESOLUTION_X" );
+ yres = find_property( face, "RESOLUTION_Y" );
+ if ( ( xres != NULL ) && ( yres != NULL ) )
+ {
+ root->available_sizes->width =
+ prop->value.integer * 75 / xres->value.integer;
+ root->available_sizes->height =
+ prop->value.integer * 75 / yres->value.integer;
+ }
+ }
+ else
+ { /* XXX */
+#if 0
+ printf( "PCF Warning: Pixel Size undefined, assuming 12\n");
+#endif
+ root->available_sizes->width = 12;
+ root->available_sizes->height = 12;
+ }
+
+ /* XXX: charmaps */
+ root->charmaps = &face->charmap_handle;
+ root->num_charmaps = 1;
+
+ {
+ PCF_Property charset_registry = 0, charset_encoding = 0;
+
+
+ charset_registry = find_property( face, "CHARSET_REGISTRY" );
+ charset_encoding = find_property( face, "CHARSET_ENCODING" );
+
+ if ( ( charset_registry != NULL ) &&
+ ( charset_encoding != NULL ) )
+ {
+ if ( ( charset_registry->isString ) &&
+ ( charset_encoding->isString ) )
+ {
+ if ( ALLOC( face->charset_encoding,
+ ( strlen( charset_encoding->value.atom ) + 1 ) *
+ sizeof ( char ) ) )
+ goto Bail;
+ if ( ALLOC( face->charset_registry,
+ ( strlen( charset_registry->value.atom ) + 1 ) *
+ sizeof ( char ) ) )
+ goto Bail;
+ strcpy( face->charset_registry, charset_registry->value.atom );
+ strcpy( face->charset_encoding, charset_encoding->value.atom );
+
+#if 0
+ if ( !strcmp( charset_registry, "ISO10646" ) )
+ {
+ face->charmap.encoding = ft_encoding_unicode;
+ face->charmap.platform_id = 3;
+ face->charmap.encoding_id = 1;
+ face->charmap.face = root;
+ face->charmap_handle
+
+ return FT_Err_Ok;
+ }
+#endif
+ }
+ }
+ }
+
+ face->charmap.encoding = ft_encoding_none;
+ face->charmap.platform_id = 0;
+ face->charmap.encoding_id = 0;
+ face->charmap.face = root;
+ face->charmap_handle = &face->charmap;
+ root->charmap = face->charmap_handle;
+ }
+ return FT_Err_Ok;
+
+ Bail:
+ PCF_Done_Face( face );
+ return FT_Err_Invalid_File_Format;
+ }
+
+
+/* END */
--- /dev/null
+++ b/src/pcf/pcfutil.c
@@ -1,0 +1,211 @@
+/*
+
+Copyright 1990, 1994, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/util/utilbitmap.c,v 1.3 1999/08/22 08:58:58 dawes Exp $ */
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+
+#include <ft2build.h>
+#include FT_SOURCE_FILE(pcf,pcfutil.h)
+
+
+ /* Utility functions for reformatting font bitmaps */
+
+ static unsigned char _reverse_byte[0x100] =
+ {
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+ };
+
+ /*
+ * Invert bit order within each BYTE of an array.
+ */
+
+ void BitOrderInvert( unsigned char* buf,
+ int nbytes )
+ {
+ unsigned char* rev = _reverse_byte;
+
+
+ for ( ; --nbytes >= 0; buf++ )
+ *buf = rev[*buf];
+ }
+
+
+ /*
+ * Invert byte order within each 16-bits of an array.
+ */
+
+ void TwoByteSwap( unsigned char* buf,
+ int nbytes )
+ {
+ unsigned char c;
+
+
+ for ( ; nbytes > 0; nbytes -= 2, buf += 2 )
+ {
+ c = buf[0];
+ buf[0] = buf[1];
+ buf[1] = c;
+ }
+ }
+
+ /*
+ * Invert byte order within each 32-bits of an array.
+ */
+
+ void FourByteSwap( unsigned char* buf,
+ int nbytes )
+ {
+ unsigned char c;
+
+
+ for ( ; nbytes > 0; nbytes -= 4, buf += 4 )
+ {
+ c = buf[0];
+ buf[0] = buf[3];
+ buf[3] = c;
+
+ c = buf[1];
+ buf[1] = buf[2];
+ buf[2] = c;
+ }
+ }
+
+
+ /*
+ * Repad a bitmap.
+ */
+
+ int RepadBitmap( char* pSrc,
+ char* pDst,
+ unsigned int srcPad,
+ unsigned int dstPad,
+ int width,
+ int height )
+ {
+ int srcWidthBytes, dstWidthBytes;
+ int row, col;
+ char *pTmpSrc, *pTmpDst;
+
+
+ switch ( srcPad )
+ {
+ case 1:
+ srcWidthBytes = ( width + 7 ) >> 3;
+ break;
+
+ case 2:
+ srcWidthBytes = ( ( width + 15 ) >> 4 ) << 1;
+ break;
+
+ case 4:
+ srcWidthBytes = ( ( width + 31 ) >> 5 ) << 2;
+ break;
+
+ case 8:
+ srcWidthBytes = ( ( width + 63 ) >> 6 ) << 3;
+ break;
+
+ default:
+ return 0;
+ }
+
+ switch ( dstPad )
+ {
+ case 1:
+ dstWidthBytes = ( width + 7 ) >> 3;
+ break;
+
+ case 2:
+ dstWidthBytes = ( ( width + 15 ) >> 4 ) << 1;
+ break;
+
+ case 4:
+ dstWidthBytes = ( ( width + 31 ) >> 5 ) << 2;
+ break;
+
+ case 8:
+ dstWidthBytes = ( ( width + 63 ) >> 6 ) << 3;
+ break;
+
+ default:
+ return 0;
+ }
+
+ width = srcWidthBytes;
+ if ( width > dstWidthBytes )
+ width = dstWidthBytes;
+
+ pTmpSrc= pSrc;
+ pTmpDst= pDst;
+
+ for ( row = 0; row < height; row++ )
+ {
+ for ( col = 0; col < width; col++ )
+ *pTmpDst++ = *pTmpSrc++;
+
+ while ( col < dstWidthBytes )
+ {
+ *pTmpDst++ = '\0';
+ col++;
+ }
+ pTmpSrc += srcWidthBytes - width;
+ }
+
+ return dstWidthBytes * height;
+ }
+
+
+/* END */
--- /dev/null
+++ b/src/pcf/pcfutil.h
@@ -1,0 +1,54 @@
+/* pcfutil.h
+
+ FreeType font driver for pcf fonts
+
+ Copyright 2000 by
+ Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+
+#ifndef __PCFUTIL_H__
+#define __PCFUTIL_H__
+
+
+#include <ft2build.h>
+
+
+ void BitOrderInvert( unsigned char* buf,
+ int nbytes);
+
+ void TwoByteSwap ( unsigned char* buf,
+ int nbytes);
+
+ void FourByteSwap ( unsigned char* buf,
+ int nbytes);
+
+ int RepadBitmap ( char* pSrc,
+ char* pDst,
+ unsigned int srcPad,
+ unsigned int dstPad,
+ int width,
+ int height);
+
+#endif /* __PCFUTIL_H__ */
+
+
+/* END */
--- /dev/null
+++ b/src/pcf/readme
@@ -1,0 +1,114 @@
+ FreeType font driver for PCF fonts
+
+ Francesco Zappa Nardelli
+ <[email protected]>
+
+
+Introduction
+************
+
+PCF (Portable Compiled Format) is a binary bitmap font format, largely used
+in X world. This code implements a PCF driver for the FreeType library.
+Glyph images are loaded into memory only on demand, thus leading to a small
+memory footprint.
+
+Informations on the PCF font format can only be worked out from
+``pcfread.c'', and ``pcfwrite.c'', to be found, for instance, in the XFree86
+(www.xfree86.org) source tree (xc/lib/font/bitmap/).
+
+Many good bitmap fonts in bdf format come with XFree86: they can be
+compiled into the pcf format using the ``bdftopcf'' utility.
+
+
+Supported hardware
+******************
+
+The driver has been tested on linux/x86 and sunos5.5/sparc. In both
+cases the compiler was gcc. When back in Paris, I will test it also
+on linux/alpha.
+
+
+Encodings
+*********
+
+The variety of encodings that accompanies pcf fonts appears to encompass the
+small set defined in freetype.h. On the other hand, each pcf font defines
+two properties that specify encoding and registry.
+
+I decided to make these two properties directly accessible, leaving to the
+client application the work of interpreting them. For instance:
+
+ #include "pcftypes.h" /* include/freetype/internal/pcftypes.h */
+
+ FT_Face face;
+ PCF_Public_Face pcfface;
+
+ FT_New_Face( library,..., &face );
+
+ pcfface = (PCF_Public_Face)face;
+
+ if ((pcfface->charset_registry == "ISO10646") &&
+ (pcfface->charset_encoding) == "1")) [..]
+
+Thus the driver always export ``ft_encoding_none'' as
+face->charmap.encoding. FT_Get_Char_Index() behavior is unmodified, that
+is, it converts the ULong value given as argument into the corresponding
+glyph number.
+
+
+Known problems
+**************
+
+- dealing explicitly with encodings breaks the uniformity of freetype2
+ api.
+
+- except for encodings properties, client applications have no
+ visibility of the PCF_Face object. This means that applications
+ cannot directly access font tables and are obliged to trust
+ FreeType.
+
+- currently, glyph names and ink_metrics are ignored.
+
+I plan to give full visibility of the PCF_Face object in the next
+release of the driver, thus implementing also glyph names and
+ink_metrics.
+
+- height is defined as (ascent - descent). Is this correct?
+
+- if unable to read size informations from the font, PCF_Init_Face
+ sets available_size->width and available_size->height to 12.
+
+- too many english grammar errors in the readme file :-(
+
+
+License
+*******
+
+Copyright (C) 2000 by Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+Credits
+*******
+
+Keith Packard wrote the pcf driver found in XFree86. His work is at
+the same time the specification and the sample implementation of the
+PCF format. Undoubtedly, this driver is inspired from his work.
--- /dev/null
+++ b/src/pcf/rules.mk
@@ -1,0 +1,79 @@
+#
+# FreeType 2 pcf driver configuration rules
+#
+
+
+# Copyright (C) 2000 by
+# Francesco Zappa Nardelli
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+
+# pcf driver directory
+#
+PCF_DIR := $(SRC_)pcf
+PCF_DIR_ := $(PCF_DIR)$(SEP)
+
+
+PCF_COMPILE := $(FT_COMPILE)
+
+
+# pcf driver sources (i.e., C files)
+#
+PCF_DRV_SRC := $(PCF_DIR_)pcfread.c \
+ $(PCF_DIR_)pcfdriver.c \
+ $(PCF_DIR_)pcfutil.c
+
+# pcf driver headers
+#
+PCF_DRV_H := $(PCF_DIR_)pcf.h \
+ $(PCF_DIR_)pcfdriver.h \
+ $(PCF_DIR_)pcfutil.h
+
+# pcf driver object(s)
+#
+# PCF_DRV_OBJ_M is used during `multi' builds
+# PCF_DRV_OBJ_S is used during `single' builds
+#
+PCF_DRV_OBJ_M := $(PCF_DRV_SRC:$(PCF_DIR_)%.c=$(OBJ_)%.$O)
+PCF_DRV_OBJ_S := $(OBJ_)pcf.$O
+
+# Windows driver source file for single build
+#
+PCF_DRV_SRC_S := $(PCF_DIR_)pcf.c
+
+
+# pcf driver - single object
+#
+$(PCF_DRV_OBJ_S): $(PCF_DRV_SRC_S) $(PCF_DRV_SRC) $(FREETYPE_H) $(PCF_DRV_H)
+ $(PCF_COMPILE) $T$@ $(PCF_DRV_SRC_S)
+
+
+# pcf driver - multiple objects
+#
+$(OBJ_)%.$O: $(PCF_DIR_)%.c $(FREETYPE_H) $(PCF_DRV_H)
+ $(PCF_COMPILE) $T$@ $<
+
+
+# update main driver object lists
+#
+DRV_OBJS_S += $(PCF_DRV_OBJ_S)
+DRV_OBJS_M += $(PCF_DRV_OBJ_M)
+
+# EOF