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