[FREETYPE] Update to v2.9.0 and use this as a chance to slim down our lib a bit....
[reactos.git] / sdk / lib / 3rdparty / freetype / src / pcf / pcfdrivr.c
1 /* pcfdrivr.c
2
3 FreeType font driver for pcf files
4
5 Copyright (C) 2000-2004, 2006-2011, 2013, 2014 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 #include FT_GZIP_H
34 #include FT_LZW_H
35 #include FT_BZIP2_H
36 #include FT_ERRORS_H
37 #include FT_BDF_H
38 #include FT_TRUETYPE_IDS_H
39
40 #include "pcf.h"
41 #include "pcfdrivr.h"
42 #include "pcfread.h"
43
44 #include "pcferror.h"
45 #include "pcfutil.h"
46
47 #undef FT_COMPONENT
48 #define FT_COMPONENT trace_pcfread
49
50 #include FT_SERVICE_BDF_H
51 #include FT_SERVICE_FONT_FORMAT_H
52 #include FT_SERVICE_PROPERTIES_H
53 #include FT_DRIVER_H
54
55
56 /*************************************************************************/
57 /* */
58 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
59 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
60 /* messages during execution. */
61 /* */
62 #undef FT_COMPONENT
63 #define FT_COMPONENT trace_pcfdriver
64
65
66 typedef struct PCF_CMapRec_
67 {
68 FT_CMapRec root;
69 FT_ULong num_encodings;
70 PCF_Encoding encodings;
71
72 } PCF_CMapRec, *PCF_CMap;
73
74
75 FT_CALLBACK_DEF( FT_Error )
76 pcf_cmap_init( FT_CMap pcfcmap, /* PCF_CMap */
77 FT_Pointer init_data )
78 {
79 PCF_CMap cmap = (PCF_CMap)pcfcmap;
80 PCF_Face face = (PCF_Face)FT_CMAP_FACE( pcfcmap );
81
82 FT_UNUSED( init_data );
83
84
85 cmap->num_encodings = face->nencodings;
86 cmap->encodings = face->encodings;
87
88 return FT_Err_Ok;
89 }
90
91
92 FT_CALLBACK_DEF( void )
93 pcf_cmap_done( FT_CMap pcfcmap ) /* PCF_CMap */
94 {
95 PCF_CMap cmap = (PCF_CMap)pcfcmap;
96
97
98 cmap->encodings = NULL;
99 cmap->num_encodings = 0;
100 }
101
102
103 FT_CALLBACK_DEF( FT_UInt )
104 pcf_cmap_char_index( FT_CMap pcfcmap, /* PCF_CMap */
105 FT_UInt32 charcode )
106 {
107 PCF_CMap cmap = (PCF_CMap)pcfcmap;
108 PCF_Encoding encodings = cmap->encodings;
109 FT_ULong min, max, mid;
110 FT_UInt result = 0;
111
112
113 min = 0;
114 max = cmap->num_encodings;
115
116 while ( min < max )
117 {
118 FT_ULong code;
119
120
121 mid = ( min + max ) >> 1;
122 code = (FT_ULong)encodings[mid].enc;
123
124 if ( charcode == code )
125 {
126 result = encodings[mid].glyph + 1;
127 break;
128 }
129
130 if ( charcode < code )
131 max = mid;
132 else
133 min = mid + 1;
134 }
135
136 return result;
137 }
138
139
140 FT_CALLBACK_DEF( FT_UInt )
141 pcf_cmap_char_next( FT_CMap pcfcmap, /* PCF_CMap */
142 FT_UInt32 *acharcode )
143 {
144 PCF_CMap cmap = (PCF_CMap)pcfcmap;
145 PCF_Encoding encodings = cmap->encodings;
146 FT_ULong min, max, mid;
147 FT_ULong charcode = *acharcode + 1;
148 FT_UInt result = 0;
149
150
151 min = 0;
152 max = cmap->num_encodings;
153
154 while ( min < max )
155 {
156 FT_ULong code;
157
158
159 mid = ( min + max ) >> 1;
160 code = (FT_ULong)encodings[mid].enc;
161
162 if ( charcode == code )
163 {
164 result = encodings[mid].glyph + 1;
165 goto Exit;
166 }
167
168 if ( charcode < code )
169 max = mid;
170 else
171 min = mid + 1;
172 }
173
174 charcode = 0;
175 if ( min < cmap->num_encodings )
176 {
177 charcode = (FT_ULong)encodings[min].enc;
178 result = encodings[min].glyph + 1;
179 }
180
181 Exit:
182 if ( charcode > 0xFFFFFFFFUL )
183 {
184 FT_TRACE1(( "pcf_cmap_char_next: charcode 0x%x > 32bit API" ));
185 *acharcode = 0;
186 /* XXX: result should be changed to indicate an overflow error */
187 }
188 else
189 *acharcode = (FT_UInt32)charcode;
190 return result;
191 }
192
193
194 static
195 const FT_CMap_ClassRec pcf_cmap_class =
196 {
197 sizeof ( PCF_CMapRec ),
198 pcf_cmap_init,
199 pcf_cmap_done,
200 pcf_cmap_char_index,
201 pcf_cmap_char_next,
202
203 NULL, NULL, NULL, NULL, NULL
204 };
205
206
207 FT_CALLBACK_DEF( void )
208 PCF_Face_Done( FT_Face pcfface ) /* PCF_Face */
209 {
210 PCF_Face face = (PCF_Face)pcfface;
211 FT_Memory memory;
212
213
214 if ( !face )
215 return;
216
217 memory = FT_FACE_MEMORY( face );
218
219 FT_FREE( face->encodings );
220 FT_FREE( face->metrics );
221
222 /* free properties */
223 if ( face->properties )
224 {
225 FT_Int i;
226
227
228 for ( i = 0; i < face->nprops; i++ )
229 {
230 PCF_Property prop = &face->properties[i];
231
232
233 if ( prop )
234 {
235 FT_FREE( prop->name );
236 if ( prop->isString )
237 FT_FREE( prop->value.atom );
238 }
239 }
240
241 FT_FREE( face->properties );
242 }
243
244 FT_FREE( face->toc.tables );
245 FT_FREE( pcfface->family_name );
246 FT_FREE( pcfface->style_name );
247 FT_FREE( pcfface->available_sizes );
248 FT_FREE( face->charset_encoding );
249 FT_FREE( face->charset_registry );
250
251 /* close compressed stream if any */
252 if ( pcfface->stream == &face->comp_stream )
253 {
254 FT_Stream_Close( &face->comp_stream );
255 pcfface->stream = face->comp_source;
256 }
257 }
258
259
260 FT_CALLBACK_DEF( FT_Error )
261 PCF_Face_Init( FT_Stream stream,
262 FT_Face pcfface, /* PCF_Face */
263 FT_Int face_index,
264 FT_Int num_params,
265 FT_Parameter* params )
266 {
267 PCF_Face face = (PCF_Face)pcfface;
268 FT_Error error;
269
270 FT_UNUSED( num_params );
271 FT_UNUSED( params );
272
273
274 FT_TRACE2(( "PCF driver\n" ));
275
276 error = pcf_load_font( stream, face, face_index );
277 if ( error )
278 {
279 PCF_Face_Done( pcfface );
280
281 #if defined( FT_CONFIG_OPTION_USE_ZLIB ) || \
282 defined( FT_CONFIG_OPTION_USE_LZW ) || \
283 defined( FT_CONFIG_OPTION_USE_BZIP2 )
284
285 #ifdef FT_CONFIG_OPTION_USE_ZLIB
286 {
287 FT_Error error2;
288
289
290 /* this didn't work, try gzip support! */
291 FT_TRACE2(( " ... try gzip stream\n" ));
292 error2 = FT_Stream_OpenGzip( &face->comp_stream, stream );
293 if ( FT_ERR_EQ( error2, Unimplemented_Feature ) )
294 goto Fail;
295
296 error = error2;
297 }
298 #endif /* FT_CONFIG_OPTION_USE_ZLIB */
299
300 #ifdef FT_CONFIG_OPTION_USE_LZW
301 if ( error )
302 {
303 FT_Error error3;
304
305
306 /* this didn't work, try LZW support! */
307 FT_TRACE2(( " ... try LZW stream\n" ));
308 error3 = FT_Stream_OpenLZW( &face->comp_stream, stream );
309 if ( FT_ERR_EQ( error3, Unimplemented_Feature ) )
310 goto Fail;
311
312 error = error3;
313 }
314 #endif /* FT_CONFIG_OPTION_USE_LZW */
315
316 #ifdef FT_CONFIG_OPTION_USE_BZIP2
317 if ( error )
318 {
319 FT_Error error4;
320
321
322 /* this didn't work, try Bzip2 support! */
323 FT_TRACE2(( " ... try Bzip2 stream\n" ));
324 error4 = FT_Stream_OpenBzip2( &face->comp_stream, stream );
325 if ( FT_ERR_EQ( error4, Unimplemented_Feature ) )
326 goto Fail;
327
328 error = error4;
329 }
330 #endif /* FT_CONFIG_OPTION_USE_BZIP2 */
331
332 if ( error )
333 goto Fail;
334
335 face->comp_source = stream;
336 pcfface->stream = &face->comp_stream;
337
338 stream = pcfface->stream;
339
340 error = pcf_load_font( stream, face, face_index );
341 if ( error )
342 goto Fail;
343
344 #else /* !(FT_CONFIG_OPTION_USE_ZLIB ||
345 FT_CONFIG_OPTION_USE_LZW ||
346 FT_CONFIG_OPTION_USE_BZIP2) */
347
348 goto Fail;
349
350 #endif
351 }
352
353 /* PCF cannot have multiple faces in a single font file.
354 * XXX: A non-zero face_index is already an invalid argument, but
355 * Type1, Type42 drivers have a convention to return
356 * an invalid argument error when the font could be
357 * opened by the specified driver.
358 */
359 if ( face_index < 0 )
360 goto Exit;
361 else if ( face_index > 0 && ( face_index & 0xFFFF ) > 0 )
362 {
363 FT_ERROR(( "PCF_Face_Init: invalid face index\n" ));
364 PCF_Face_Done( pcfface );
365 return FT_THROW( Invalid_Argument );
366 }
367
368 /* set up charmap */
369 {
370 FT_String *charset_registry = face->charset_registry;
371 FT_String *charset_encoding = face->charset_encoding;
372 FT_Bool unicode_charmap = 0;
373
374
375 if ( charset_registry && charset_encoding )
376 {
377 char* s = charset_registry;
378
379
380 /* Uh, oh, compare first letters manually to avoid dependency
381 on locales. */
382 if ( ( s[0] == 'i' || s[0] == 'I' ) &&
383 ( s[1] == 's' || s[1] == 'S' ) &&
384 ( s[2] == 'o' || s[2] == 'O' ) )
385 {
386 s += 3;
387 if ( !ft_strcmp( s, "10646" ) ||
388 ( !ft_strcmp( s, "8859" ) &&
389 !ft_strcmp( face->charset_encoding, "1" ) ) )
390 unicode_charmap = 1;
391 /* another name for ASCII */
392 else if ( !ft_strcmp( s, "646.1991" ) &&
393 !ft_strcmp( face->charset_encoding, "IRV" ) )
394 unicode_charmap = 1;
395 }
396 }
397
398 {
399 FT_CharMapRec charmap;
400
401
402 charmap.face = FT_FACE( face );
403 charmap.encoding = FT_ENCODING_NONE;
404 /* initial platform/encoding should indicate unset status? */
405 charmap.platform_id = TT_PLATFORM_APPLE_UNICODE;
406 charmap.encoding_id = TT_APPLE_ID_DEFAULT;
407
408 if ( unicode_charmap )
409 {
410 charmap.encoding = FT_ENCODING_UNICODE;
411 charmap.platform_id = TT_PLATFORM_MICROSOFT;
412 charmap.encoding_id = TT_MS_ID_UNICODE_CS;
413 }
414
415 error = FT_CMap_New( &pcf_cmap_class, NULL, &charmap, NULL );
416 }
417 }
418
419 Exit:
420 return error;
421
422 Fail:
423 FT_TRACE2(( " not a PCF file\n" ));
424 PCF_Face_Done( pcfface );
425 error = FT_THROW( Unknown_File_Format ); /* error */
426 goto Exit;
427 }
428
429
430 FT_CALLBACK_DEF( FT_Error )
431 PCF_Size_Select( FT_Size size,
432 FT_ULong strike_index )
433 {
434 PCF_Accel accel = &( (PCF_Face)size->face )->accel;
435
436
437 FT_Select_Metrics( size->face, strike_index );
438
439 size->metrics.ascender = accel->fontAscent * 64;
440 size->metrics.descender = -accel->fontDescent * 64;
441 size->metrics.max_advance = accel->maxbounds.characterWidth * 64;
442
443 return FT_Err_Ok;
444 }
445
446
447 FT_CALLBACK_DEF( FT_Error )
448 PCF_Size_Request( FT_Size size,
449 FT_Size_Request req )
450 {
451 PCF_Face face = (PCF_Face)size->face;
452 FT_Bitmap_Size* bsize = size->face->available_sizes;
453 FT_Error error = FT_ERR( Invalid_Pixel_Size );
454 FT_Long height;
455
456
457 height = FT_REQUEST_HEIGHT( req );
458 height = ( height + 32 ) >> 6;
459
460 switch ( req->type )
461 {
462 case FT_SIZE_REQUEST_TYPE_NOMINAL:
463 if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) )
464 error = FT_Err_Ok;
465 break;
466
467 case FT_SIZE_REQUEST_TYPE_REAL_DIM:
468 if ( height == ( face->accel.fontAscent +
469 face->accel.fontDescent ) )
470 error = FT_Err_Ok;
471 break;
472
473 default:
474 error = FT_THROW( Unimplemented_Feature );
475 break;
476 }
477
478 if ( error )
479 return error;
480 else
481 return PCF_Size_Select( size, 0 );
482 }
483
484
485 FT_CALLBACK_DEF( FT_Error )
486 PCF_Glyph_Load( FT_GlyphSlot slot,
487 FT_Size size,
488 FT_UInt glyph_index,
489 FT_Int32 load_flags )
490 {
491 PCF_Face face = (PCF_Face)FT_SIZE_FACE( size );
492 FT_Stream stream;
493 FT_Error error = FT_Err_Ok;
494 FT_Bitmap* bitmap = &slot->bitmap;
495 PCF_Metric metric;
496 FT_ULong bytes;
497
498
499 FT_TRACE1(( "PCF_Glyph_Load: glyph index %d\n", glyph_index ));
500
501 if ( !face )
502 {
503 error = FT_THROW( Invalid_Face_Handle );
504 goto Exit;
505 }
506
507 if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
508 {
509 error = FT_THROW( Invalid_Argument );
510 goto Exit;
511 }
512
513 stream = face->root.stream;
514
515 if ( glyph_index > 0 )
516 glyph_index--;
517
518 metric = face->metrics + glyph_index;
519
520 bitmap->rows = (unsigned int)( metric->ascent +
521 metric->descent );
522 bitmap->width = (unsigned int)( metric->rightSideBearing -
523 metric->leftSideBearing );
524 bitmap->num_grays = 1;
525 bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
526
527 switch ( PCF_GLYPH_PAD( face->bitmapsFormat ) )
528 {
529 case 1:
530 bitmap->pitch = (int)( ( bitmap->width + 7 ) >> 3 );
531 break;
532
533 case 2:
534 bitmap->pitch = (int)( ( ( bitmap->width + 15 ) >> 4 ) << 1 );
535 break;
536
537 case 4:
538 bitmap->pitch = (int)( ( ( bitmap->width + 31 ) >> 5 ) << 2 );
539 break;
540
541 case 8:
542 bitmap->pitch = (int)( ( ( bitmap->width + 63 ) >> 6 ) << 3 );
543 break;
544
545 default:
546 return FT_THROW( Invalid_File_Format );
547 }
548
549 slot->format = FT_GLYPH_FORMAT_BITMAP;
550 slot->bitmap_left = metric->leftSideBearing;
551 slot->bitmap_top = metric->ascent;
552
553 slot->metrics.horiAdvance = (FT_Pos)( metric->characterWidth * 64 );
554 slot->metrics.horiBearingX = (FT_Pos)( metric->leftSideBearing * 64 );
555 slot->metrics.horiBearingY = (FT_Pos)( metric->ascent * 64 );
556 slot->metrics.width = (FT_Pos)( ( metric->rightSideBearing -
557 metric->leftSideBearing ) * 64 );
558 slot->metrics.height = (FT_Pos)( bitmap->rows * 64 );
559
560 ft_synthesize_vertical_metrics( &slot->metrics,
561 ( face->accel.fontAscent +
562 face->accel.fontDescent ) * 64 );
563
564 if ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY )
565 goto Exit;
566
567 /* XXX: to do: are there cases that need repadding the bitmap? */
568 bytes = (FT_ULong)bitmap->pitch * bitmap->rows;
569
570 error = ft_glyphslot_alloc_bitmap( slot, (FT_ULong)bytes );
571 if ( error )
572 goto Exit;
573
574 if ( FT_STREAM_SEEK( metric->bits ) ||
575 FT_STREAM_READ( bitmap->buffer, bytes ) )
576 goto Exit;
577
578 if ( PCF_BIT_ORDER( face->bitmapsFormat ) != MSBFirst )
579 BitOrderInvert( bitmap->buffer, bytes );
580
581 if ( ( PCF_BYTE_ORDER( face->bitmapsFormat ) !=
582 PCF_BIT_ORDER( face->bitmapsFormat ) ) )
583 {
584 switch ( PCF_SCAN_UNIT( face->bitmapsFormat ) )
585 {
586 case 1:
587 break;
588
589 case 2:
590 TwoByteSwap( bitmap->buffer, bytes );
591 break;
592
593 case 4:
594 FourByteSwap( bitmap->buffer, bytes );
595 break;
596 }
597 }
598
599 Exit:
600 return error;
601 }
602
603
604 /*
605 *
606 * BDF SERVICE
607 *
608 */
609
610 static FT_Error
611 pcf_get_bdf_property( PCF_Face face,
612 const char* prop_name,
613 BDF_PropertyRec *aproperty )
614 {
615 PCF_Property prop;
616
617
618 prop = pcf_find_property( face, prop_name );
619 if ( prop )
620 {
621 if ( prop->isString )
622 {
623 aproperty->type = BDF_PROPERTY_TYPE_ATOM;
624 aproperty->u.atom = prop->value.atom;
625 }
626 else
627 {
628 if ( prop->value.l > 0x7FFFFFFFL ||
629 prop->value.l < ( -1 - 0x7FFFFFFFL ) )
630 {
631 FT_TRACE1(( "pcf_get_bdf_property:" ));
632 FT_TRACE1(( " too large integer 0x%x is truncated\n" ));
633 }
634
635 /*
636 * The PCF driver loads all properties as signed integers.
637 * This really doesn't seem to be a problem, because this is
638 * sufficient for any meaningful values.
639 */
640 aproperty->type = BDF_PROPERTY_TYPE_INTEGER;
641 aproperty->u.integer = (FT_Int32)prop->value.l;
642 }
643
644 return FT_Err_Ok;
645 }
646
647 return FT_THROW( Invalid_Argument );
648 }
649
650
651 static FT_Error
652 pcf_get_charset_id( PCF_Face face,
653 const char* *acharset_encoding,
654 const char* *acharset_registry )
655 {
656 *acharset_encoding = face->charset_encoding;
657 *acharset_registry = face->charset_registry;
658
659 return FT_Err_Ok;
660 }
661
662
663 static const FT_Service_BDFRec pcf_service_bdf =
664 {
665 (FT_BDF_GetCharsetIdFunc)pcf_get_charset_id, /* get_charset_id */
666 (FT_BDF_GetPropertyFunc) pcf_get_bdf_property /* get_property */
667 };
668
669
670 /*
671 * PROPERTY SERVICE
672 *
673 */
674 static FT_Error
675 pcf_property_set( FT_Module module, /* PCF_Driver */
676 const char* property_name,
677 const void* value,
678 FT_Bool value_is_string )
679 {
680 #ifdef PCF_CONFIG_OPTION_LONG_FAMILY_NAMES
681
682 FT_Error error = FT_Err_Ok;
683 PCF_Driver driver = (PCF_Driver)module;
684
685 #ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
686 FT_UNUSED( value_is_string );
687 #endif
688
689
690 if ( !ft_strcmp( property_name, "no-long-family-names" ) )
691 {
692 #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
693 if ( value_is_string )
694 {
695 const char* s = (const char*)value;
696 long lfn = ft_strtol( s, NULL, 10 );
697
698
699 if ( lfn == 0 )
700 driver->no_long_family_names = 0;
701 else if ( lfn == 1 )
702 driver->no_long_family_names = 1;
703 else
704 return FT_THROW( Invalid_Argument );
705 }
706 else
707 #endif
708 {
709 FT_Bool* no_long_family_names = (FT_Bool*)value;
710
711
712 driver->no_long_family_names = *no_long_family_names;
713 }
714
715 return error;
716 }
717
718 #else /* !PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */
719
720 FT_UNUSED( module );
721 FT_UNUSED( value );
722 FT_UNUSED( value_is_string );
723 #ifndef FT_DEBUG_LEVEL_TRACE
724 FT_UNUSED( property_name );
725 #endif
726
727 #endif /* !PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */
728
729 FT_TRACE0(( "pcf_property_set: missing property `%s'\n",
730 property_name ));
731 return FT_THROW( Missing_Property );
732 }
733
734
735 static FT_Error
736 pcf_property_get( FT_Module module, /* PCF_Driver */
737 const char* property_name,
738 const void* value )
739 {
740 #ifdef PCF_CONFIG_OPTION_LONG_FAMILY_NAMES
741
742 FT_Error error = FT_Err_Ok;
743 PCF_Driver driver = (PCF_Driver)module;
744
745
746 if ( !ft_strcmp( property_name, "no-long-family-names" ) )
747 {
748 FT_Bool no_long_family_names = driver->no_long_family_names;
749 FT_Bool* val = (FT_Bool*)value;
750
751
752 *val = no_long_family_names;
753
754 return error;
755 }
756
757 #else /* !PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */
758
759 FT_UNUSED( module );
760 FT_UNUSED( value );
761 #ifndef FT_DEBUG_LEVEL_TRACE
762 FT_UNUSED( property_name );
763 #endif
764
765 #endif /* !PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */
766
767 FT_TRACE0(( "pcf_property_get: missing property `%s'\n",
768 property_name ));
769 return FT_THROW( Missing_Property );
770 }
771
772
773 FT_DEFINE_SERVICE_PROPERTIESREC(
774 pcf_service_properties,
775
776 (FT_Properties_SetFunc)pcf_property_set, /* set_property */
777 (FT_Properties_GetFunc)pcf_property_get ) /* get_property */
778
779
780 /*
781 *
782 * SERVICE LIST
783 *
784 */
785
786 static const FT_ServiceDescRec pcf_services[] =
787 {
788 { FT_SERVICE_ID_BDF, &pcf_service_bdf },
789 { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_PCF },
790 { FT_SERVICE_ID_PROPERTIES, &pcf_service_properties },
791 { NULL, NULL }
792 };
793
794
795 FT_CALLBACK_DEF( FT_Module_Interface )
796 pcf_driver_requester( FT_Module module,
797 const char* name )
798 {
799 FT_UNUSED( module );
800
801 return ft_service_list_lookup( pcf_services, name );
802 }
803
804
805 FT_CALLBACK_DEF( FT_Error )
806 pcf_driver_init( FT_Module module ) /* PCF_Driver */
807 {
808 #ifdef PCF_CONFIG_OPTION_LONG_FAMILY_NAMES
809 PCF_Driver driver = (PCF_Driver)module;
810
811
812 driver->no_long_family_names = 0;
813 #else
814 FT_UNUSED( module );
815 #endif
816
817 return FT_Err_Ok;
818 }
819
820
821 FT_CALLBACK_DEF( void )
822 pcf_driver_done( FT_Module module ) /* PCF_Driver */
823 {
824 FT_UNUSED( module );
825 }
826
827
828 FT_CALLBACK_TABLE_DEF
829 const FT_Driver_ClassRec pcf_driver_class =
830 {
831 {
832 FT_MODULE_FONT_DRIVER |
833 FT_MODULE_DRIVER_NO_OUTLINES,
834
835 sizeof ( PCF_DriverRec ),
836 "pcf",
837 0x10000L,
838 0x20000L,
839
840 NULL, /* module-specific interface */
841
842 pcf_driver_init, /* FT_Module_Constructor module_init */
843 pcf_driver_done, /* FT_Module_Destructor module_done */
844 pcf_driver_requester /* FT_Module_Requester get_interface */
845 },
846
847 sizeof ( PCF_FaceRec ),
848 sizeof ( FT_SizeRec ),
849 sizeof ( FT_GlyphSlotRec ),
850
851 PCF_Face_Init, /* FT_Face_InitFunc init_face */
852 PCF_Face_Done, /* FT_Face_DoneFunc done_face */
853 NULL, /* FT_Size_InitFunc init_size */
854 NULL, /* FT_Size_DoneFunc done_size */
855 NULL, /* FT_Slot_InitFunc init_slot */
856 NULL, /* FT_Slot_DoneFunc done_slot */
857
858 PCF_Glyph_Load, /* FT_Slot_LoadFunc load_glyph */
859
860 NULL, /* FT_Face_GetKerningFunc get_kerning */
861 NULL, /* FT_Face_AttachFunc attach_file */
862 NULL, /* FT_Face_GetAdvancesFunc get_advances */
863
864 PCF_Size_Request, /* FT_Size_RequestFunc request_size */
865 PCF_Size_Select /* FT_Size_SelectFunc select_size */
866 };
867
868
869 /* END */