1 | /**************************************************************************** |
2 | * |
3 | * ttdriver.c |
4 | * |
5 | * TrueType font driver implementation (body). |
6 | * |
7 | * Copyright (C) 1996-2019 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 | #include <ft2build.h> |
20 | #include FT_INTERNAL_DEBUG_H |
21 | #include FT_INTERNAL_STREAM_H |
22 | #include FT_INTERNAL_SFNT_H |
23 | #include FT_SERVICE_FONT_FORMAT_H |
24 | |
25 | #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
26 | #include FT_MULTIPLE_MASTERS_H |
27 | #include FT_SERVICE_MULTIPLE_MASTERS_H |
28 | #include FT_SERVICE_METRICS_VARIATIONS_H |
29 | #endif |
30 | |
31 | #include FT_SERVICE_TRUETYPE_ENGINE_H |
32 | #include FT_SERVICE_TRUETYPE_GLYF_H |
33 | #include FT_SERVICE_PROPERTIES_H |
34 | #include FT_DRIVER_H |
35 | |
36 | #include "ttdriver.h" |
37 | #include "ttgload.h" |
38 | #include "ttpload.h" |
39 | |
40 | #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
41 | #include "ttgxvar.h" |
42 | #endif |
43 | |
44 | #include "tterrors.h" |
45 | |
46 | |
47 | /************************************************************************** |
48 | * |
49 | * The macro FT_COMPONENT is used in trace mode. It is an implicit |
50 | * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log |
51 | * messages during execution. |
52 | */ |
53 | #undef FT_COMPONENT |
54 | #define FT_COMPONENT ttdriver |
55 | |
56 | |
57 | /* |
58 | * PROPERTY SERVICE |
59 | * |
60 | */ |
61 | static FT_Error |
62 | tt_property_set( FT_Module module, /* TT_Driver */ |
63 | const char* property_name, |
64 | const void* value, |
65 | FT_Bool value_is_string ) |
66 | { |
67 | FT_Error error = FT_Err_Ok; |
68 | TT_Driver driver = (TT_Driver)module; |
69 | |
70 | #ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES |
71 | FT_UNUSED( value_is_string ); |
72 | #endif |
73 | |
74 | |
75 | if ( !ft_strcmp( property_name, "interpreter-version" ) ) |
76 | { |
77 | FT_UInt interpreter_version; |
78 | |
79 | |
80 | #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES |
81 | if ( value_is_string ) |
82 | { |
83 | const char* s = (const char*)value; |
84 | |
85 | |
86 | interpreter_version = (FT_UInt)ft_strtol( s, NULL, 10 ); |
87 | } |
88 | else |
89 | #endif |
90 | { |
91 | FT_UInt* iv = (FT_UInt*)value; |
92 | |
93 | |
94 | interpreter_version = *iv; |
95 | } |
96 | |
97 | if ( interpreter_version == TT_INTERPRETER_VERSION_35 |
98 | #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY |
99 | || interpreter_version == TT_INTERPRETER_VERSION_38 |
100 | #endif |
101 | #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL |
102 | || interpreter_version == TT_INTERPRETER_VERSION_40 |
103 | #endif |
104 | ) |
105 | driver->interpreter_version = interpreter_version; |
106 | else |
107 | error = FT_ERR( Unimplemented_Feature ); |
108 | |
109 | return error; |
110 | } |
111 | |
112 | FT_TRACE0(( "tt_property_set: missing property `%s'\n" , |
113 | property_name )); |
114 | return FT_THROW( Missing_Property ); |
115 | } |
116 | |
117 | |
118 | static FT_Error |
119 | tt_property_get( FT_Module module, /* TT_Driver */ |
120 | const char* property_name, |
121 | const void* value ) |
122 | { |
123 | FT_Error error = FT_Err_Ok; |
124 | TT_Driver driver = (TT_Driver)module; |
125 | |
126 | FT_UInt interpreter_version = driver->interpreter_version; |
127 | |
128 | |
129 | if ( !ft_strcmp( property_name, "interpreter-version" ) ) |
130 | { |
131 | FT_UInt* val = (FT_UInt*)value; |
132 | |
133 | |
134 | *val = interpreter_version; |
135 | |
136 | return error; |
137 | } |
138 | |
139 | FT_TRACE0(( "tt_property_get: missing property `%s'\n" , |
140 | property_name )); |
141 | return FT_THROW( Missing_Property ); |
142 | } |
143 | |
144 | |
145 | FT_DEFINE_SERVICE_PROPERTIESREC( |
146 | tt_service_properties, |
147 | |
148 | (FT_Properties_SetFunc)tt_property_set, /* set_property */ |
149 | (FT_Properties_GetFunc)tt_property_get /* get_property */ |
150 | ) |
151 | |
152 | |
153 | /*************************************************************************/ |
154 | /*************************************************************************/ |
155 | /*************************************************************************/ |
156 | /**** ****/ |
157 | /**** ****/ |
158 | /**** F A C E S ****/ |
159 | /**** ****/ |
160 | /**** ****/ |
161 | /*************************************************************************/ |
162 | /*************************************************************************/ |
163 | /*************************************************************************/ |
164 | |
165 | |
166 | /************************************************************************** |
167 | * |
168 | * @Function: |
169 | * tt_get_kerning |
170 | * |
171 | * @Description: |
172 | * A driver method used to return the kerning vector between two |
173 | * glyphs of the same face. |
174 | * |
175 | * @Input: |
176 | * face :: |
177 | * A handle to the source face object. |
178 | * |
179 | * left_glyph :: |
180 | * The index of the left glyph in the kern pair. |
181 | * |
182 | * right_glyph :: |
183 | * The index of the right glyph in the kern pair. |
184 | * |
185 | * @Output: |
186 | * kerning :: |
187 | * The kerning vector. This is in font units for |
188 | * scalable formats, and in pixels for fixed-sizes |
189 | * formats. |
190 | * |
191 | * @Return: |
192 | * FreeType error code. 0 means success. |
193 | * |
194 | * @Note: |
195 | * Only horizontal layouts (left-to-right & right-to-left) are |
196 | * supported by this function. Other layouts, or more sophisticated |
197 | * kernings, are out of scope of this method (the basic driver |
198 | * interface is meant to be simple). |
199 | * |
200 | * They can be implemented by format-specific interfaces. |
201 | */ |
202 | static FT_Error |
203 | tt_get_kerning( FT_Face ttface, /* TT_Face */ |
204 | FT_UInt left_glyph, |
205 | FT_UInt right_glyph, |
206 | FT_Vector* kerning ) |
207 | { |
208 | TT_Face face = (TT_Face)ttface; |
209 | SFNT_Service sfnt = (SFNT_Service)face->sfnt; |
210 | |
211 | |
212 | kerning->x = 0; |
213 | kerning->y = 0; |
214 | |
215 | if ( sfnt ) |
216 | kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph ); |
217 | |
218 | return 0; |
219 | } |
220 | |
221 | |
222 | static FT_Error |
223 | tt_get_advances( FT_Face ttface, |
224 | FT_UInt start, |
225 | FT_UInt count, |
226 | FT_Int32 flags, |
227 | FT_Fixed *advances ) |
228 | { |
229 | FT_UInt nn; |
230 | TT_Face face = (TT_Face)ttface; |
231 | |
232 | |
233 | /* XXX: TODO: check for sbits */ |
234 | |
235 | if ( flags & FT_LOAD_VERTICAL_LAYOUT ) |
236 | { |
237 | #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
238 | /* no fast retrieval for blended MM fonts without VVAR table */ |
239 | if ( ( FT_IS_NAMED_INSTANCE( ttface ) || FT_IS_VARIATION( ttface ) ) && |
240 | !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) |
241 | return FT_THROW( Unimplemented_Feature ); |
242 | #endif |
243 | |
244 | for ( nn = 0; nn < count; nn++ ) |
245 | { |
246 | FT_Short tsb; |
247 | FT_UShort ah; |
248 | |
249 | |
250 | /* since we don't need `tsb', we use zero for `yMax' parameter */ |
251 | TT_Get_VMetrics( face, start + nn, 0, &tsb, &ah ); |
252 | advances[nn] = ah; |
253 | } |
254 | } |
255 | else |
256 | { |
257 | #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
258 | /* no fast retrieval for blended MM fonts without HVAR table */ |
259 | if ( ( FT_IS_NAMED_INSTANCE( ttface ) || FT_IS_VARIATION( ttface ) ) && |
260 | !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) |
261 | return FT_THROW( Unimplemented_Feature ); |
262 | #endif |
263 | |
264 | for ( nn = 0; nn < count; nn++ ) |
265 | { |
266 | FT_Short lsb; |
267 | FT_UShort aw; |
268 | |
269 | |
270 | TT_Get_HMetrics( face, start + nn, &lsb, &aw ); |
271 | advances[nn] = aw; |
272 | } |
273 | } |
274 | |
275 | return FT_Err_Ok; |
276 | } |
277 | |
278 | |
279 | /*************************************************************************/ |
280 | /*************************************************************************/ |
281 | /*************************************************************************/ |
282 | /**** ****/ |
283 | /**** ****/ |
284 | /**** S I Z E S ****/ |
285 | /**** ****/ |
286 | /**** ****/ |
287 | /*************************************************************************/ |
288 | /*************************************************************************/ |
289 | /*************************************************************************/ |
290 | |
291 | |
292 | #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS |
293 | |
294 | static FT_Error |
295 | tt_size_select( FT_Size size, |
296 | FT_ULong strike_index ) |
297 | { |
298 | TT_Face ttface = (TT_Face)size->face; |
299 | TT_Size ttsize = (TT_Size)size; |
300 | FT_Error error = FT_Err_Ok; |
301 | |
302 | |
303 | ttsize->strike_index = strike_index; |
304 | |
305 | if ( FT_IS_SCALABLE( size->face ) ) |
306 | { |
307 | /* use the scaled metrics, even when tt_size_reset fails */ |
308 | FT_Select_Metrics( size->face, strike_index ); |
309 | |
310 | tt_size_reset( ttsize, 0 ); /* ignore return value */ |
311 | } |
312 | else |
313 | { |
314 | SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; |
315 | FT_Size_Metrics* size_metrics = &size->metrics; |
316 | |
317 | |
318 | error = sfnt->load_strike_metrics( ttface, |
319 | strike_index, |
320 | size_metrics ); |
321 | if ( error ) |
322 | ttsize->strike_index = 0xFFFFFFFFUL; |
323 | } |
324 | |
325 | return error; |
326 | } |
327 | |
328 | #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ |
329 | |
330 | |
331 | static FT_Error |
332 | tt_size_request( FT_Size size, |
333 | FT_Size_Request req ) |
334 | { |
335 | TT_Size ttsize = (TT_Size)size; |
336 | FT_Error error = FT_Err_Ok; |
337 | |
338 | |
339 | #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS |
340 | |
341 | if ( FT_HAS_FIXED_SIZES( size->face ) ) |
342 | { |
343 | TT_Face ttface = (TT_Face)size->face; |
344 | SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; |
345 | FT_ULong strike_index; |
346 | |
347 | |
348 | error = sfnt->set_sbit_strike( ttface, req, &strike_index ); |
349 | |
350 | if ( error ) |
351 | ttsize->strike_index = 0xFFFFFFFFUL; |
352 | else |
353 | return tt_size_select( size, strike_index ); |
354 | } |
355 | |
356 | #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ |
357 | |
358 | FT_Request_Metrics( size->face, req ); |
359 | |
360 | if ( FT_IS_SCALABLE( size->face ) ) |
361 | { |
362 | error = tt_size_reset( ttsize, 0 ); |
363 | |
364 | #ifdef TT_USE_BYTECODE_INTERPRETER |
365 | /* for the `MPS' bytecode instruction we need the point size */ |
366 | if ( !error ) |
367 | { |
368 | FT_UInt resolution = |
369 | ttsize->metrics->x_ppem > ttsize->metrics->y_ppem |
370 | ? req->horiResolution |
371 | : req->vertResolution; |
372 | |
373 | |
374 | /* if we don't have a resolution value, assume 72dpi */ |
375 | if ( req->type == FT_SIZE_REQUEST_TYPE_SCALES || |
376 | !resolution ) |
377 | resolution = 72; |
378 | |
379 | ttsize->point_size = FT_MulDiv( ttsize->ttmetrics.ppem, |
380 | 64 * 72, |
381 | resolution ); |
382 | } |
383 | #endif |
384 | } |
385 | |
386 | return error; |
387 | } |
388 | |
389 | |
390 | /************************************************************************** |
391 | * |
392 | * @Function: |
393 | * tt_glyph_load |
394 | * |
395 | * @Description: |
396 | * A driver method used to load a glyph within a given glyph slot. |
397 | * |
398 | * @Input: |
399 | * slot :: |
400 | * A handle to the target slot object where the glyph |
401 | * will be loaded. |
402 | * |
403 | * size :: |
404 | * A handle to the source face size at which the glyph |
405 | * must be scaled, loaded, etc. |
406 | * |
407 | * glyph_index :: |
408 | * The index of the glyph in the font file. |
409 | * |
410 | * load_flags :: |
411 | * A flag indicating what to load for this glyph. The |
412 | * FT_LOAD_XXX constants can be used to control the |
413 | * glyph loading process (e.g., whether the outline |
414 | * should be scaled, whether to load bitmaps or not, |
415 | * whether to hint the outline, etc). |
416 | * |
417 | * @Return: |
418 | * FreeType error code. 0 means success. |
419 | */ |
420 | static FT_Error |
421 | tt_glyph_load( FT_GlyphSlot ttslot, /* TT_GlyphSlot */ |
422 | FT_Size ttsize, /* TT_Size */ |
423 | FT_UInt glyph_index, |
424 | FT_Int32 load_flags ) |
425 | { |
426 | TT_GlyphSlot slot = (TT_GlyphSlot)ttslot; |
427 | TT_Size size = (TT_Size)ttsize; |
428 | FT_Face face = ttslot->face; |
429 | FT_Error error; |
430 | |
431 | |
432 | if ( !slot ) |
433 | return FT_THROW( Invalid_Slot_Handle ); |
434 | |
435 | if ( !size ) |
436 | return FT_THROW( Invalid_Size_Handle ); |
437 | |
438 | if ( !face ) |
439 | return FT_THROW( Invalid_Face_Handle ); |
440 | |
441 | #ifdef FT_CONFIG_OPTION_INCREMENTAL |
442 | if ( glyph_index >= (FT_UInt)face->num_glyphs && |
443 | !face->internal->incremental_interface ) |
444 | #else |
445 | if ( glyph_index >= (FT_UInt)face->num_glyphs ) |
446 | #endif |
447 | return FT_THROW( Invalid_Argument ); |
448 | |
449 | if ( load_flags & FT_LOAD_NO_HINTING ) |
450 | { |
451 | /* both FT_LOAD_NO_HINTING and FT_LOAD_NO_AUTOHINT */ |
452 | /* are necessary to disable hinting for tricky fonts */ |
453 | |
454 | if ( FT_IS_TRICKY( face ) ) |
455 | load_flags &= ~FT_LOAD_NO_HINTING; |
456 | |
457 | if ( load_flags & FT_LOAD_NO_AUTOHINT ) |
458 | load_flags |= FT_LOAD_NO_HINTING; |
459 | } |
460 | |
461 | if ( load_flags & ( FT_LOAD_NO_RECURSE | FT_LOAD_NO_SCALE ) ) |
462 | { |
463 | load_flags |= FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE; |
464 | |
465 | if ( !FT_IS_TRICKY( face ) ) |
466 | load_flags |= FT_LOAD_NO_HINTING; |
467 | } |
468 | |
469 | /* use hinted metrics only if we load a glyph with hinting */ |
470 | size->metrics = ( load_flags & FT_LOAD_NO_HINTING ) |
471 | ? &ttsize->metrics |
472 | : &size->hinted_metrics; |
473 | |
474 | /* now fill in the glyph slot with outline/bitmap/layered */ |
475 | error = TT_Load_Glyph( size, slot, glyph_index, load_flags ); |
476 | |
477 | /* force drop-out mode to 2 - irrelevant now */ |
478 | /* slot->outline.dropout_mode = 2; */ |
479 | |
480 | return error; |
481 | } |
482 | |
483 | |
484 | /*************************************************************************/ |
485 | /*************************************************************************/ |
486 | /*************************************************************************/ |
487 | /**** ****/ |
488 | /**** ****/ |
489 | /**** D R I V E R I N T E R F A C E ****/ |
490 | /**** ****/ |
491 | /**** ****/ |
492 | /*************************************************************************/ |
493 | /*************************************************************************/ |
494 | /*************************************************************************/ |
495 | |
496 | #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
497 | |
498 | FT_DEFINE_SERVICE_MULTIMASTERSREC( |
499 | tt_service_gx_multi_masters, |
500 | |
501 | (FT_Get_MM_Func) NULL, /* get_mm */ |
502 | (FT_Set_MM_Design_Func) NULL, /* set_mm_design */ |
503 | (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, /* set_mm_blend */ |
504 | (FT_Get_MM_Blend_Func) TT_Get_MM_Blend, /* get_mm_blend */ |
505 | (FT_Get_MM_Var_Func) TT_Get_MM_Var, /* get_mm_var */ |
506 | (FT_Set_Var_Design_Func) TT_Set_Var_Design, /* set_var_design */ |
507 | (FT_Get_Var_Design_Func) TT_Get_Var_Design, /* get_var_design */ |
508 | (FT_Set_Instance_Func) TT_Set_Named_Instance, /* set_instance */ |
509 | (FT_Set_MM_WeightVector_Func)NULL, /* set_mm_weightvector */ |
510 | (FT_Get_MM_WeightVector_Func)NULL, /* get_mm_weightvector */ |
511 | |
512 | (FT_Get_Var_Blend_Func) tt_get_var_blend, /* get_var_blend */ |
513 | (FT_Done_Blend_Func) tt_done_blend /* done_blend */ |
514 | ) |
515 | |
516 | FT_DEFINE_SERVICE_METRICSVARIATIONSREC( |
517 | tt_service_metrics_variations, |
518 | |
519 | (FT_HAdvance_Adjust_Func)tt_hadvance_adjust, /* hadvance_adjust */ |
520 | (FT_LSB_Adjust_Func) NULL, /* lsb_adjust */ |
521 | (FT_RSB_Adjust_Func) NULL, /* rsb_adjust */ |
522 | |
523 | (FT_VAdvance_Adjust_Func)tt_vadvance_adjust, /* vadvance_adjust */ |
524 | (FT_TSB_Adjust_Func) NULL, /* tsb_adjust */ |
525 | (FT_BSB_Adjust_Func) NULL, /* bsb_adjust */ |
526 | (FT_VOrg_Adjust_Func) NULL, /* vorg_adjust */ |
527 | |
528 | (FT_Metrics_Adjust_Func) tt_apply_mvar /* metrics_adjust */ |
529 | ) |
530 | |
531 | #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ |
532 | |
533 | |
534 | static const FT_Service_TrueTypeEngineRec tt_service_truetype_engine = |
535 | { |
536 | #ifdef TT_USE_BYTECODE_INTERPRETER |
537 | |
538 | FT_TRUETYPE_ENGINE_TYPE_PATENTED |
539 | |
540 | #else /* !TT_USE_BYTECODE_INTERPRETER */ |
541 | |
542 | FT_TRUETYPE_ENGINE_TYPE_NONE |
543 | |
544 | #endif /* TT_USE_BYTECODE_INTERPRETER */ |
545 | }; |
546 | |
547 | |
548 | FT_DEFINE_SERVICE_TTGLYFREC( |
549 | tt_service_truetype_glyf, |
550 | |
551 | (TT_Glyf_GetLocationFunc)tt_face_get_location /* get_location */ |
552 | ) |
553 | |
554 | |
555 | #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
556 | FT_DEFINE_SERVICEDESCREC6( |
557 | tt_services, |
558 | |
559 | FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE, |
560 | FT_SERVICE_ID_MULTI_MASTERS, &tt_service_gx_multi_masters, |
561 | FT_SERVICE_ID_METRICS_VARIATIONS, &tt_service_metrics_variations, |
562 | FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, |
563 | FT_SERVICE_ID_TT_GLYF, &tt_service_truetype_glyf, |
564 | FT_SERVICE_ID_PROPERTIES, &tt_service_properties ) |
565 | #else |
566 | FT_DEFINE_SERVICEDESCREC4( |
567 | tt_services, |
568 | |
569 | FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE, |
570 | FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, |
571 | FT_SERVICE_ID_TT_GLYF, &tt_service_truetype_glyf, |
572 | FT_SERVICE_ID_PROPERTIES, &tt_service_properties ) |
573 | #endif |
574 | |
575 | |
576 | FT_CALLBACK_DEF( FT_Module_Interface ) |
577 | tt_get_interface( FT_Module driver, /* TT_Driver */ |
578 | const char* tt_interface ) |
579 | { |
580 | FT_Library library; |
581 | FT_Module_Interface result; |
582 | FT_Module sfntd; |
583 | SFNT_Service sfnt; |
584 | |
585 | |
586 | result = ft_service_list_lookup( tt_services, tt_interface ); |
587 | if ( result ) |
588 | return result; |
589 | |
590 | if ( !driver ) |
591 | return NULL; |
592 | library = driver->library; |
593 | if ( !library ) |
594 | return NULL; |
595 | |
596 | /* only return the default interface from the SFNT module */ |
597 | sfntd = FT_Get_Module( library, "sfnt" ); |
598 | if ( sfntd ) |
599 | { |
600 | sfnt = (SFNT_Service)( sfntd->clazz->module_interface ); |
601 | if ( sfnt ) |
602 | return sfnt->get_interface( driver, tt_interface ); |
603 | } |
604 | |
605 | return 0; |
606 | } |
607 | |
608 | |
609 | /* The FT_DriverInterface structure is defined in ftdriver.h. */ |
610 | |
611 | #ifdef TT_USE_BYTECODE_INTERPRETER |
612 | #define TT_HINTER_FLAG FT_MODULE_DRIVER_HAS_HINTER |
613 | #else |
614 | #define TT_HINTER_FLAG 0 |
615 | #endif |
616 | |
617 | #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS |
618 | #define TT_SIZE_SELECT tt_size_select |
619 | #else |
620 | #define TT_SIZE_SELECT 0 |
621 | #endif |
622 | |
623 | FT_DEFINE_DRIVER( |
624 | tt_driver_class, |
625 | |
626 | FT_MODULE_FONT_DRIVER | |
627 | FT_MODULE_DRIVER_SCALABLE | |
628 | TT_HINTER_FLAG, |
629 | |
630 | sizeof ( TT_DriverRec ), |
631 | |
632 | "truetype" , /* driver name */ |
633 | 0x10000L, /* driver version == 1.0 */ |
634 | 0x20000L, /* driver requires FreeType 2.0 or above */ |
635 | |
636 | NULL, /* module-specific interface */ |
637 | |
638 | tt_driver_init, /* FT_Module_Constructor module_init */ |
639 | tt_driver_done, /* FT_Module_Destructor module_done */ |
640 | tt_get_interface, /* FT_Module_Requester get_interface */ |
641 | |
642 | sizeof ( TT_FaceRec ), |
643 | sizeof ( TT_SizeRec ), |
644 | sizeof ( FT_GlyphSlotRec ), |
645 | |
646 | tt_face_init, /* FT_Face_InitFunc init_face */ |
647 | tt_face_done, /* FT_Face_DoneFunc done_face */ |
648 | tt_size_init, /* FT_Size_InitFunc init_size */ |
649 | tt_size_done, /* FT_Size_DoneFunc done_size */ |
650 | tt_slot_init, /* FT_Slot_InitFunc init_slot */ |
651 | NULL, /* FT_Slot_DoneFunc done_slot */ |
652 | |
653 | tt_glyph_load, /* FT_Slot_LoadFunc load_glyph */ |
654 | |
655 | tt_get_kerning, /* FT_Face_GetKerningFunc get_kerning */ |
656 | NULL, /* FT_Face_AttachFunc attach_file */ |
657 | tt_get_advances, /* FT_Face_GetAdvancesFunc get_advances */ |
658 | |
659 | tt_size_request, /* FT_Size_RequestFunc request_size */ |
660 | TT_SIZE_SELECT /* FT_Size_SelectFunc select_size */ |
661 | ) |
662 | |
663 | |
664 | /* END */ |
665 | |