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