Disabling auto-refresh of game list by default, as it is causing bugs sometimes
[open-ps2-loader.git] / thirdparty / freetype-2.3.12 / src / pcf / pcfdrivr.c
blobb34e542aeb0a3f1add1a69796cb2dfa3ca25cfae
1 /* pcfdrivr.c
3 FreeType font driver for pcf files
5 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 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.
28 #include <ft2build.h>
30 #include FT_INTERNAL_DEBUG_H
31 #include FT_INTERNAL_STREAM_H
32 #include FT_INTERNAL_OBJECTS_H
33 #include FT_GZIP_H
34 #include FT_LZW_H
35 #include FT_ERRORS_H
36 #include FT_BDF_H
38 #include "pcf.h"
39 #include "pcfdrivr.h"
40 #include "pcfread.h"
42 #include "pcferror.h"
43 #include "pcfutil.h"
45 #undef FT_COMPONENT
46 #define FT_COMPONENT trace_pcfread
48 #include FT_SERVICE_BDF_H
49 #include FT_SERVICE_XFREE86_NAME_H
52 /*************************************************************************/
53 /* */
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. */
57 /* */
58 #undef FT_COMPONENT
59 #define FT_COMPONENT trace_pcfdriver
62 typedef struct PCF_CMapRec_
64 FT_CMapRec root;
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;
84 return PCF_Err_Ok;
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 */
101 FT_UInt32 charcode )
103 PCF_CMap cmap = (PCF_CMap)pcfcmap;
104 PCF_Encoding encodings = cmap->encodings;
105 FT_UInt min, max, mid;
106 FT_UInt result = 0;
109 min = 0;
110 max = cmap->num_encodings;
112 while ( min < max )
114 FT_ULong code;
117 mid = ( min + max ) >> 1;
118 code = encodings[mid].enc;
120 if ( charcode == code )
122 result = encodings[mid].glyph + 1;
123 break;
126 if ( charcode < code )
127 max = mid;
128 else
129 min = mid + 1;
132 return result;
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_ULong charcode = *acharcode + 1;
144 FT_UInt result = 0;
147 min = 0;
148 max = cmap->num_encodings;
150 while ( min < max )
152 FT_ULong code;
155 mid = ( min + max ) >> 1;
156 code = encodings[mid].enc;
158 if ( charcode == code )
160 result = encodings[mid].glyph + 1;
161 goto Exit;
164 if ( charcode < code )
165 max = mid;
166 else
167 min = mid + 1;
170 charcode = 0;
171 if ( min < cmap->num_encodings )
173 charcode = encodings[min].enc;
174 result = encodings[min].glyph + 1;
177 Exit:
178 if ( charcode > 0xFFFFFFFFUL )
180 FT_TRACE1(( "pcf_cmap_char_next: charcode 0x%x > 32bit API" ));
181 *acharcode = 0;
182 /* XXX: result should be changed to indicate an overflow error */
184 else
185 *acharcode = (FT_UInt32)charcode;
186 return result;
190 FT_CALLBACK_TABLE_DEF
191 const FT_CMap_ClassRec pcf_cmap_class =
193 sizeof ( PCF_CMapRec ),
194 pcf_cmap_init,
195 pcf_cmap_done,
196 pcf_cmap_char_index,
197 pcf_cmap_char_next,
199 NULL, NULL, NULL, NULL, NULL
203 FT_CALLBACK_DEF( void )
204 PCF_Face_Done( FT_Face pcfface ) /* PCF_Face */
206 PCF_Face face = (PCF_Face)pcfface;
207 FT_Memory memory;
210 if ( !face )
211 return;
213 memory = FT_FACE_MEMORY( face );
215 FT_FREE( face->encodings );
216 FT_FREE( face->metrics );
218 /* free properties */
220 PCF_Property prop;
221 FT_Int i;
224 if ( face->properties )
226 for ( i = 0; i < face->nprops; i++ )
228 prop = &face->properties[i];
230 if ( prop ) {
231 FT_FREE( prop->name );
232 if ( prop->isString )
233 FT_FREE( prop->value.atom );
237 FT_FREE( face->properties );
240 FT_FREE( face->toc.tables );
241 FT_FREE( pcfface->family_name );
242 FT_FREE( pcfface->style_name );
243 FT_FREE( pcfface->available_sizes );
244 FT_FREE( face->charset_encoding );
245 FT_FREE( face->charset_registry );
247 FT_TRACE4(( "PCF_Face_Done: done face\n" ));
249 /* close gzip/LZW stream if any */
250 if ( pcfface->stream == &face->gzip_stream )
252 FT_Stream_Close( &face->gzip_stream );
253 pcfface->stream = face->gzip_source;
258 FT_CALLBACK_DEF( FT_Error )
259 PCF_Face_Init( FT_Stream stream,
260 FT_Face pcfface, /* PCF_Face */
261 FT_Int face_index,
262 FT_Int num_params,
263 FT_Parameter* params )
265 PCF_Face face = (PCF_Face)pcfface;
266 FT_Error error = PCF_Err_Ok;
268 FT_UNUSED( num_params );
269 FT_UNUSED( params );
270 FT_UNUSED( face_index );
273 error = pcf_load_font( stream, face );
274 if ( error )
276 PCF_Face_Done( pcfface );
278 #if defined( FT_CONFIG_OPTION_USE_ZLIB ) || \
279 defined( FT_CONFIG_OPTION_USE_LZW )
281 #ifdef FT_CONFIG_OPTION_USE_ZLIB
283 FT_Error error2;
286 /* this didn't work, try gzip support! */
287 error2 = FT_Stream_OpenGzip( &face->gzip_stream, stream );
288 if ( FT_ERROR_BASE( error2 ) == FT_Err_Unimplemented_Feature )
289 goto Fail;
291 error = error2;
293 #endif /* FT_CONFIG_OPTION_USE_ZLIB */
295 #ifdef FT_CONFIG_OPTION_USE_LZW
296 if ( error )
298 FT_Error error3;
301 /* this didn't work, try LZW support! */
302 error3 = FT_Stream_OpenLZW( &face->gzip_stream, stream );
303 if ( FT_ERROR_BASE( error3 ) == FT_Err_Unimplemented_Feature )
304 goto Fail;
306 error = error3;
308 #endif /* FT_CONFIG_OPTION_USE_LZW */
310 if ( error )
311 goto Fail;
313 face->gzip_source = stream;
314 pcfface->stream = &face->gzip_stream;
316 stream = pcfface->stream;
318 error = pcf_load_font( stream, face );
319 if ( error )
320 goto Fail;
322 #else /* !(FT_CONFIG_OPTION_USE_ZLIB || FT_CONFIG_OPTION_USE_LZW) */
324 goto Fail;
326 #endif
329 /* set up charmap */
331 FT_String *charset_registry = face->charset_registry;
332 FT_String *charset_encoding = face->charset_encoding;
333 FT_Bool unicode_charmap = 0;
336 if ( charset_registry && charset_encoding )
338 char* s = charset_registry;
341 /* Uh, oh, compare first letters manually to avoid dependency
342 on locales. */
343 if ( ( s[0] == 'i' || s[0] == 'I' ) &&
344 ( s[1] == 's' || s[1] == 'S' ) &&
345 ( s[2] == 'o' || s[2] == 'O' ) )
347 s += 3;
348 if ( !ft_strcmp( s, "10646" ) ||
349 ( !ft_strcmp( s, "8859" ) &&
350 !ft_strcmp( face->charset_encoding, "1" ) ) )
351 unicode_charmap = 1;
356 FT_CharMapRec charmap;
359 charmap.face = FT_FACE( face );
360 charmap.encoding = FT_ENCODING_NONE;
361 charmap.platform_id = 0;
362 charmap.encoding_id = 0;
364 if ( unicode_charmap )
366 charmap.encoding = FT_ENCODING_UNICODE;
367 charmap.platform_id = 3;
368 charmap.encoding_id = 1;
371 error = FT_CMap_New( &pcf_cmap_class, NULL, &charmap, NULL );
373 #if 0
374 /* Select default charmap */
375 if ( pcfface->num_charmaps )
376 pcfface->charmap = pcfface->charmaps[0];
377 #endif
381 Exit:
382 return error;
384 Fail:
385 FT_TRACE2(( "[not a valid PCF file]\n" ));
386 PCF_Face_Done( pcfface );
387 error = PCF_Err_Unknown_File_Format; /* error */
388 goto Exit;
392 FT_CALLBACK_DEF( FT_Error )
393 PCF_Size_Select( FT_Size size,
394 FT_ULong strike_index )
396 PCF_Accel accel = &( (PCF_Face)size->face )->accel;
399 FT_Select_Metrics( size->face, strike_index );
401 size->metrics.ascender = accel->fontAscent << 6;
402 size->metrics.descender = -accel->fontDescent << 6;
403 size->metrics.max_advance = accel->maxbounds.characterWidth << 6;
405 return PCF_Err_Ok;
409 FT_CALLBACK_DEF( FT_Error )
410 PCF_Size_Request( FT_Size size,
411 FT_Size_Request req )
413 PCF_Face face = (PCF_Face)size->face;
414 FT_Bitmap_Size* bsize = size->face->available_sizes;
415 FT_Error error = PCF_Err_Invalid_Pixel_Size;
416 FT_Long height;
419 height = FT_REQUEST_HEIGHT( req );
420 height = ( height + 32 ) >> 6;
422 switch ( req->type )
424 case FT_SIZE_REQUEST_TYPE_NOMINAL:
425 if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) )
426 error = PCF_Err_Ok;
427 break;
429 case FT_SIZE_REQUEST_TYPE_REAL_DIM:
430 if ( height == ( face->accel.fontAscent +
431 face->accel.fontDescent ) )
432 error = PCF_Err_Ok;
433 break;
435 default:
436 error = PCF_Err_Unimplemented_Feature;
437 break;
440 if ( error )
441 return error;
442 else
443 return PCF_Size_Select( size, 0 );
447 FT_CALLBACK_DEF( FT_Error )
448 PCF_Glyph_Load( FT_GlyphSlot slot,
449 FT_Size size,
450 FT_UInt glyph_index,
451 FT_Int32 load_flags )
453 PCF_Face face = (PCF_Face)FT_SIZE_FACE( size );
454 FT_Stream stream;
455 FT_Error error = PCF_Err_Ok;
456 FT_Bitmap* bitmap = &slot->bitmap;
457 PCF_Metric metric;
458 FT_Offset bytes;
460 FT_UNUSED( load_flags );
463 FT_TRACE4(( "load_glyph %d ---", glyph_index ));
465 if ( !face || glyph_index >= (FT_UInt)face->root.num_glyphs )
467 error = PCF_Err_Invalid_Argument;
468 goto Exit;
471 stream = face->root.stream;
473 if ( glyph_index > 0 )
474 glyph_index--;
476 metric = face->metrics + glyph_index;
478 bitmap->rows = metric->ascent + metric->descent;
479 bitmap->width = metric->rightSideBearing - metric->leftSideBearing;
480 bitmap->num_grays = 1;
481 bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
483 FT_TRACE6(( "BIT_ORDER %d ; BYTE_ORDER %d ; GLYPH_PAD %d\n",
484 PCF_BIT_ORDER( face->bitmapsFormat ),
485 PCF_BYTE_ORDER( face->bitmapsFormat ),
486 PCF_GLYPH_PAD( face->bitmapsFormat ) ));
488 switch ( PCF_GLYPH_PAD( face->bitmapsFormat ) )
490 case 1:
491 bitmap->pitch = ( bitmap->width + 7 ) >> 3;
492 break;
494 case 2:
495 bitmap->pitch = ( ( bitmap->width + 15 ) >> 4 ) << 1;
496 break;
498 case 4:
499 bitmap->pitch = ( ( bitmap->width + 31 ) >> 5 ) << 2;
500 break;
502 case 8:
503 bitmap->pitch = ( ( bitmap->width + 63 ) >> 6 ) << 3;
504 break;
506 default:
507 return PCF_Err_Invalid_File_Format;
510 /* XXX: to do: are there cases that need repadding the bitmap? */
511 bytes = bitmap->pitch * bitmap->rows;
513 error = ft_glyphslot_alloc_bitmap( slot, bytes );
514 if ( error )
515 goto Exit;
517 if ( FT_STREAM_SEEK( metric->bits ) ||
518 FT_STREAM_READ( bitmap->buffer, bytes ) )
519 goto Exit;
521 if ( PCF_BIT_ORDER( face->bitmapsFormat ) != MSBFirst )
522 BitOrderInvert( bitmap->buffer, bytes );
524 if ( ( PCF_BYTE_ORDER( face->bitmapsFormat ) !=
525 PCF_BIT_ORDER( face->bitmapsFormat ) ) )
527 switch ( PCF_SCAN_UNIT( face->bitmapsFormat ) )
529 case 1:
530 break;
532 case 2:
533 TwoByteSwap( bitmap->buffer, bytes );
534 break;
536 case 4:
537 FourByteSwap( bitmap->buffer, bytes );
538 break;
542 slot->format = FT_GLYPH_FORMAT_BITMAP;
543 slot->bitmap_left = metric->leftSideBearing;
544 slot->bitmap_top = metric->ascent;
546 slot->metrics.horiAdvance = metric->characterWidth << 6;
547 slot->metrics.horiBearingX = metric->leftSideBearing << 6;
548 slot->metrics.horiBearingY = metric->ascent << 6;
549 slot->metrics.width = ( metric->rightSideBearing -
550 metric->leftSideBearing ) << 6;
551 slot->metrics.height = bitmap->rows << 6;
553 ft_synthesize_vertical_metrics( &slot->metrics,
554 ( face->accel.fontAscent +
555 face->accel.fontDescent ) << 6 );
557 FT_TRACE4(( " --- ok\n" ));
559 Exit:
560 return error;
566 * BDF SERVICE
570 static FT_Error
571 pcf_get_bdf_property( PCF_Face face,
572 const char* prop_name,
573 BDF_PropertyRec *aproperty )
575 PCF_Property prop;
578 prop = pcf_find_property( face, prop_name );
579 if ( prop != NULL )
581 if ( prop->isString )
583 aproperty->type = BDF_PROPERTY_TYPE_ATOM;
584 aproperty->u.atom = prop->value.atom;
586 else
588 if ( prop->value.l > 0x7FFFFFFFL || prop->value.l < ( -1 - 0x7FFFFFFFL ) )
590 FT_TRACE1(( "pcf_get_bdf_property: " ));
591 FT_TRACE1(( "too large integer 0x%x is truncated\n" ));
593 /* Apparently, the PCF driver loads all properties as signed integers!
594 * This really doesn't seem to be a problem, because this is
595 * sufficient for any meaningful values.
597 aproperty->type = BDF_PROPERTY_TYPE_INTEGER;
598 aproperty->u.integer = (FT_Int32)prop->value.l;
600 return 0;
603 return PCF_Err_Invalid_Argument;
607 static FT_Error
608 pcf_get_charset_id( PCF_Face face,
609 const char* *acharset_encoding,
610 const char* *acharset_registry )
612 *acharset_encoding = face->charset_encoding;
613 *acharset_registry = face->charset_registry;
615 return 0;
619 static const FT_Service_BDFRec pcf_service_bdf =
621 (FT_BDF_GetCharsetIdFunc)pcf_get_charset_id,
622 (FT_BDF_GetPropertyFunc) pcf_get_bdf_property
628 * SERVICE LIST
632 static const FT_ServiceDescRec pcf_services[] =
634 { FT_SERVICE_ID_BDF, &pcf_service_bdf },
635 { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PCF },
636 { NULL, NULL }
640 FT_CALLBACK_DEF( FT_Module_Interface )
641 pcf_driver_requester( FT_Module module,
642 const char* name )
644 FT_UNUSED( module );
646 return ft_service_list_lookup( pcf_services, name );
650 FT_CALLBACK_TABLE_DEF
651 const FT_Driver_ClassRec pcf_driver_class =
654 FT_MODULE_FONT_DRIVER |
655 FT_MODULE_DRIVER_NO_OUTLINES,
656 sizeof ( FT_DriverRec ),
658 "pcf",
659 0x10000L,
660 0x20000L,
666 pcf_driver_requester
669 sizeof ( PCF_FaceRec ),
670 sizeof ( FT_SizeRec ),
671 sizeof ( FT_GlyphSlotRec ),
673 PCF_Face_Init,
674 PCF_Face_Done,
675 0, /* FT_Size_InitFunc */
676 0, /* FT_Size_DoneFunc */
677 0, /* FT_Slot_InitFunc */
678 0, /* FT_Slot_DoneFunc */
680 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
681 ft_stub_set_char_sizes,
682 ft_stub_set_pixel_sizes,
683 #endif
684 PCF_Glyph_Load,
686 0, /* FT_Face_GetKerningFunc */
687 0, /* FT_Face_AttachFunc */
688 0, /* FT_Face_GetAdvancesFunc */
690 PCF_Size_Request,
691 PCF_Size_Select
695 /* END */