The BIG graph update
[rrdtool.git] / libraries / freetype-2.0.5 / pcfdriver.c
1 /*  pcfdriver.c
2
3     FreeType font driver for pcf files
4
5     Copyright (C) 2000-2001 by
6     Francesco Zappa Nardelli
7
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:
14
15 The above copyright notice and this permission notice shall be included in
16 all copies or substantial portions of the Software.
17
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 */
26
27
28 #include <ft2build.h>
29
30 #include FT_INTERNAL_DEBUG_H
31 #include FT_INTERNAL_STREAM_H
32 #include FT_INTERNAL_OBJECTS_H
33
34 #include "pcf.h"
35 #include "pcfdriver.h"
36 #include "pcfutil.h"
37
38 #include "pcferror.h"
39
40
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
49
50
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;
57
58
59     FREE( face->encodings );
60     FREE( face->metrics );
61
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 );
69
70     FT_TRACE4(( "DONE_FACE!!!\n" ));
71
72     return PCF_Err_Ok;
73   }
74
75
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;
84
85     FT_UNUSED( num_params );
86     FT_UNUSED( params );
87     FT_UNUSED( face_index );
88
89
90     error = pcf_load_font( stream, face );
91     if ( error )
92       goto Fail;
93
94     return PCF_Err_Ok;
95
96   Fail:
97     FT_TRACE2(( "[not a valid PCF file]\n" ));
98     PCF_Done_Face( face );
99
100     return PCF_Err_Unknown_File_Format; /* error */
101   }
102
103
104   static FT_Error
105   PCF_Set_Pixel_Size( FT_Size  size )
106   {
107     PCF_Face face = (PCF_Face)FT_SIZE_FACE( size );
108
109
110     FT_TRACE4(( "rec %d - pres %d\n", size->metrics.y_ppem,
111                                       face->root.available_sizes->height ));
112
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;
122
123       return PCF_Err_Ok;
124     }
125     else
126     {
127       FT_TRACE4(( "size WRONG\n" ));
128       return PCF_Err_Invalid_Pixel_Size;
129     }
130   }
131
132
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;
145
146     FT_Stream   stream = face->root.stream;
147
148     FT_UNUSED( load_flags );
149
150
151     FT_TRACE4(( "load_glyph %d ---", glyph_index ));
152
153     if ( !face )
154     {
155       error = PCF_Err_Invalid_Argument;
156       goto Exit;
157     }
158
159     metric = face->metrics + glyph_index;
160
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;
165
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 ) ));
170
171     switch ( PCF_GLYPH_PAD( face->bitmapsFormat ) )
172     {
173     case 1:
174       bitmap->pitch = ( bitmap->width + 7 ) >> 3;
175       break;
176
177     case 2:
178       bitmap->pitch = ( ( bitmap->width + 15 ) >> 4 ) << 1;
179       break;
180
181     case 4:
182       bitmap->pitch = ( ( bitmap->width + 31 ) >> 5 ) << 2;
183       break;
184
185     case 8:
186       bitmap->pitch = ( ( bitmap->width + 63 ) >> 6 ) << 3;
187       break;
188
189     default:
190       return PCF_Err_Invalid_File_Format;
191     }
192
193     /* XXX: to do: are there cases that need repadding the bitmap? */
194     bytes = bitmap->pitch * bitmap->rows;
195
196     if ( ALLOC( bitmap->buffer, bytes ) )
197       goto Exit;
198
199     if ( FILE_Seek( metric->bits )        ||
200          FILE_Read( bitmap->buffer, bytes ) )
201       goto Exit;
202
203     if ( PCF_BIT_ORDER( face->bitmapsFormat ) != MSBFirst )
204       BitOrderInvert( bitmap->buffer,bytes );
205
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;
213
214       case 2:
215         TwoByteSwap( bitmap->buffer, bytes );
216         break;
217
218       case 4:
219         FourByteSwap( bitmap->buffer, bytes );
220         break;
221       }
222     }
223
224     slot->bitmap_left = metric->leftSideBearing;
225     slot->bitmap_top  = metric->ascent;
226
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;
232
233     slot->linearHoriAdvance = (FT_Fixed)bitmap->width << 16;
234     slot->format            = ft_glyph_format_bitmap;
235     slot->flags             = ft_glyph_own_bitmap;
236
237     FT_TRACE4(( " --- ok\n" ));
238
239   Exit:
240     return error;
241   }
242
243
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;
251
252
253     FT_TRACE4(( "get_char_index %ld\n", char_code ));
254
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     }
267
268     return 0;
269   }
270
271
272   FT_CALLBACK_TABLE_DEF
273   const FT_Driver_Class  pcf_driver_class =
274   {
275     {
276       ft_module_font_driver,
277       sizeof ( FT_DriverRec ),
278
279       "pcf",
280       0x10000L,
281       0x20000L,
282
283       0,
284
285       (FT_Module_Constructor)0,
286       (FT_Module_Destructor) 0,
287       (FT_Module_Requester)  0
288     },
289
290     sizeof( PCF_FaceRec ),
291     sizeof( FT_SizeRec ),
292     sizeof( FT_GlyphSlotRec ),
293
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,
300
301     (FTDriver_setCharSizes) PCF_Set_Pixel_Size,
302     (FTDriver_setPixelSizes)PCF_Set_Pixel_Size,
303
304     (FTDriver_loadGlyph)    PCF_Load_Glyph,
305     (FTDriver_getCharIndex) PCF_Get_Char_Index,
306
307     (FTDriver_getKerning)   0,
308     (FTDriver_attachFile)   0,
309     (FTDriver_getAdvances)  0
310   };
311
312
313 #ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS
314
315
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   }
340
341
342 #endif /* FT_CONFIG_OPTION_DYNAMIC_DRIVERS */
343
344
345 /* END */