Sync trunk.
[reactos.git] / lib / 3rdparty / freetype / src / bdf / bdfdrivr.c
1 /* bdfdrivr.c
2
3 FreeType font driver for bdf files
4
5 Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 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 #include <ft2build.h>
28
29 #include FT_INTERNAL_DEBUG_H
30 #include FT_INTERNAL_STREAM_H
31 #include FT_INTERNAL_OBJECTS_H
32 #include FT_BDF_H
33
34 #include FT_SERVICE_BDF_H
35 #include FT_SERVICE_XFREE86_NAME_H
36
37 #include "bdf.h"
38 #include "bdfdrivr.h"
39
40 #include "bdferror.h"
41
42
43 /*************************************************************************/
44 /* */
45 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
46 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
47 /* messages during execution. */
48 /* */
49 #undef FT_COMPONENT
50 #define FT_COMPONENT trace_bdfdriver
51
52
53 typedef struct BDF_CMapRec_
54 {
55 FT_CMapRec cmap;
56 FT_ULong num_encodings; /* ftobjs.h: FT_CMap->clazz->size */
57 BDF_encoding_el* encodings;
58
59 } BDF_CMapRec, *BDF_CMap;
60
61
62 FT_CALLBACK_DEF( FT_Error )
63 bdf_cmap_init( FT_CMap bdfcmap,
64 FT_Pointer init_data )
65 {
66 BDF_CMap cmap = (BDF_CMap)bdfcmap;
67 BDF_Face face = (BDF_Face)FT_CMAP_FACE( cmap );
68 FT_UNUSED( init_data );
69
70
71 cmap->num_encodings = face->bdffont->glyphs_used;
72 cmap->encodings = face->en_table;
73
74 return BDF_Err_Ok;
75 }
76
77
78 FT_CALLBACK_DEF( void )
79 bdf_cmap_done( FT_CMap bdfcmap )
80 {
81 BDF_CMap cmap = (BDF_CMap)bdfcmap;
82
83
84 cmap->encodings = NULL;
85 cmap->num_encodings = 0;
86 }
87
88
89 FT_CALLBACK_DEF( FT_UInt )
90 bdf_cmap_char_index( FT_CMap bdfcmap,
91 FT_UInt32 charcode )
92 {
93 BDF_CMap cmap = (BDF_CMap)bdfcmap;
94 BDF_encoding_el* encodings = cmap->encodings;
95 FT_ULong min, max, mid; /* num_encodings */
96 FT_UShort result = 0; /* encodings->glyph */
97
98
99 min = 0;
100 max = cmap->num_encodings;
101
102 while ( min < max )
103 {
104 FT_ULong code;
105
106
107 mid = ( min + max ) >> 1;
108 code = encodings[mid].enc;
109
110 if ( charcode == code )
111 {
112 /* increase glyph index by 1 -- */
113 /* we reserve slot 0 for the undefined glyph */
114 result = encodings[mid].glyph + 1;
115 break;
116 }
117
118 if ( charcode < code )
119 max = mid;
120 else
121 min = mid + 1;
122 }
123
124 return result;
125 }
126
127
128 FT_CALLBACK_DEF( FT_UInt )
129 bdf_cmap_char_next( FT_CMap bdfcmap,
130 FT_UInt32 *acharcode )
131 {
132 BDF_CMap cmap = (BDF_CMap)bdfcmap;
133 BDF_encoding_el* encodings = cmap->encodings;
134 FT_ULong min, max, mid; /* num_encodings */
135 FT_UShort result = 0; /* encodings->glyph */
136 FT_ULong charcode = *acharcode + 1;
137
138
139 min = 0;
140 max = cmap->num_encodings;
141
142 while ( min < max )
143 {
144 FT_ULong code; /* same as BDF_encoding_el.enc */
145
146
147 mid = ( min + max ) >> 1;
148 code = encodings[mid].enc;
149
150 if ( charcode == code )
151 {
152 /* increase glyph index by 1 -- */
153 /* we reserve slot 0 for the undefined glyph */
154 result = encodings[mid].glyph + 1;
155 goto Exit;
156 }
157
158 if ( charcode < code )
159 max = mid;
160 else
161 min = mid + 1;
162 }
163
164 charcode = 0;
165 if ( min < cmap->num_encodings )
166 {
167 charcode = encodings[min].enc;
168 result = encodings[min].glyph + 1;
169 }
170
171 Exit:
172 if ( charcode > 0xFFFFFFFFUL )
173 {
174 FT_TRACE1(( "bdf_cmap_char_next: charcode 0x%x > 32bit API" ));
175 *acharcode = 0;
176 /* XXX: result should be changed to indicate an overflow error */
177 }
178 else
179 *acharcode = (FT_UInt32)charcode;
180 return result;
181 }
182
183
184 FT_CALLBACK_TABLE_DEF
185 const FT_CMap_ClassRec bdf_cmap_class =
186 {
187 sizeof ( BDF_CMapRec ),
188 bdf_cmap_init,
189 bdf_cmap_done,
190 bdf_cmap_char_index,
191 bdf_cmap_char_next,
192
193 NULL, NULL, NULL, NULL, NULL
194 };
195
196
197 static FT_Error
198 bdf_interpret_style( BDF_Face bdf )
199 {
200 FT_Error error = BDF_Err_Ok;
201 FT_Face face = FT_FACE( bdf );
202 FT_Memory memory = face->memory;
203 bdf_font_t* font = bdf->bdffont;
204 bdf_property_t* prop;
205
206 char* strings[4] = { NULL, NULL, NULL, NULL };
207 size_t nn, len, lengths[4];
208
209
210 face->style_flags = 0;
211
212 prop = bdf_get_font_property( font, (char *)"SLANT" );
213 if ( prop && prop->format == BDF_ATOM &&
214 prop->value.atom &&
215 ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' ||
216 *(prop->value.atom) == 'I' || *(prop->value.atom) == 'i' ) )
217 {
218 face->style_flags |= FT_STYLE_FLAG_ITALIC;
219 strings[2] = ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' )
220 ? (char *)"Oblique"
221 : (char *)"Italic";
222 }
223
224 prop = bdf_get_font_property( font, (char *)"WEIGHT_NAME" );
225 if ( prop && prop->format == BDF_ATOM &&
226 prop->value.atom &&
227 ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) )
228 {
229 face->style_flags |= FT_STYLE_FLAG_BOLD;
230 strings[1] = (char *)"Bold";
231 }
232
233 prop = bdf_get_font_property( font, (char *)"SETWIDTH_NAME" );
234 if ( prop && prop->format == BDF_ATOM &&
235 prop->value.atom && *(prop->value.atom) &&
236 !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
237 strings[3] = (char *)(prop->value.atom);
238
239 prop = bdf_get_font_property( font, (char *)"ADD_STYLE_NAME" );
240 if ( prop && prop->format == BDF_ATOM &&
241 prop->value.atom && *(prop->value.atom) &&
242 !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
243 strings[0] = (char *)(prop->value.atom);
244
245 len = 0;
246
247 for ( len = 0, nn = 0; nn < 4; nn++ )
248 {
249 lengths[nn] = 0;
250 if ( strings[nn] )
251 {
252 lengths[nn] = ft_strlen( strings[nn] );
253 len += lengths[nn] + 1;
254 }
255 }
256
257 if ( len == 0 )
258 {
259 strings[0] = (char *)"Regular";
260 lengths[0] = ft_strlen( strings[0] );
261 len = lengths[0] + 1;
262 }
263
264 {
265 char* s;
266
267
268 if ( FT_ALLOC( face->style_name, len ) )
269 return error;
270
271 s = face->style_name;
272
273 for ( nn = 0; nn < 4; nn++ )
274 {
275 char* src = strings[nn];
276
277
278 len = lengths[nn];
279
280 if ( src == NULL )
281 continue;
282
283 /* separate elements with a space */
284 if ( s != face->style_name )
285 *s++ = ' ';
286
287 ft_memcpy( s, src, len );
288
289 /* need to convert spaces to dashes for */
290 /* add_style_name and setwidth_name */
291 if ( nn == 0 || nn == 3 )
292 {
293 size_t mm;
294
295
296 for ( mm = 0; mm < len; mm++ )
297 if ( s[mm] == ' ' )
298 s[mm] = '-';
299 }
300
301 s += len;
302 }
303 *s = 0;
304 }
305
306 return error;
307 }
308
309
310 FT_CALLBACK_DEF( void )
311 BDF_Face_Done( FT_Face bdfface ) /* BDF_Face */
312 {
313 BDF_Face face = (BDF_Face)bdfface;
314 FT_Memory memory;
315
316
317 if ( !face )
318 return;
319
320 memory = FT_FACE_MEMORY( face );
321
322 bdf_free_font( face->bdffont );
323
324 FT_FREE( face->en_table );
325
326 FT_FREE( face->charset_encoding );
327 FT_FREE( face->charset_registry );
328 FT_FREE( bdfface->family_name );
329 FT_FREE( bdfface->style_name );
330
331 FT_FREE( bdfface->available_sizes );
332
333 FT_FREE( face->bdffont );
334
335 FT_TRACE4(( "BDF_Face_Done: done face\n" ));
336 }
337
338
339 FT_CALLBACK_DEF( FT_Error )
340 BDF_Face_Init( FT_Stream stream,
341 FT_Face bdfface, /* BDF_Face */
342 FT_Int face_index,
343 FT_Int num_params,
344 FT_Parameter* params )
345 {
346 FT_Error error = BDF_Err_Ok;
347 BDF_Face face = (BDF_Face)bdfface;
348 FT_Memory memory = FT_FACE_MEMORY( face );
349
350 bdf_font_t* font = NULL;
351 bdf_options_t options;
352
353 FT_UNUSED( num_params );
354 FT_UNUSED( params );
355 FT_UNUSED( face_index );
356
357
358 if ( FT_STREAM_SEEK( 0 ) )
359 goto Exit;
360
361 options.correct_metrics = 1; /* FZ XXX: options semantics */
362 options.keep_unencoded = 1;
363 options.keep_comments = 0;
364 options.font_spacing = BDF_PROPORTIONAL;
365
366 error = bdf_load_font( stream, memory, &options, &font );
367 if ( error == BDF_Err_Missing_Startfont_Field )
368 {
369 FT_TRACE2(( "[not a valid BDF file]\n" ));
370 goto Fail;
371 }
372 else if ( error )
373 goto Exit;
374
375 /* we have a bdf font: let's construct the face object */
376 face->bdffont = font;
377 {
378 bdf_property_t* prop = NULL;
379
380
381 FT_TRACE4(( "number of glyphs: %d (%d)\n",
382 font->glyphs_size,
383 font->glyphs_used ));
384 FT_TRACE4(( "number of unencoded glyphs: %d (%d)\n",
385 font->unencoded_size,
386 font->unencoded_used ));
387
388 bdfface->num_faces = 1;
389 bdfface->face_index = 0;
390 bdfface->face_flags = FT_FACE_FLAG_FIXED_SIZES |
391 FT_FACE_FLAG_HORIZONTAL |
392 FT_FACE_FLAG_FAST_GLYPHS;
393
394 prop = bdf_get_font_property( font, "SPACING" );
395 if ( prop && prop->format == BDF_ATOM &&
396 prop->value.atom &&
397 ( *(prop->value.atom) == 'M' || *(prop->value.atom) == 'm' ||
398 *(prop->value.atom) == 'C' || *(prop->value.atom) == 'c' ) )
399 bdfface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
400
401 /* FZ XXX: TO DO: FT_FACE_FLAGS_VERTICAL */
402 /* FZ XXX: I need a font to implement this */
403
404 prop = bdf_get_font_property( font, "FAMILY_NAME" );
405 if ( prop && prop->value.atom )
406 {
407 if ( FT_STRDUP( bdfface->family_name, prop->value.atom ) )
408 goto Exit;
409 }
410 else
411 bdfface->family_name = 0;
412
413 if ( ( error = bdf_interpret_style( face ) ) != 0 )
414 goto Exit;
415
416 /* the number of glyphs (with one slot for the undefined glyph */
417 /* at position 0 and all unencoded glyphs) */
418 bdfface->num_glyphs = font->glyphs_size + 1;
419
420 bdfface->num_fixed_sizes = 1;
421 if ( FT_NEW_ARRAY( bdfface->available_sizes, 1 ) )
422 goto Exit;
423
424 {
425 FT_Bitmap_Size* bsize = bdfface->available_sizes;
426 FT_Short resolution_x = 0, resolution_y = 0;
427
428
429 FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) );
430
431 bsize->height = (FT_Short)( font->font_ascent + font->font_descent );
432
433 prop = bdf_get_font_property( font, "AVERAGE_WIDTH" );
434 if ( prop )
435 bsize->width = (FT_Short)( ( prop->value.l + 5 ) / 10 );
436 else
437 bsize->width = (FT_Short)( bsize->height * 2/3 );
438
439 prop = bdf_get_font_property( font, "POINT_SIZE" );
440 if ( prop )
441 /* convert from 722.7 decipoints to 72 points per inch */
442 bsize->size =
443 (FT_Pos)( ( prop->value.l * 64 * 7200 + 36135L ) / 72270L );
444 else
445 bsize->size = bsize->width << 6;
446
447 prop = bdf_get_font_property( font, "PIXEL_SIZE" );
448 if ( prop )
449 bsize->y_ppem = (FT_Short)prop->value.l << 6;
450
451 prop = bdf_get_font_property( font, "RESOLUTION_X" );
452 if ( prop )
453 resolution_x = (FT_Short)prop->value.l;
454
455 prop = bdf_get_font_property( font, "RESOLUTION_Y" );
456 if ( prop )
457 resolution_y = (FT_Short)prop->value.l;
458
459 if ( bsize->y_ppem == 0 )
460 {
461 bsize->y_ppem = bsize->size;
462 if ( resolution_y )
463 bsize->y_ppem = bsize->y_ppem * resolution_y / 72;
464 }
465 if ( resolution_x && resolution_y )
466 bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y;
467 else
468 bsize->x_ppem = bsize->y_ppem;
469 }
470
471 /* encoding table */
472 {
473 bdf_glyph_t* cur = font->glyphs;
474 unsigned long n;
475
476
477 if ( FT_NEW_ARRAY( face->en_table, font->glyphs_size ) )
478 goto Exit;
479
480 face->default_glyph = 0;
481 for ( n = 0; n < font->glyphs_size; n++ )
482 {
483 (face->en_table[n]).enc = cur[n].encoding;
484 FT_TRACE4(( "idx %d, val 0x%lX\n", n, cur[n].encoding ));
485 (face->en_table[n]).glyph = (FT_Short)n;
486
487 if ( cur[n].encoding == font->default_char )
488 {
489 if ( n < FT_UINT_MAX )
490 face->default_glyph = (FT_UInt)n;
491 else
492 FT_TRACE1(( "idx %d is too large for this system\n", n ));
493 }
494 }
495 }
496
497 /* charmaps */
498 {
499 bdf_property_t *charset_registry = 0, *charset_encoding = 0;
500 FT_Bool unicode_charmap = 0;
501
502
503 charset_registry =
504 bdf_get_font_property( font, "CHARSET_REGISTRY" );
505 charset_encoding =
506 bdf_get_font_property( font, "CHARSET_ENCODING" );
507 if ( charset_registry && charset_encoding )
508 {
509 if ( charset_registry->format == BDF_ATOM &&
510 charset_encoding->format == BDF_ATOM &&
511 charset_registry->value.atom &&
512 charset_encoding->value.atom )
513 {
514 const char* s;
515
516
517 if ( FT_STRDUP( face->charset_encoding,
518 charset_encoding->value.atom ) ||
519 FT_STRDUP( face->charset_registry,
520 charset_registry->value.atom ) )
521 goto Exit;
522
523 /* Uh, oh, compare first letters manually to avoid dependency */
524 /* on locales. */
525 s = face->charset_registry;
526 if ( ( s[0] == 'i' || s[0] == 'I' ) &&
527 ( s[1] == 's' || s[1] == 'S' ) &&
528 ( s[2] == 'o' || s[2] == 'O' ) )
529 {
530 s += 3;
531 if ( !ft_strcmp( s, "10646" ) ||
532 ( !ft_strcmp( s, "8859" ) &&
533 !ft_strcmp( face->charset_encoding, "1" ) ) )
534 unicode_charmap = 1;
535 }
536
537 {
538 FT_CharMapRec charmap;
539
540
541 charmap.face = FT_FACE( face );
542 charmap.encoding = FT_ENCODING_NONE;
543 charmap.platform_id = 0;
544 charmap.encoding_id = 0;
545
546 if ( unicode_charmap )
547 {
548 charmap.encoding = FT_ENCODING_UNICODE;
549 charmap.platform_id = 3;
550 charmap.encoding_id = 1;
551 }
552
553 error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL );
554
555 #if 0
556 /* Select default charmap */
557 if ( bdfface->num_charmaps )
558 bdfface->charmap = bdfface->charmaps[0];
559 #endif
560 }
561
562 goto Exit;
563 }
564 }
565
566 /* otherwise assume Adobe standard encoding */
567
568 {
569 FT_CharMapRec charmap;
570
571
572 charmap.face = FT_FACE( face );
573 charmap.encoding = FT_ENCODING_ADOBE_STANDARD;
574 charmap.platform_id = 7;
575 charmap.encoding_id = 0;
576
577 error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL );
578
579 /* Select default charmap */
580 if ( bdfface->num_charmaps )
581 bdfface->charmap = bdfface->charmaps[0];
582 }
583 }
584 }
585
586 Exit:
587 return error;
588
589 Fail:
590 BDF_Face_Done( bdfface );
591 return BDF_Err_Unknown_File_Format;
592 }
593
594
595 FT_CALLBACK_DEF( FT_Error )
596 BDF_Size_Select( FT_Size size,
597 FT_ULong strike_index )
598 {
599 bdf_font_t* bdffont = ( (BDF_Face)size->face )->bdffont;
600
601
602 FT_Select_Metrics( size->face, strike_index );
603
604 size->metrics.ascender = bdffont->font_ascent << 6;
605 size->metrics.descender = -bdffont->font_descent << 6;
606 size->metrics.max_advance = bdffont->bbx.width << 6;
607
608 return BDF_Err_Ok;
609 }
610
611
612 FT_CALLBACK_DEF( FT_Error )
613 BDF_Size_Request( FT_Size size,
614 FT_Size_Request req )
615 {
616 FT_Face face = size->face;
617 FT_Bitmap_Size* bsize = face->available_sizes;
618 bdf_font_t* bdffont = ( (BDF_Face)face )->bdffont;
619 FT_Error error = BDF_Err_Invalid_Pixel_Size;
620 FT_Long height;
621
622
623 height = FT_REQUEST_HEIGHT( req );
624 height = ( height + 32 ) >> 6;
625
626 switch ( req->type )
627 {
628 case FT_SIZE_REQUEST_TYPE_NOMINAL:
629 if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) )
630 error = BDF_Err_Ok;
631 break;
632
633 case FT_SIZE_REQUEST_TYPE_REAL_DIM:
634 if ( height == ( bdffont->font_ascent +
635 bdffont->font_descent ) )
636 error = BDF_Err_Ok;
637 break;
638
639 default:
640 error = BDF_Err_Unimplemented_Feature;
641 break;
642 }
643
644 if ( error )
645 return error;
646 else
647 return BDF_Size_Select( size, 0 );
648 }
649
650
651
652 FT_CALLBACK_DEF( FT_Error )
653 BDF_Glyph_Load( FT_GlyphSlot slot,
654 FT_Size size,
655 FT_UInt glyph_index,
656 FT_Int32 load_flags )
657 {
658 BDF_Face bdf = (BDF_Face)FT_SIZE_FACE( size );
659 FT_Face face = FT_FACE( bdf );
660 FT_Error error = BDF_Err_Ok;
661 FT_Bitmap* bitmap = &slot->bitmap;
662 bdf_glyph_t glyph;
663 int bpp = bdf->bdffont->bpp;
664
665 FT_UNUSED( load_flags );
666
667
668 if ( !face || glyph_index >= (FT_UInt)face->num_glyphs )
669 {
670 error = BDF_Err_Invalid_Argument;
671 goto Exit;
672 }
673
674 /* index 0 is the undefined glyph */
675 if ( glyph_index == 0 )
676 glyph_index = bdf->default_glyph;
677 else
678 glyph_index--;
679
680 /* slot, bitmap => freetype, glyph => bdflib */
681 glyph = bdf->bdffont->glyphs[glyph_index];
682
683 bitmap->rows = glyph.bbx.height;
684 bitmap->width = glyph.bbx.width;
685 if ( glyph.bpr > INT_MAX )
686 FT_TRACE1(( "BDF_Glyph_Load: too large pitch %d is truncated\n",
687 glyph.bpr ));
688 bitmap->pitch = (int)glyph.bpr; /* same as FT_Bitmap.pitch */
689
690 /* note: we don't allocate a new array to hold the bitmap; */
691 /* we can simply point to it */
692 ft_glyphslot_set_bitmap( slot, glyph.bitmap );
693
694 switch ( bpp )
695 {
696 case 1:
697 bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
698 break;
699 case 2:
700 bitmap->pixel_mode = FT_PIXEL_MODE_GRAY2;
701 break;
702 case 4:
703 bitmap->pixel_mode = FT_PIXEL_MODE_GRAY4;
704 break;
705 case 8:
706 bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;
707 bitmap->num_grays = 256;
708 break;
709 }
710
711 slot->format = FT_GLYPH_FORMAT_BITMAP;
712 slot->bitmap_left = glyph.bbx.x_offset;
713 slot->bitmap_top = glyph.bbx.ascent;
714
715 slot->metrics.horiAdvance = glyph.dwidth << 6;
716 slot->metrics.horiBearingX = glyph.bbx.x_offset << 6;
717 slot->metrics.horiBearingY = glyph.bbx.ascent << 6;
718 slot->metrics.width = bitmap->width << 6;
719 slot->metrics.height = bitmap->rows << 6;
720
721 /*
722 * XXX DWIDTH1 and VVECTOR should be parsed and
723 * used here, provided such fonts do exist.
724 */
725 ft_synthesize_vertical_metrics( &slot->metrics,
726 bdf->bdffont->bbx.height << 6 );
727
728 Exit:
729 return error;
730 }
731
732
733 /*
734 *
735 * BDF SERVICE
736 *
737 */
738
739 static FT_Error
740 bdf_get_bdf_property( BDF_Face face,
741 const char* prop_name,
742 BDF_PropertyRec *aproperty )
743 {
744 bdf_property_t* prop;
745
746
747 FT_ASSERT( face && face->bdffont );
748
749 prop = bdf_get_font_property( face->bdffont, prop_name );
750 if ( prop )
751 {
752 switch ( prop->format )
753 {
754 case BDF_ATOM:
755 aproperty->type = BDF_PROPERTY_TYPE_ATOM;
756 aproperty->u.atom = prop->value.atom;
757 break;
758
759 case BDF_INTEGER:
760 if ( prop->value.l > 0x7FFFFFFFL || prop->value.l < ( -1 - 0x7FFFFFFFL ) )
761 {
762 FT_TRACE1(( "bdf_get_bdf_property: " ));
763 FT_TRACE1(( "too large integer 0x%x is truncated\n" ));
764 }
765 aproperty->type = BDF_PROPERTY_TYPE_INTEGER;
766 aproperty->u.integer = (FT_Int32)prop->value.l;
767 break;
768
769 case BDF_CARDINAL:
770 if ( prop->value.ul > 0xFFFFFFFFUL )
771 {
772 FT_TRACE1(( "bdf_get_bdf_property: " ));
773 FT_TRACE1(( "too large cardinal 0x%x is truncated\n" ));
774 }
775 aproperty->type = BDF_PROPERTY_TYPE_CARDINAL;
776 aproperty->u.cardinal = (FT_UInt32)prop->value.ul;
777 break;
778
779 default:
780 goto Fail;
781 }
782 return 0;
783 }
784
785 Fail:
786 return BDF_Err_Invalid_Argument;
787 }
788
789
790 static FT_Error
791 bdf_get_charset_id( BDF_Face face,
792 const char* *acharset_encoding,
793 const char* *acharset_registry )
794 {
795 *acharset_encoding = face->charset_encoding;
796 *acharset_registry = face->charset_registry;
797
798 return 0;
799 }
800
801
802 static const FT_Service_BDFRec bdf_service_bdf =
803 {
804 (FT_BDF_GetCharsetIdFunc)bdf_get_charset_id,
805 (FT_BDF_GetPropertyFunc) bdf_get_bdf_property
806 };
807
808
809 /*
810 *
811 * SERVICES LIST
812 *
813 */
814
815 static const FT_ServiceDescRec bdf_services[] =
816 {
817 { FT_SERVICE_ID_BDF, &bdf_service_bdf },
818 { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_BDF },
819 { NULL, NULL }
820 };
821
822
823 FT_CALLBACK_DEF( FT_Module_Interface )
824 bdf_driver_requester( FT_Module module,
825 const char* name )
826 {
827 FT_UNUSED( module );
828
829 return ft_service_list_lookup( bdf_services, name );
830 }
831
832
833
834 FT_CALLBACK_TABLE_DEF
835 const FT_Driver_ClassRec bdf_driver_class =
836 {
837 {
838 FT_MODULE_FONT_DRIVER |
839 FT_MODULE_DRIVER_NO_OUTLINES,
840 sizeof ( FT_DriverRec ),
841
842 "bdf",
843 0x10000L,
844 0x20000L,
845
846 0,
847
848 (FT_Module_Constructor)0,
849 (FT_Module_Destructor) 0,
850 (FT_Module_Requester) bdf_driver_requester
851 },
852
853 sizeof ( BDF_FaceRec ),
854 sizeof ( FT_SizeRec ),
855 sizeof ( FT_GlyphSlotRec ),
856
857 BDF_Face_Init,
858 BDF_Face_Done,
859 0, /* FT_Size_InitFunc */
860 0, /* FT_Size_DoneFunc */
861 0, /* FT_Slot_InitFunc */
862 0, /* FT_Slot_DoneFunc */
863
864 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
865 ft_stub_set_char_sizes,
866 ft_stub_set_pixel_sizes,
867 #endif
868 BDF_Glyph_Load,
869
870 0, /* FT_Face_GetKerningFunc */
871 0, /* FT_Face_AttachFunc */
872 0, /* FT_Face_GetAdvancesFunc */
873
874 BDF_Size_Request,
875 BDF_Size_Select
876 };
877
878
879 /* END */