1 /* pcfdriver.c
3 FreeType font driver for pcf files
5 Copyright (C) 2000-2001 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
24 THE SOFTWARE.
25 */
28 #include <ft2build.h>
30 #include FT_INTERNAL_DEBUG_H
31 #include FT_INTERNAL_STREAM_H
32 #include FT_INTERNAL_OBJECTS_H
34 #include "pcf.h"
35 #include "pcfdriver.h"
36 #include "pcfutil.h"
38 #include "pcferror.h"
41 /*************************************************************************/
42 /* */
43 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
44 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
45 /* messages during execution. */
46 /* */
47 #undef FT_COMPONENT
48 #define FT_COMPONENT trace_pcfdriver
51 FT_LOCAL_DEF FT_Error
52 PCF_Done_Face( PCF_Face face )
53 {
54 FT_Memory memory = FT_FACE_MEMORY( face );
55 PCF_Property tmp = face->properties;
56 int i;
59 FREE( face->encodings );
60 FREE( face->metrics );
62 for ( i = 0; i < face->nprops; i++ )
63 {
64 FREE( tmp->name );
65 if ( tmp->isString )
66 FREE( tmp->value );
67 }
68 FREE( face->properties );
70 FT_TRACE4(( "DONE_FACE!!!\n" ));
72 return PCF_Err_Ok;
73 }
76 static FT_Error
77 PCF_Init_Face( FT_Stream stream,
78 PCF_Face face,
79 FT_Int face_index,
80 FT_Int num_params,
81 FT_Parameter* params )
82 {
83 FT_Error error = PCF_Err_Ok;
85 FT_UNUSED( num_params );
86 FT_UNUSED( params );
87 FT_UNUSED( face_index );
90 error = pcf_load_font( stream, face );
91 if ( error )
92 goto Fail;
94 return PCF_Err_Ok;
96 Fail:
97 FT_TRACE2(( "[not a valid PCF file]\n" ));
98 PCF_Done_Face( face );
100 return PCF_Err_Unknown_File_Format; /* error */
101 }
104 static FT_Error
105 PCF_Set_Pixel_Size( FT_Size size )
106 {
107 PCF_Face face = (PCF_Face)FT_SIZE_FACE( size );
110 FT_TRACE4(( "rec %d - pres %d\n", size->metrics.y_ppem,
111 face->root.available_sizes->height ));
113 if ( size->metrics.y_ppem == face->root.available_sizes->height )
114 {
115 size->metrics.ascender = face->accel.fontAscent << 6;
116 size->metrics.descender = face->accel.fontDescent * (-64);
117 #if 0
118 size->metrics.height = face->accel.maxbounds.ascent << 6;
119 #endif
120 size->metrics.height = size->metrics.ascender -
121 size->metrics.descender;
123 return PCF_Err_Ok;
124 }
125 else
126 {
127 FT_TRACE4(( "size WRONG\n" ));
128 return PCF_Err_Invalid_Pixel_Size;
129 }
130 }
133 static FT_Error
134 PCF_Load_Glyph( FT_GlyphSlot slot,
135 FT_Size size,
136 FT_UInt glyph_index,
137 FT_Int load_flags )
138 {
139 PCF_Face face = (PCF_Face)FT_SIZE_FACE( size );
140 FT_Error error = PCF_Err_Ok;
141 FT_Memory memory = FT_FACE(face)->memory;
142 FT_Bitmap* bitmap = &slot->bitmap;
143 PCF_Metric metric;
144 int bytes;
146 FT_Stream stream = face->root.stream;
148 FT_UNUSED( load_flags );
151 FT_TRACE4(( "load_glyph %d ---", glyph_index ));
153 if ( !face )
154 {
155 error = PCF_Err_Invalid_Argument;
156 goto Exit;
157 }
159 metric = face->metrics + glyph_index;
161 bitmap->rows = metric->ascent + metric->descent;
162 bitmap->width = metric->rightSideBearing - metric->leftSideBearing;
163 bitmap->num_grays = 1;
164 bitmap->pixel_mode = ft_pixel_mode_mono;
166 FT_TRACE6(( "BIT_ORDER %d ; BYTE_ORDER %d ; GLYPH_PAD %d\n",
167 PCF_BIT_ORDER( face->bitmapsFormat ),
168 PCF_BYTE_ORDER( face->bitmapsFormat ),
169 PCF_GLYPH_PAD( face->bitmapsFormat ) ));
171 switch ( PCF_GLYPH_PAD( face->bitmapsFormat ) )
172 {
173 case 1:
174 bitmap->pitch = ( bitmap->width + 7 ) >> 3;
175 break;
177 case 2:
178 bitmap->pitch = ( ( bitmap->width + 15 ) >> 4 ) << 1;
179 break;
181 case 4:
182 bitmap->pitch = ( ( bitmap->width + 31 ) >> 5 ) << 2;
183 break;
185 case 8:
186 bitmap->pitch = ( ( bitmap->width + 63 ) >> 6 ) << 3;
187 break;
189 default:
190 return PCF_Err_Invalid_File_Format;
191 }
193 /* XXX: to do: are there cases that need repadding the bitmap? */
194 bytes = bitmap->pitch * bitmap->rows;
196 if ( ALLOC( bitmap->buffer, bytes ) )
197 goto Exit;
199 if ( FILE_Seek( metric->bits ) ||
200 FILE_Read( bitmap->buffer, bytes ) )
201 goto Exit;
203 if ( PCF_BIT_ORDER( face->bitmapsFormat ) != MSBFirst )
204 BitOrderInvert( bitmap->buffer,bytes );
206 if ( ( PCF_BYTE_ORDER( face->bitmapsFormat ) !=
207 PCF_BIT_ORDER( face->bitmapsFormat ) ) )
208 {
209 switch ( PCF_SCAN_UNIT( face->bitmapsFormat ) )
210 {
211 case 1:
212 break;
214 case 2:
215 TwoByteSwap( bitmap->buffer, bytes );
216 break;
218 case 4:
219 FourByteSwap( bitmap->buffer, bytes );
220 break;
221 }
222 }
224 slot->bitmap_left = metric->leftSideBearing;
225 slot->bitmap_top = metric->ascent;
227 slot->metrics.horiAdvance = metric->characterWidth << 6 ;
228 slot->metrics.horiBearingX = metric->rightSideBearing << 6 ;
229 slot->metrics.horiBearingY = metric->ascent << 6 ;
230 slot->metrics.width = metric->characterWidth << 6 ;
231 slot->metrics.height = bitmap->rows << 6;
233 slot->linearHoriAdvance = (FT_Fixed)bitmap->width << 16;
234 slot->format = ft_glyph_format_bitmap;
235 slot->flags = ft_glyph_own_bitmap;
237 FT_TRACE4(( " --- ok\n" ));
239 Exit:
240 return error;
241 }
244 static FT_UInt
245 PCF_Get_Char_Index( FT_CharMap charmap,
246 FT_Long char_code )
247 {
248 PCF_Face face = (PCF_Face)charmap->face;
249 PCF_Encoding en_table = face->encodings;
250 int low, high, mid;
253 FT_TRACE4(( "get_char_index %ld\n", char_code ));
255 low = 0;
256 high = face->nencodings - 1;
257 while ( low <= high )
258 {
259 mid = ( low + high ) / 2;
260 if ( char_code < en_table[mid].enc )
261 high = mid - 1;
262 else if ( char_code > en_table[mid].enc )
263 low = mid + 1;
264 else
265 return en_table[mid].glyph;
266 }
268 return 0;
269 }
272 FT_CALLBACK_TABLE_DEF
273 const FT_Driver_Class pcf_driver_class =
274 {
275 {
276 ft_module_font_driver,
277 sizeof ( FT_DriverRec ),
279 "pcf",
280 0x10000L,
281 0x20000L,
283 0,
285 (FT_Module_Constructor)0,
286 (FT_Module_Destructor) 0,
287 (FT_Module_Requester) 0
288 },
290 sizeof( PCF_FaceRec ),
291 sizeof( FT_SizeRec ),
292 sizeof( FT_GlyphSlotRec ),
294 (FTDriver_initFace) PCF_Init_Face,
295 (FTDriver_doneFace) PCF_Done_Face,
296 (FTDriver_initSize) 0,
297 (FTDriver_doneSize) 0,
298 (FTDriver_initGlyphSlot)0,
299 (FTDriver_doneGlyphSlot)0,
301 (FTDriver_setCharSizes) PCF_Set_Pixel_Size,
302 (FTDriver_setPixelSizes)PCF_Set_Pixel_Size,
304 (FTDriver_loadGlyph) PCF_Load_Glyph,
305 (FTDriver_getCharIndex) PCF_Get_Char_Index,
307 (FTDriver_getKerning) 0,
308 (FTDriver_attachFile) 0,
309 (FTDriver_getAdvances) 0
310 };
313 #ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS
316 /*************************************************************************/
317 /* */
318 /* <Function> */
319 /* getDriverClass */
320 /* */
321 /* <Description> */
322 /* This function is used when compiling the TrueType driver as a */
323 /* shared library (`.DLL' or `.so'). It will be used by the */
324 /* high-level library of FreeType to retrieve the address of the */
325 /* driver's generic interface. */
326 /* */
327 /* It shouldn't be implemented in a static build, as each driver must */
328 /* have the same function as an exported entry point. */
329 /* */
330 /* <Return> */
331 /* The address of the TrueType's driver generic interface. The */
332 /* format-specific interface can then be retrieved through the method */
333 /* interface->get_format_interface. */
334 /* */
335 FT_EXPORT_DEF( const FT_Driver_Class* )
336 getDriverClass( void )
337 {
338 return &pcf_driver_class;
339 }
342 #endif /* FT_CONFIG_OPTION_DYNAMIC_DRIVERS */
345 /* END */