1 /* pcfdrivr.c |
|
2 |
|
3 FreeType font driver for pcf files |
|
4 |
|
5 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, |
|
6 2010 by |
|
7 Francesco Zappa Nardelli |
|
8 |
|
9 Permission is hereby granted, free of charge, to any person obtaining a copy |
|
10 of this software and associated documentation files (the "Software"), to deal |
|
11 in the Software without restriction, including without limitation the rights |
|
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
13 copies of the Software, and to permit persons to whom the Software is |
|
14 furnished to do so, subject to the following conditions: |
|
15 |
|
16 The above copyright notice and this permission notice shall be included in |
|
17 all copies or substantial portions of the Software. |
|
18 |
|
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
25 THE SOFTWARE. |
|
26 */ |
|
27 |
|
28 |
|
29 #include <ft2build.h> |
|
30 |
|
31 #include FT_INTERNAL_DEBUG_H |
|
32 #include FT_INTERNAL_STREAM_H |
|
33 #include FT_INTERNAL_OBJECTS_H |
|
34 #include FT_GZIP_H |
|
35 #include FT_LZW_H |
|
36 #include FT_BZIP2_H |
|
37 #include FT_ERRORS_H |
|
38 #include FT_BDF_H |
|
39 #include FT_TRUETYPE_IDS_H |
|
40 |
|
41 #include "pcf.h" |
|
42 #include "pcfdrivr.h" |
|
43 #include "pcfread.h" |
|
44 |
|
45 #include "pcferror.h" |
|
46 #include "pcfutil.h" |
|
47 |
|
48 #undef FT_COMPONENT |
|
49 #define FT_COMPONENT trace_pcfread |
|
50 |
|
51 #include FT_SERVICE_BDF_H |
|
52 #include FT_SERVICE_XFREE86_NAME_H |
|
53 |
|
54 |
|
55 /*************************************************************************/ |
|
56 /* */ |
|
57 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
|
58 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ |
|
59 /* messages during execution. */ |
|
60 /* */ |
|
61 #undef FT_COMPONENT |
|
62 #define FT_COMPONENT trace_pcfdriver |
|
63 |
|
64 |
|
65 typedef struct PCF_CMapRec_ |
|
66 { |
|
67 FT_CMapRec root; |
|
68 FT_UInt num_encodings; |
|
69 PCF_Encoding encodings; |
|
70 |
|
71 } PCF_CMapRec, *PCF_CMap; |
|
72 |
|
73 |
|
74 FT_CALLBACK_DEF( FT_Error ) |
|
75 pcf_cmap_init( FT_CMap pcfcmap, /* PCF_CMap */ |
|
76 FT_Pointer init_data ) |
|
77 { |
|
78 PCF_CMap cmap = (PCF_CMap)pcfcmap; |
|
79 PCF_Face face = (PCF_Face)FT_CMAP_FACE( pcfcmap ); |
|
80 |
|
81 FT_UNUSED( init_data ); |
|
82 |
|
83 |
|
84 cmap->num_encodings = (FT_UInt)face->nencodings; |
|
85 cmap->encodings = face->encodings; |
|
86 |
|
87 return PCF_Err_Ok; |
|
88 } |
|
89 |
|
90 |
|
91 FT_CALLBACK_DEF( void ) |
|
92 pcf_cmap_done( FT_CMap pcfcmap ) /* PCF_CMap */ |
|
93 { |
|
94 PCF_CMap cmap = (PCF_CMap)pcfcmap; |
|
95 |
|
96 |
|
97 cmap->encodings = NULL; |
|
98 cmap->num_encodings = 0; |
|
99 } |
|
100 |
|
101 |
|
102 FT_CALLBACK_DEF( FT_UInt ) |
|
103 pcf_cmap_char_index( FT_CMap pcfcmap, /* PCF_CMap */ |
|
104 FT_UInt32 charcode ) |
|
105 { |
|
106 PCF_CMap cmap = (PCF_CMap)pcfcmap; |
|
107 PCF_Encoding encodings = cmap->encodings; |
|
108 FT_UInt min, max, mid; |
|
109 FT_UInt result = 0; |
|
110 |
|
111 |
|
112 min = 0; |
|
113 max = cmap->num_encodings; |
|
114 |
|
115 while ( min < max ) |
|
116 { |
|
117 FT_ULong code; |
|
118 |
|
119 |
|
120 mid = ( min + max ) >> 1; |
|
121 code = encodings[mid].enc; |
|
122 |
|
123 if ( charcode == code ) |
|
124 { |
|
125 result = encodings[mid].glyph + 1; |
|
126 break; |
|
127 } |
|
128 |
|
129 if ( charcode < code ) |
|
130 max = mid; |
|
131 else |
|
132 min = mid + 1; |
|
133 } |
|
134 |
|
135 return result; |
|
136 } |
|
137 |
|
138 |
|
139 FT_CALLBACK_DEF( FT_UInt ) |
|
140 pcf_cmap_char_next( FT_CMap pcfcmap, /* PCF_CMap */ |
|
141 FT_UInt32 *acharcode ) |
|
142 { |
|
143 PCF_CMap cmap = (PCF_CMap)pcfcmap; |
|
144 PCF_Encoding encodings = cmap->encodings; |
|
145 FT_UInt min, max, mid; |
|
146 FT_ULong charcode = *acharcode + 1; |
|
147 FT_UInt result = 0; |
|
148 |
|
149 |
|
150 min = 0; |
|
151 max = cmap->num_encodings; |
|
152 |
|
153 while ( min < max ) |
|
154 { |
|
155 FT_ULong code; |
|
156 |
|
157 |
|
158 mid = ( min + max ) >> 1; |
|
159 code = encodings[mid].enc; |
|
160 |
|
161 if ( charcode == code ) |
|
162 { |
|
163 result = encodings[mid].glyph + 1; |
|
164 goto Exit; |
|
165 } |
|
166 |
|
167 if ( charcode < code ) |
|
168 max = mid; |
|
169 else |
|
170 min = mid + 1; |
|
171 } |
|
172 |
|
173 charcode = 0; |
|
174 if ( min < cmap->num_encodings ) |
|
175 { |
|
176 charcode = encodings[min].enc; |
|
177 result = encodings[min].glyph + 1; |
|
178 } |
|
179 |
|
180 Exit: |
|
181 if ( charcode > 0xFFFFFFFFUL ) |
|
182 { |
|
183 FT_TRACE1(( "pcf_cmap_char_next: charcode 0x%x > 32bit API" )); |
|
184 *acharcode = 0; |
|
185 /* XXX: result should be changed to indicate an overflow error */ |
|
186 } |
|
187 else |
|
188 *acharcode = (FT_UInt32)charcode; |
|
189 return result; |
|
190 } |
|
191 |
|
192 |
|
193 FT_CALLBACK_TABLE_DEF |
|
194 const FT_CMap_ClassRec pcf_cmap_class = |
|
195 { |
|
196 sizeof ( PCF_CMapRec ), |
|
197 pcf_cmap_init, |
|
198 pcf_cmap_done, |
|
199 pcf_cmap_char_index, |
|
200 pcf_cmap_char_next, |
|
201 |
|
202 NULL, NULL, NULL, NULL, NULL |
|
203 }; |
|
204 |
|
205 |
|
206 FT_CALLBACK_DEF( void ) |
|
207 PCF_Face_Done( FT_Face pcfface ) /* PCF_Face */ |
|
208 { |
|
209 PCF_Face face = (PCF_Face)pcfface; |
|
210 FT_Memory memory; |
|
211 |
|
212 |
|
213 if ( !face ) |
|
214 return; |
|
215 |
|
216 memory = FT_FACE_MEMORY( face ); |
|
217 |
|
218 FT_FREE( face->encodings ); |
|
219 FT_FREE( face->metrics ); |
|
220 |
|
221 /* free properties */ |
|
222 { |
|
223 PCF_Property prop; |
|
224 FT_Int i; |
|
225 |
|
226 |
|
227 if ( face->properties ) |
|
228 { |
|
229 for ( i = 0; i < face->nprops; i++ ) |
|
230 { |
|
231 prop = &face->properties[i]; |
|
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 FT_TRACE4(( "PCF_Face_Done: done face\n" )); |
|
252 |
|
253 /* close compressed stream if any */ |
|
254 if ( pcfface->stream == &face->comp_stream ) |
|
255 { |
|
256 FT_Stream_Close( &face->comp_stream ); |
|
257 pcfface->stream = face->comp_source; |
|
258 } |
|
259 } |
|
260 |
|
261 |
|
262 FT_CALLBACK_DEF( FT_Error ) |
|
263 PCF_Face_Init( FT_Stream stream, |
|
264 FT_Face pcfface, /* PCF_Face */ |
|
265 FT_Int face_index, |
|
266 FT_Int num_params, |
|
267 FT_Parameter* params ) |
|
268 { |
|
269 PCF_Face face = (PCF_Face)pcfface; |
|
270 FT_Error error = PCF_Err_Ok; |
|
271 |
|
272 FT_UNUSED( num_params ); |
|
273 FT_UNUSED( params ); |
|
274 FT_UNUSED( face_index ); |
|
275 |
|
276 |
|
277 error = pcf_load_font( stream, face ); |
|
278 if ( error ) |
|
279 { |
|
280 PCF_Face_Done( pcfface ); |
|
281 |
|
282 #if defined( FT_CONFIG_OPTION_USE_ZLIB ) || \ |
|
283 defined( FT_CONFIG_OPTION_USE_LZW ) || \ |
|
284 defined( FT_CONFIG_OPTION_USE_BZIP2 ) |
|
285 |
|
286 #ifdef FT_CONFIG_OPTION_USE_ZLIB |
|
287 { |
|
288 FT_Error error2; |
|
289 |
|
290 |
|
291 /* this didn't work, try gzip support! */ |
|
292 error2 = FT_Stream_OpenGzip( &face->comp_stream, stream ); |
|
293 if ( FT_ERROR_BASE( error2 ) == FT_Err_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 error3 = FT_Stream_OpenLZW( &face->comp_stream, stream ); |
|
308 if ( FT_ERROR_BASE( error3 ) == FT_Err_Unimplemented_Feature ) |
|
309 goto Fail; |
|
310 |
|
311 error = error3; |
|
312 } |
|
313 #endif /* FT_CONFIG_OPTION_USE_LZW */ |
|
314 |
|
315 #ifdef FT_CONFIG_OPTION_USE_BZIP2 |
|
316 if ( error ) |
|
317 { |
|
318 FT_Error error4; |
|
319 |
|
320 |
|
321 /* this didn't work, try Bzip2 support! */ |
|
322 error4 = FT_Stream_OpenBzip2( &face->comp_stream, stream ); |
|
323 if ( FT_ERROR_BASE( error4 ) == FT_Err_Unimplemented_Feature ) |
|
324 goto Fail; |
|
325 |
|
326 error = error4; |
|
327 } |
|
328 #endif /* FT_CONFIG_OPTION_USE_BZIP2 */ |
|
329 |
|
330 if ( error ) |
|
331 goto Fail; |
|
332 |
|
333 face->comp_source = stream; |
|
334 pcfface->stream = &face->comp_stream; |
|
335 |
|
336 stream = pcfface->stream; |
|
337 |
|
338 error = pcf_load_font( stream, face ); |
|
339 if ( error ) |
|
340 goto Fail; |
|
341 |
|
342 #else /* !(FT_CONFIG_OPTION_USE_ZLIB || |
|
343 FT_CONFIG_OPTION_USE_LZW || |
|
344 FT_CONFIG_OPTION_USE_BZIP2) */ |
|
345 |
|
346 goto Fail; |
|
347 |
|
348 #endif |
|
349 } |
|
350 |
|
351 /* set up charmap */ |
|
352 { |
|
353 FT_String *charset_registry = face->charset_registry; |
|
354 FT_String *charset_encoding = face->charset_encoding; |
|
355 FT_Bool unicode_charmap = 0; |
|
356 |
|
357 |
|
358 if ( charset_registry && charset_encoding ) |
|
359 { |
|
360 char* s = charset_registry; |
|
361 |
|
362 |
|
363 /* Uh, oh, compare first letters manually to avoid dependency |
|
364 on locales. */ |
|
365 if ( ( s[0] == 'i' || s[0] == 'I' ) && |
|
366 ( s[1] == 's' || s[1] == 'S' ) && |
|
367 ( s[2] == 'o' || s[2] == 'O' ) ) |
|
368 { |
|
369 s += 3; |
|
370 if ( !ft_strcmp( s, "10646" ) || |
|
371 ( !ft_strcmp( s, "8859" ) && |
|
372 !ft_strcmp( face->charset_encoding, "1" ) ) ) |
|
373 unicode_charmap = 1; |
|
374 } |
|
375 } |
|
376 |
|
377 { |
|
378 FT_CharMapRec charmap; |
|
379 |
|
380 |
|
381 charmap.face = FT_FACE( face ); |
|
382 charmap.encoding = FT_ENCODING_NONE; |
|
383 /* initial platform/encoding should indicate unset status? */ |
|
384 charmap.platform_id = TT_PLATFORM_APPLE_UNICODE; |
|
385 charmap.encoding_id = TT_APPLE_ID_DEFAULT; |
|
386 |
|
387 if ( unicode_charmap ) |
|
388 { |
|
389 charmap.encoding = FT_ENCODING_UNICODE; |
|
390 charmap.platform_id = TT_PLATFORM_MICROSOFT; |
|
391 charmap.encoding_id = TT_MS_ID_UNICODE_CS; |
|
392 } |
|
393 |
|
394 error = FT_CMap_New( &pcf_cmap_class, NULL, &charmap, NULL ); |
|
395 |
|
396 #if 0 |
|
397 /* Select default charmap */ |
|
398 if ( pcfface->num_charmaps ) |
|
399 pcfface->charmap = pcfface->charmaps[0]; |
|
400 #endif |
|
401 } |
|
402 } |
|
403 |
|
404 Exit: |
|
405 return error; |
|
406 |
|
407 Fail: |
|
408 FT_TRACE2(( "[not a valid PCF file]\n" )); |
|
409 PCF_Face_Done( pcfface ); |
|
410 error = PCF_Err_Unknown_File_Format; /* error */ |
|
411 goto Exit; |
|
412 } |
|
413 |
|
414 |
|
415 FT_CALLBACK_DEF( FT_Error ) |
|
416 PCF_Size_Select( FT_Size size, |
|
417 FT_ULong strike_index ) |
|
418 { |
|
419 PCF_Accel accel = &( (PCF_Face)size->face )->accel; |
|
420 |
|
421 |
|
422 FT_Select_Metrics( size->face, strike_index ); |
|
423 |
|
424 size->metrics.ascender = accel->fontAscent << 6; |
|
425 size->metrics.descender = -accel->fontDescent << 6; |
|
426 size->metrics.max_advance = accel->maxbounds.characterWidth << 6; |
|
427 |
|
428 return PCF_Err_Ok; |
|
429 } |
|
430 |
|
431 |
|
432 FT_CALLBACK_DEF( FT_Error ) |
|
433 PCF_Size_Request( FT_Size size, |
|
434 FT_Size_Request req ) |
|
435 { |
|
436 PCF_Face face = (PCF_Face)size->face; |
|
437 FT_Bitmap_Size* bsize = size->face->available_sizes; |
|
438 FT_Error error = PCF_Err_Invalid_Pixel_Size; |
|
439 FT_Long height; |
|
440 |
|
441 |
|
442 height = FT_REQUEST_HEIGHT( req ); |
|
443 height = ( height + 32 ) >> 6; |
|
444 |
|
445 switch ( req->type ) |
|
446 { |
|
447 case FT_SIZE_REQUEST_TYPE_NOMINAL: |
|
448 if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) ) |
|
449 error = PCF_Err_Ok; |
|
450 break; |
|
451 |
|
452 case FT_SIZE_REQUEST_TYPE_REAL_DIM: |
|
453 if ( height == ( face->accel.fontAscent + |
|
454 face->accel.fontDescent ) ) |
|
455 error = PCF_Err_Ok; |
|
456 break; |
|
457 |
|
458 default: |
|
459 error = PCF_Err_Unimplemented_Feature; |
|
460 break; |
|
461 } |
|
462 |
|
463 if ( error ) |
|
464 return error; |
|
465 else |
|
466 return PCF_Size_Select( size, 0 ); |
|
467 } |
|
468 |
|
469 |
|
470 FT_CALLBACK_DEF( FT_Error ) |
|
471 PCF_Glyph_Load( FT_GlyphSlot slot, |
|
472 FT_Size size, |
|
473 FT_UInt glyph_index, |
|
474 FT_Int32 load_flags ) |
|
475 { |
|
476 PCF_Face face = (PCF_Face)FT_SIZE_FACE( size ); |
|
477 FT_Stream stream; |
|
478 FT_Error error = PCF_Err_Ok; |
|
479 FT_Bitmap* bitmap = &slot->bitmap; |
|
480 PCF_Metric metric; |
|
481 FT_Offset bytes; |
|
482 |
|
483 FT_UNUSED( load_flags ); |
|
484 |
|
485 |
|
486 FT_TRACE4(( "load_glyph %d ---", glyph_index )); |
|
487 |
|
488 if ( !face || glyph_index >= (FT_UInt)face->root.num_glyphs ) |
|
489 { |
|
490 error = PCF_Err_Invalid_Argument; |
|
491 goto Exit; |
|
492 } |
|
493 |
|
494 stream = face->root.stream; |
|
495 |
|
496 if ( glyph_index > 0 ) |
|
497 glyph_index--; |
|
498 |
|
499 metric = face->metrics + glyph_index; |
|
500 |
|
501 bitmap->rows = metric->ascent + metric->descent; |
|
502 bitmap->width = metric->rightSideBearing - metric->leftSideBearing; |
|
503 bitmap->num_grays = 1; |
|
504 bitmap->pixel_mode = FT_PIXEL_MODE_MONO; |
|
505 |
|
506 FT_TRACE6(( "BIT_ORDER %d ; BYTE_ORDER %d ; GLYPH_PAD %d\n", |
|
507 PCF_BIT_ORDER( face->bitmapsFormat ), |
|
508 PCF_BYTE_ORDER( face->bitmapsFormat ), |
|
509 PCF_GLYPH_PAD( face->bitmapsFormat ) )); |
|
510 |
|
511 switch ( PCF_GLYPH_PAD( face->bitmapsFormat ) ) |
|
512 { |
|
513 case 1: |
|
514 bitmap->pitch = ( bitmap->width + 7 ) >> 3; |
|
515 break; |
|
516 |
|
517 case 2: |
|
518 bitmap->pitch = ( ( bitmap->width + 15 ) >> 4 ) << 1; |
|
519 break; |
|
520 |
|
521 case 4: |
|
522 bitmap->pitch = ( ( bitmap->width + 31 ) >> 5 ) << 2; |
|
523 break; |
|
524 |
|
525 case 8: |
|
526 bitmap->pitch = ( ( bitmap->width + 63 ) >> 6 ) << 3; |
|
527 break; |
|
528 |
|
529 default: |
|
530 return PCF_Err_Invalid_File_Format; |
|
531 } |
|
532 |
|
533 /* XXX: to do: are there cases that need repadding the bitmap? */ |
|
534 bytes = bitmap->pitch * bitmap->rows; |
|
535 |
|
536 error = ft_glyphslot_alloc_bitmap( slot, bytes ); |
|
537 if ( error ) |
|
538 goto Exit; |
|
539 |
|
540 if ( FT_STREAM_SEEK( metric->bits ) || |
|
541 FT_STREAM_READ( bitmap->buffer, bytes ) ) |
|
542 goto Exit; |
|
543 |
|
544 if ( PCF_BIT_ORDER( face->bitmapsFormat ) != MSBFirst ) |
|
545 BitOrderInvert( bitmap->buffer, bytes ); |
|
546 |
|
547 if ( ( PCF_BYTE_ORDER( face->bitmapsFormat ) != |
|
548 PCF_BIT_ORDER( face->bitmapsFormat ) ) ) |
|
549 { |
|
550 switch ( PCF_SCAN_UNIT( face->bitmapsFormat ) ) |
|
551 { |
|
552 case 1: |
|
553 break; |
|
554 |
|
555 case 2: |
|
556 TwoByteSwap( bitmap->buffer, bytes ); |
|
557 break; |
|
558 |
|
559 case 4: |
|
560 FourByteSwap( bitmap->buffer, bytes ); |
|
561 break; |
|
562 } |
|
563 } |
|
564 |
|
565 slot->format = FT_GLYPH_FORMAT_BITMAP; |
|
566 slot->bitmap_left = metric->leftSideBearing; |
|
567 slot->bitmap_top = metric->ascent; |
|
568 |
|
569 slot->metrics.horiAdvance = metric->characterWidth << 6; |
|
570 slot->metrics.horiBearingX = metric->leftSideBearing << 6; |
|
571 slot->metrics.horiBearingY = metric->ascent << 6; |
|
572 slot->metrics.width = ( metric->rightSideBearing - |
|
573 metric->leftSideBearing ) << 6; |
|
574 slot->metrics.height = bitmap->rows << 6; |
|
575 |
|
576 ft_synthesize_vertical_metrics( &slot->metrics, |
|
577 ( face->accel.fontAscent + |
|
578 face->accel.fontDescent ) << 6 ); |
|
579 |
|
580 FT_TRACE4(( " --- ok\n" )); |
|
581 |
|
582 Exit: |
|
583 return error; |
|
584 } |
|
585 |
|
586 |
|
587 /* |
|
588 * |
|
589 * BDF SERVICE |
|
590 * |
|
591 */ |
|
592 |
|
593 static FT_Error |
|
594 pcf_get_bdf_property( PCF_Face face, |
|
595 const char* prop_name, |
|
596 BDF_PropertyRec *aproperty ) |
|
597 { |
|
598 PCF_Property prop; |
|
599 |
|
600 |
|
601 prop = pcf_find_property( face, prop_name ); |
|
602 if ( prop != NULL ) |
|
603 { |
|
604 if ( prop->isString ) |
|
605 { |
|
606 aproperty->type = BDF_PROPERTY_TYPE_ATOM; |
|
607 aproperty->u.atom = prop->value.atom; |
|
608 } |
|
609 else |
|
610 { |
|
611 if ( prop->value.l > 0x7FFFFFFFL || prop->value.l < ( -1 - 0x7FFFFFFFL ) ) |
|
612 { |
|
613 FT_TRACE1(( "pcf_get_bdf_property: " )); |
|
614 FT_TRACE1(( "too large integer 0x%x is truncated\n" )); |
|
615 } |
|
616 /* Apparently, the PCF driver loads all properties as signed integers! |
|
617 * This really doesn't seem to be a problem, because this is |
|
618 * sufficient for any meaningful values. |
|
619 */ |
|
620 aproperty->type = BDF_PROPERTY_TYPE_INTEGER; |
|
621 aproperty->u.integer = (FT_Int32)prop->value.l; |
|
622 } |
|
623 return 0; |
|
624 } |
|
625 |
|
626 return PCF_Err_Invalid_Argument; |
|
627 } |
|
628 |
|
629 |
|
630 static FT_Error |
|
631 pcf_get_charset_id( PCF_Face face, |
|
632 const char* *acharset_encoding, |
|
633 const char* *acharset_registry ) |
|
634 { |
|
635 *acharset_encoding = face->charset_encoding; |
|
636 *acharset_registry = face->charset_registry; |
|
637 |
|
638 return 0; |
|
639 } |
|
640 |
|
641 |
|
642 static const FT_Service_BDFRec pcf_service_bdf = |
|
643 { |
|
644 (FT_BDF_GetCharsetIdFunc)pcf_get_charset_id, |
|
645 (FT_BDF_GetPropertyFunc) pcf_get_bdf_property |
|
646 }; |
|
647 |
|
648 |
|
649 /* |
|
650 * |
|
651 * SERVICE LIST |
|
652 * |
|
653 */ |
|
654 |
|
655 static const FT_ServiceDescRec pcf_services[] = |
|
656 { |
|
657 { FT_SERVICE_ID_BDF, &pcf_service_bdf }, |
|
658 { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PCF }, |
|
659 { NULL, NULL } |
|
660 }; |
|
661 |
|
662 |
|
663 FT_CALLBACK_DEF( FT_Module_Interface ) |
|
664 pcf_driver_requester( FT_Module module, |
|
665 const char* name ) |
|
666 { |
|
667 FT_UNUSED( module ); |
|
668 |
|
669 return ft_service_list_lookup( pcf_services, name ); |
|
670 } |
|
671 |
|
672 |
|
673 FT_CALLBACK_TABLE_DEF |
|
674 const FT_Driver_ClassRec pcf_driver_class = |
|
675 { |
|
676 { |
|
677 FT_MODULE_FONT_DRIVER | |
|
678 FT_MODULE_DRIVER_NO_OUTLINES, |
|
679 sizeof ( FT_DriverRec ), |
|
680 |
|
681 "pcf", |
|
682 0x10000L, |
|
683 0x20000L, |
|
684 |
|
685 0, |
|
686 |
|
687 0, |
|
688 0, |
|
689 pcf_driver_requester |
|
690 }, |
|
691 |
|
692 sizeof ( PCF_FaceRec ), |
|
693 sizeof ( FT_SizeRec ), |
|
694 sizeof ( FT_GlyphSlotRec ), |
|
695 |
|
696 PCF_Face_Init, |
|
697 PCF_Face_Done, |
|
698 0, /* FT_Size_InitFunc */ |
|
699 0, /* FT_Size_DoneFunc */ |
|
700 0, /* FT_Slot_InitFunc */ |
|
701 0, /* FT_Slot_DoneFunc */ |
|
702 |
|
703 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS |
|
704 ft_stub_set_char_sizes, |
|
705 ft_stub_set_pixel_sizes, |
|
706 #endif |
|
707 PCF_Glyph_Load, |
|
708 |
|
709 0, /* FT_Face_GetKerningFunc */ |
|
710 0, /* FT_Face_AttachFunc */ |
|
711 0, /* FT_Face_GetAdvancesFunc */ |
|
712 |
|
713 PCF_Size_Request, |
|
714 PCF_Size_Select |
|
715 }; |
|
716 |
|
717 |
|
718 /* END */ |
|