]>
Commit | Line | Data |
---|---|---|
1 | /***************************************************************************/ | |
2 | /* */ | |
3 | /* winfnt.c */ | |
4 | /* */ | |
5 | /* FreeType font driver for Windows FNT/FON files */ | |
6 | /* */ | |
7 | /* Copyright 1996-2000 by */ | |
8 | /* David Turner, Robert Wilhelm, and Werner Lemberg. */ | |
9 | /* */ | |
10 | /* This file is part of the FreeType project, and may only be used, */ | |
11 | /* modified, and distributed under the terms of the FreeType project */ | |
12 | /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ | |
13 | /* this file you indicate that you have read the license and */ | |
14 | /* understand and accept it fully. */ | |
15 | /* */ | |
16 | /***************************************************************************/ | |
17 | ||
18 | ||
19 | #ifdef FT_FLAT_COMPILE | |
20 | ||
21 | #include "winfnt.h" | |
22 | ||
23 | #else | |
24 | ||
25 | #include <winfonts/winfnt.h> | |
26 | ||
27 | #endif | |
28 | ||
29 | ||
30 | #include <freetype/fterrors.h> | |
31 | #include <freetype/internal/ftstream.h> | |
32 | #include <freetype/internal/ftdebug.h> | |
33 | #include <freetype/internal/ftobjs.h> | |
34 | ||
35 | ||
36 | /*************************************************************************/ | |
37 | /* */ | |
38 | /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ | |
39 | /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ | |
40 | /* messages during execution. */ | |
41 | /* */ | |
42 | #undef FT_COMPONENT | |
43 | #define FT_COMPONENT trace_winfnt | |
44 | ||
45 | ||
46 | static | |
47 | const FT_Frame_Field winmz_header_fields[] = | |
48 | { | |
49 | FT_FRAME_START( 64 ), | |
50 | FT_FRAME_USHORT_LE ( WinMZ_Header, magic ), | |
51 | FT_FRAME_SKIP_BYTES( 29 * 2 ), | |
52 | FT_FRAME_ULONG_LE ( WinMZ_Header, lfanew ), | |
53 | FT_FRAME_END | |
54 | }; | |
55 | ||
56 | static | |
57 | const FT_Frame_Field winne_header_fields[] = | |
58 | { | |
59 | FT_FRAME_START( 40 ), | |
60 | FT_FRAME_USHORT_LE ( WinNE_Header, magic ), | |
61 | FT_FRAME_SKIP_BYTES( 34 ), | |
62 | FT_FRAME_USHORT_LE ( WinNE_Header, resource_tab_offset ), | |
63 | FT_FRAME_USHORT_LE ( WinNE_Header, rname_tab_offset ), | |
64 | FT_FRAME_END | |
65 | }; | |
66 | ||
67 | static | |
68 | const FT_Frame_Field winfnt_header_fields[] = | |
69 | { | |
70 | FT_FRAME_START( 134 ), | |
71 | FT_FRAME_USHORT_LE( WinFNT_Header, version ), | |
72 | FT_FRAME_ULONG_LE ( WinFNT_Header, file_size ), | |
73 | FT_FRAME_BYTES ( WinFNT_Header, copyright, 60 ), | |
74 | FT_FRAME_USHORT_LE( WinFNT_Header, file_type ), | |
75 | FT_FRAME_USHORT_LE( WinFNT_Header, nominal_point_size ), | |
76 | FT_FRAME_USHORT_LE( WinFNT_Header, vertical_resolution ), | |
77 | FT_FRAME_USHORT_LE( WinFNT_Header, horizontal_resolution ), | |
78 | FT_FRAME_USHORT_LE( WinFNT_Header, ascent ), | |
79 | FT_FRAME_USHORT_LE( WinFNT_Header, internal_leading ), | |
80 | FT_FRAME_USHORT_LE( WinFNT_Header, external_leading ), | |
81 | FT_FRAME_BYTE ( WinFNT_Header, italic ), | |
82 | FT_FRAME_BYTE ( WinFNT_Header, underline ), | |
83 | FT_FRAME_BYTE ( WinFNT_Header, strike_out ), | |
84 | FT_FRAME_USHORT_LE( WinFNT_Header, weight ), | |
85 | FT_FRAME_BYTE ( WinFNT_Header, charset ), | |
86 | FT_FRAME_USHORT_LE( WinFNT_Header, pixel_width ), | |
87 | FT_FRAME_USHORT_LE( WinFNT_Header, pixel_height ), | |
88 | FT_FRAME_BYTE ( WinFNT_Header, pitch_and_family ), | |
89 | FT_FRAME_USHORT_LE( WinFNT_Header, avg_width ), | |
90 | FT_FRAME_USHORT_LE( WinFNT_Header, max_width ), | |
91 | FT_FRAME_BYTE ( WinFNT_Header, first_char ), | |
92 | FT_FRAME_BYTE ( WinFNT_Header, last_char ), | |
93 | FT_FRAME_BYTE ( WinFNT_Header, default_char ), | |
94 | FT_FRAME_BYTE ( WinFNT_Header, break_char ), | |
95 | FT_FRAME_USHORT_LE( WinFNT_Header, bytes_per_row ), | |
96 | FT_FRAME_ULONG_LE ( WinFNT_Header, device_offset ), | |
97 | FT_FRAME_ULONG_LE ( WinFNT_Header, face_name_offset ), | |
98 | FT_FRAME_ULONG_LE ( WinFNT_Header, bits_pointer ), | |
99 | FT_FRAME_ULONG_LE ( WinFNT_Header, bits_offset ), | |
100 | FT_FRAME_BYTE ( WinFNT_Header, reserved ), | |
101 | FT_FRAME_ULONG_LE ( WinFNT_Header, flags ), | |
102 | FT_FRAME_USHORT_LE( WinFNT_Header, A_space ), | |
103 | FT_FRAME_USHORT_LE( WinFNT_Header, B_space ), | |
104 | FT_FRAME_USHORT_LE( WinFNT_Header, C_space ), | |
105 | FT_FRAME_USHORT_LE( WinFNT_Header, color_table_offset ), | |
106 | FT_FRAME_BYTES ( WinFNT_Header, reserved, 4 ), | |
107 | FT_FRAME_END | |
108 | }; | |
109 | ||
110 | ||
111 | static | |
112 | void fnt_done_font( FT_Stream stream, | |
113 | FNT_Font* font ) | |
114 | { | |
115 | if ( font->fnt_frame ) | |
116 | RELEASE_Frame( font->fnt_frame ); | |
117 | ||
118 | font->fnt_size = 0; | |
119 | font->fnt_frame = 0; | |
120 | } | |
121 | ||
122 | ||
123 | static | |
124 | FT_Error fnt_load_font( FT_Stream stream, | |
125 | FNT_Font* font ) | |
126 | { | |
127 | FT_Error error; | |
128 | WinFNT_Header* header = &font->header; | |
129 | ||
130 | ||
131 | /* first of all, read the FNT header */ | |
132 | if ( FILE_Seek( font->offset ) || | |
133 | READ_Fields( winfnt_header_fields, header ) ) | |
134 | goto Exit; | |
135 | ||
136 | /* check header */ | |
137 | if ( header->version != 0x200 && | |
138 | header->version != 0x300 ) | |
139 | { | |
140 | FT_TRACE2(( "[not a valid FNT file]\n" )); | |
141 | error = FT_Err_Unknown_File_Format; | |
142 | goto Exit; | |
143 | } | |
144 | ||
145 | if ( header->file_type & 1 ) | |
146 | { | |
147 | FT_TRACE2(( "can't handle vector FNT fonts\n" )); | |
148 | error = FT_Err_Unknown_File_Format; | |
149 | goto Exit; | |
150 | } | |
151 | ||
152 | /* small fixup -- some fonts have the `pixel_width' field set to 0 */ | |
153 | if ( header->pixel_width == 0 ) | |
154 | header->pixel_width = header->pixel_height; | |
155 | ||
156 | /* this is a FNT file/table, we now extract its frame */ | |
157 | if ( FILE_Seek( font->offset ) || | |
158 | EXTRACT_Frame( header->file_size, font->fnt_frame ) ) | |
159 | goto Exit; | |
160 | ||
161 | Exit: | |
162 | return error; | |
163 | } | |
164 | ||
165 | ||
166 | static | |
167 | void fnt_done_fonts( FNT_Face face ) | |
168 | { | |
169 | FT_Memory memory = FT_FACE(face)->memory; | |
170 | FT_Stream stream = FT_FACE(face)->stream; | |
171 | FNT_Font* cur = face->fonts; | |
172 | FNT_Font* limit = cur + face->num_fonts; | |
173 | ||
174 | ||
175 | for ( ; cur < limit; cur++ ) | |
176 | fnt_done_font( stream, cur ); | |
177 | ||
178 | FREE( face->fonts ); | |
179 | face->num_fonts = 0; | |
180 | } | |
181 | ||
182 | static | |
183 | FT_Error fnt_get_dll_fonts( FNT_Face face ) | |
184 | { | |
185 | FT_Error error; | |
186 | FT_Stream stream = FT_FACE(face)->stream; | |
187 | FT_Memory memory = FT_FACE(face)->memory; | |
188 | WinMZ_Header mz_header; | |
189 | ||
190 | ||
191 | face->fonts = 0; | |
192 | face->num_fonts = 0; | |
193 | ||
194 | /* does it begin with a MZ header? */ | |
195 | if ( FILE_Seek( 0 ) || | |
196 | READ_Fields( winmz_header_fields, &mz_header ) ) | |
197 | goto Exit; | |
198 | ||
199 | error = FT_Err_Unknown_File_Format; | |
200 | if ( mz_header.magic == WINFNT_MZ_MAGIC ) | |
201 | { | |
202 | /* yes, now look for a NE header in the file */ | |
203 | WinNE_Header ne_header; | |
204 | ||
205 | ||
206 | if ( FILE_Seek( mz_header.lfanew ) || | |
207 | READ_Fields( winne_header_fields, &ne_header ) ) | |
208 | goto Exit; | |
209 | ||
210 | error = FT_Err_Unknown_File_Format; | |
211 | if ( ne_header.magic == WINFNT_NE_MAGIC ) | |
212 | { | |
213 | /* good, now look in the resource table for each FNT resource */ | |
214 | FT_ULong res_offset = mz_header.lfanew + | |
215 | ne_header.resource_tab_offset; | |
216 | ||
217 | FT_UShort size_shift; | |
218 | FT_UShort font_count = 0; | |
219 | FT_ULong font_offset = 0; | |
220 | ||
221 | ||
222 | if ( FILE_Seek( res_offset ) || | |
223 | ACCESS_Frame( ne_header.rname_tab_offset - | |
224 | ne_header.resource_tab_offset ) ) | |
225 | goto Exit; | |
226 | ||
227 | size_shift = GET_UShortLE(); | |
228 | ||
229 | for (;;) | |
230 | { | |
231 | FT_UShort type_id, count; | |
232 | ||
233 | ||
234 | type_id = GET_UShortLE(); | |
235 | if ( !type_id ) | |
236 | break; | |
237 | ||
238 | count = GET_UShortLE(); | |
239 | ||
240 | if ( type_id == 0x8008 ) | |
241 | { | |
242 | font_count = count; | |
243 | font_offset = FILE_Pos() + 4 + ( stream->cursor - stream->limit ); | |
244 | break; | |
245 | } | |
246 | ||
247 | stream->cursor += 4 + count * 12; | |
248 | } | |
249 | FORGET_Frame(); | |
250 | ||
251 | if ( !font_count || !font_offset ) | |
252 | { | |
253 | FT_TRACE2(( "this file doesn't contain any FNT resources!\n" )); | |
254 | error = FT_Err_Unknown_File_Format; | |
255 | goto Exit; | |
256 | } | |
257 | ||
258 | if ( FILE_Seek( font_offset ) || | |
259 | ALLOC_ARRAY( face->fonts, font_count, FNT_Font ) ) | |
260 | goto Exit; | |
261 | ||
262 | face->num_fonts = font_count; | |
263 | ||
264 | if ( ACCESS_Frame( (FT_Long)font_count * 12 ) ) | |
265 | goto Exit; | |
266 | ||
267 | /* now read the offset and position of each FNT font */ | |
268 | { | |
269 | FNT_Font* cur = face->fonts; | |
270 | FNT_Font* limit = cur + font_count; | |
271 | ||
272 | ||
273 | for ( ; cur < limit; cur++ ) | |
274 | { | |
275 | cur->offset = (FT_ULong)GET_UShortLE() << size_shift; | |
276 | cur->fnt_size = (FT_ULong)GET_UShortLE() << size_shift; | |
277 | cur->size_shift = size_shift; | |
278 | stream->cursor += 8; | |
279 | } | |
280 | } | |
281 | FORGET_Frame(); | |
282 | ||
283 | /* finally, try to load each font there */ | |
284 | { | |
285 | FNT_Font* cur = face->fonts; | |
286 | FNT_Font* limit = cur + font_count; | |
287 | ||
288 | ||
289 | for ( ; cur < limit; cur++ ) | |
290 | { | |
291 | error = fnt_load_font( stream, cur ); | |
292 | if ( error ) | |
293 | goto Fail; | |
294 | } | |
295 | } | |
296 | } | |
297 | } | |
298 | ||
299 | Fail: | |
300 | if ( error ) | |
301 | fnt_done_fonts( face ); | |
302 | ||
303 | Exit: | |
304 | return error; | |
305 | } | |
306 | ||
307 | ||
308 | static | |
309 | void FNT_Done_Face( FNT_Face face ) | |
310 | { | |
311 | FT_Memory memory = FT_FACE_MEMORY( face ); | |
312 | ||
313 | ||
314 | fnt_done_fonts( face ); | |
315 | ||
316 | FREE( face->root.available_sizes ); | |
317 | face->root.num_fixed_sizes = 0; | |
318 | } | |
319 | ||
320 | ||
321 | static | |
322 | FT_Error FNT_Init_Face( FT_Stream stream, | |
323 | FNT_Face face, | |
324 | FT_Int face_index, | |
325 | FT_Int num_params, | |
326 | FT_Parameter* params ) | |
327 | { | |
328 | FT_Error error; | |
329 | FT_Memory memory = FT_FACE_MEMORY( face ); | |
330 | ||
331 | FT_UNUSED( num_params ); | |
332 | FT_UNUSED( params ); | |
333 | FT_UNUSED( face_index ); | |
334 | ||
335 | ||
336 | /* try to load several fonts from a DLL */ | |
337 | error = fnt_get_dll_fonts( face ); | |
338 | if ( error ) | |
339 | { | |
340 | /* this didn't work, now try to load a single FNT font */ | |
341 | FT_Memory memory = FT_FACE_MEMORY( face ); | |
342 | FNT_Font* font; | |
343 | ||
344 | if ( ALLOC( face->fonts, sizeof ( *face->fonts ) ) ) | |
345 | goto Exit; | |
346 | ||
347 | face->num_fonts = 1; | |
348 | font = face->fonts; | |
349 | ||
350 | font->offset = 0; | |
351 | font->fnt_size = stream->size; | |
352 | ||
353 | error = fnt_load_font( stream, font ); | |
354 | if ( error ) | |
355 | goto Fail; | |
356 | } | |
357 | ||
358 | /* all right, one or more fonts were loaded; we now need to */ | |
359 | /* fill the root FT_Face fields with relevant information */ | |
360 | { | |
361 | FT_Face root = FT_FACE( face ); | |
362 | FNT_Font* fonts = face->fonts; | |
363 | FNT_Font* limit = fonts + face->num_fonts; | |
364 | FNT_Font* cur; | |
365 | ||
366 | ||
367 | root->num_faces = 1; | |
368 | root->face_flags = FT_FACE_FLAG_FIXED_SIZES | | |
369 | FT_FACE_FLAG_HORIZONTAL; | |
370 | ||
371 | if ( fonts->header.avg_width == fonts->header.max_width ) | |
372 | root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; | |
373 | ||
374 | if ( fonts->header.italic ) | |
375 | root->style_flags |= FT_STYLE_FLAG_ITALIC; | |
376 | ||
377 | if ( fonts->header.weight >= 800 ) | |
378 | root->style_flags |= FT_STYLE_FLAG_BOLD; | |
379 | ||
380 | /* Setup the `fixed_sizes' array */ | |
381 | if ( ALLOC_ARRAY( root->available_sizes, face->num_fonts, | |
382 | FT_Bitmap_Size ) ) | |
383 | goto Fail; | |
384 | ||
385 | root->num_fixed_sizes = face->num_fonts; | |
386 | ||
387 | { | |
388 | FT_Bitmap_Size* size = root->available_sizes; | |
389 | ||
390 | ||
391 | for ( cur = fonts; cur < limit; cur++, size++ ) | |
392 | { | |
393 | size->width = cur->header.pixel_width; | |
394 | size->height = cur->header.pixel_height; | |
395 | } | |
396 | } | |
397 | ||
398 | /* Setup the `charmaps' array */ | |
399 | root->charmaps = &face->charmap_handle; | |
400 | root->num_charmaps = 1; | |
401 | ||
402 | face->charmap.encoding = ft_encoding_unicode; | |
403 | face->charmap.platform_id = 3; | |
404 | face->charmap.encoding_id = 1; | |
405 | face->charmap.face = root; | |
406 | ||
407 | face->charmap_handle = &face->charmap; | |
408 | ||
409 | root->charmap = face->charmap_handle; | |
410 | ||
411 | /* setup remaining flags */ | |
412 | root->num_glyphs = fonts->header.last_char - | |
413 | fonts->header.first_char + 1; | |
414 | ||
415 | root->family_name = (FT_String*)fonts->fnt_frame + | |
416 | fonts->header.face_name_offset; | |
417 | root->style_name = "Regular"; | |
418 | ||
419 | if ( root->style_flags & FT_STYLE_FLAG_BOLD ) | |
420 | { | |
421 | if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) | |
422 | root->style_name = "Bold Italic"; | |
423 | else | |
424 | root->style_name = "Bold"; | |
425 | } | |
426 | else if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) | |
427 | root->style_name = "Italic"; | |
428 | } | |
429 | ||
430 | Fail: | |
431 | if ( error ) | |
432 | FNT_Done_Face( face ); | |
433 | ||
434 | Exit: | |
435 | return error; | |
436 | } | |
437 | ||
438 | ||
439 | static | |
440 | FT_Error FNT_Set_Pixel_Size( FNT_Size size ) | |
441 | { | |
442 | /* look up a font corresponding to the current pixel size */ | |
443 | FNT_Face face = (FNT_Face)FT_SIZE_FACE( size ); | |
444 | FNT_Font* cur = face->fonts; | |
445 | FNT_Font* limit = cur + face->num_fonts; | |
446 | ||
447 | ||
448 | size->font = 0; | |
449 | for ( ; cur < limit; cur++ ) | |
450 | { | |
451 | /* we only compare the character height, as fonts used some strange */ | |
452 | /* values */ | |
453 | if ( cur->header.pixel_height == size->root.metrics.y_ppem ) | |
454 | { | |
455 | size->font = cur; | |
456 | ||
457 | size->root.metrics.ascender = cur->header.ascent * 64; | |
458 | size->root.metrics.descender = ( cur->header.pixel_height - | |
459 | cur->header.ascent ) * 64; | |
460 | size->root.metrics.height = cur->header.pixel_height * 64; | |
461 | break; | |
462 | } | |
463 | } | |
464 | ||
465 | return ( size->font ? FT_Err_Ok : FT_Err_Invalid_Argument ); | |
466 | } | |
467 | ||
468 | ||
469 | static | |
470 | FT_UInt FNT_Get_Char_Index( FT_CharMap charmap, | |
471 | FT_ULong char_code ) | |
472 | { | |
473 | FT_UInt result = char_code; | |
474 | ||
475 | ||
476 | if ( charmap ) | |
477 | { | |
478 | FNT_Font* font = ((FNT_Face)charmap->face)->fonts; | |
479 | FT_UInt first = font->header.first_char; | |
480 | FT_UInt count = font->header.last_char - first + 1; | |
481 | ||
482 | ||
483 | char_code -= first; | |
484 | if ( char_code < count ) | |
485 | result = char_code + 1; | |
486 | else | |
487 | result = 0; | |
488 | } | |
489 | ||
490 | return result; | |
491 | } | |
492 | ||
493 | ||
494 | static | |
495 | FT_Error FNT_Load_Glyph( FT_GlyphSlot slot, | |
496 | FNT_Size size, | |
497 | FT_UInt glyph_index, | |
498 | FT_Int load_flags ) | |
499 | { | |
500 | FNT_Font* font = size->font; | |
501 | FT_Error error = 0; | |
502 | FT_Byte* p; | |
503 | FT_Int len; | |
504 | FT_Bitmap* bitmap = &slot->bitmap; | |
505 | FT_ULong offset; | |
506 | FT_Bool new_format; | |
507 | ||
508 | FT_UNUSED( slot ); | |
509 | FT_UNUSED( load_flags ); | |
510 | ||
511 | ||
512 | if ( !font ) | |
513 | { | |
514 | error = FT_Err_Invalid_Argument; | |
515 | goto Exit; | |
516 | } | |
517 | ||
518 | if ( glyph_index > 0 ) | |
519 | glyph_index--; | |
520 | else | |
521 | glyph_index = font->header.default_char - font->header.first_char; | |
522 | ||
523 | new_format = font->header.version == 0x300; | |
524 | len = new_format ? 6 : 4; | |
525 | ||
526 | /* jump to glyph entry */ | |
527 | p = font->fnt_frame + 118 + len * glyph_index; | |
528 | ||
529 | bitmap->width = NEXT_ShortLE(p); | |
530 | ||
531 | if ( new_format ) | |
532 | offset = NEXT_ULongLE(p); | |
533 | else | |
534 | offset = NEXT_UShortLE(p); | |
535 | ||
536 | /* jump to glyph data */ | |
537 | p = font->fnt_frame + /* font->header.bits_offset */ + offset; | |
538 | ||
539 | /* allocate and build bitmap */ | |
540 | { | |
541 | FT_Memory memory = FT_FACE_MEMORY( slot->face ); | |
542 | FT_Int pitch = ( bitmap->width + 7 ) >> 3; | |
543 | FT_Byte* column; | |
544 | FT_Byte* write; | |
545 | ||
546 | ||
547 | bitmap->pitch = pitch; | |
548 | bitmap->rows = font->header.pixel_height; | |
549 | bitmap->pixel_mode = ft_pixel_mode_mono; | |
550 | ||
551 | if ( ALLOC( bitmap->buffer, pitch * bitmap->rows ) ) | |
552 | goto Exit; | |
553 | ||
554 | column = (FT_Byte*)bitmap->buffer; | |
555 | ||
556 | for ( ; pitch > 0; pitch--, column++ ) | |
557 | { | |
558 | FT_Byte* limit = p + bitmap->rows; | |
559 | ||
560 | ||
561 | for ( write = column; p < limit; p++, write += bitmap->pitch ) | |
562 | write[0] = p[0]; | |
563 | } | |
564 | } | |
565 | ||
566 | slot->flags = ft_glyph_own_bitmap; | |
567 | slot->bitmap_left = 0; | |
568 | slot->bitmap_top = font->header.ascent; | |
569 | slot->format = ft_glyph_format_bitmap; | |
570 | ||
571 | /* now set up metrics */ | |
572 | slot->metrics.horiAdvance = bitmap->width << 6; | |
573 | slot->metrics.horiBearingX = 0; | |
574 | slot->metrics.horiBearingY = slot->bitmap_top << 6; | |
575 | ||
576 | slot->linearHoriAdvance = (FT_Fixed)bitmap->width << 16; | |
577 | ||
578 | Exit: | |
579 | return error; | |
580 | } | |
581 | ||
582 | ||
583 | const FT_Driver_Class winfnt_driver_class = | |
584 | { | |
585 | { | |
586 | ft_module_font_driver, | |
587 | sizeof ( FT_DriverRec ), | |
588 | ||
589 | "winfonts", | |
590 | 0x10000L, | |
591 | 0x20000L, | |
592 | ||
593 | 0, | |
594 | ||
595 | (FT_Module_Constructor)0, | |
596 | (FT_Module_Destructor) 0, | |
597 | (FT_Module_Requester) 0 | |
598 | }, | |
599 | ||
600 | sizeof( FNT_FaceRec ), | |
601 | sizeof( FNT_SizeRec ), | |
602 | sizeof( FT_GlyphSlotRec ), | |
603 | ||
604 | (FTDriver_initFace) FNT_Init_Face, | |
605 | (FTDriver_doneFace) FNT_Done_Face, | |
606 | (FTDriver_initSize) 0, | |
607 | (FTDriver_doneSize) 0, | |
608 | (FTDriver_initGlyphSlot)0, | |
609 | (FTDriver_doneGlyphSlot)0, | |
610 | ||
611 | (FTDriver_setCharSizes) FNT_Set_Pixel_Size, | |
612 | (FTDriver_setPixelSizes)FNT_Set_Pixel_Size, | |
613 | ||
614 | (FTDriver_loadGlyph) FNT_Load_Glyph, | |
615 | (FTDriver_getCharIndex) FNT_Get_Char_Index, | |
616 | ||
617 | (FTDriver_getKerning) 0, | |
618 | (FTDriver_attachFile) 0, | |
619 | (FTDriver_getAdvances) 0 | |
620 | }; | |
621 | ||
622 | ||
623 | /* END */ |