OLD | NEW |
| (Empty) |
1 /***************************************************************************/ | |
2 /* */ | |
3 /* ttdriver.c */ | |
4 /* */ | |
5 /* TrueType font driver implementation (body). */ | |
6 /* */ | |
7 /* Copyright 1996-2013 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 "../../include/ft2build.h" | |
20 #include "../../include/freetype/internal/ftdebug.h" | |
21 #include "../../include/freetype/internal/ftstream.h" | |
22 #include "../../include/freetype/internal/sfnt.h" | |
23 #include "../../include/freetype/internal/services/svxf86nm.h" | |
24 | |
25 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT | |
26 #include "../../include/freetype/ftmm.h" | |
27 #include "../../include/freetype/internal/services/svmm.h" | |
28 #endif | |
29 | |
30 #include "../../include/freetype/internal/services/svtteng.h" | |
31 #include "../../include/freetype/internal/services/svttglyf.h" | |
32 #include "../../include/freetype/internal/services/svprop.h" | |
33 #include "../../include/freetype/ftttdrv.h" | |
34 | |
35 #include "ttdriver.h" | |
36 #include "ttgload.h" | |
37 #include "ttpload.h" | |
38 | |
39 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT | |
40 #include "ttgxvar.h" | |
41 #endif | |
42 | |
43 #include "tterrors.h" | |
44 | |
45 #include "ttpic.h" | |
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 trace_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 { | |
66 FT_Error error = FT_Err_Ok; | |
67 TT_Driver driver = (TT_Driver)module; | |
68 | |
69 | |
70 if ( !ft_strcmp( property_name, "interpreter-version" ) ) | |
71 { | |
72 FT_UInt* interpreter_version = (FT_UInt*)value; | |
73 | |
74 | |
75 #ifndef TT_CONFIG_OPTION_SUBPIXEL_HINTING | |
76 if ( *interpreter_version != TT_INTERPRETER_VERSION_35 ) | |
77 error = FT_ERR( Unimplemented_Feature ); | |
78 else | |
79 #endif | |
80 driver->interpreter_version = *interpreter_version; | |
81 | |
82 return error; | |
83 } | |
84 | |
85 FT_TRACE0(( "tt_property_set: missing property `%s'\n", | |
86 property_name )); | |
87 return FT_THROW( Missing_Property ); | |
88 } | |
89 | |
90 | |
91 static FT_Error | |
92 tt_property_get( FT_Module module, /* TT_Driver */ | |
93 const char* property_name, | |
94 const void* value ) | |
95 { | |
96 FT_Error error = FT_Err_Ok; | |
97 TT_Driver driver = (TT_Driver)module; | |
98 | |
99 FT_UInt interpreter_version = driver->interpreter_version; | |
100 | |
101 | |
102 if ( !ft_strcmp( property_name, "interpreter-version" ) ) | |
103 { | |
104 FT_UInt* val = (FT_UInt*)value; | |
105 | |
106 | |
107 *val = interpreter_version; | |
108 | |
109 return error; | |
110 } | |
111 | |
112 FT_TRACE0(( "tt_property_get: missing property `%s'\n", | |
113 property_name )); | |
114 return FT_THROW( Missing_Property ); | |
115 } | |
116 | |
117 | |
118 FT_DEFINE_SERVICE_PROPERTIESREC( | |
119 tt_service_properties, | |
120 (FT_Properties_SetFunc)tt_property_set, | |
121 (FT_Properties_GetFunc)tt_property_get ) | |
122 | |
123 | |
124 /*************************************************************************/ | |
125 /*************************************************************************/ | |
126 /*************************************************************************/ | |
127 /**** ****/ | |
128 /**** ****/ | |
129 /**** F A C E S ****/ | |
130 /**** ****/ | |
131 /**** ****/ | |
132 /*************************************************************************/ | |
133 /*************************************************************************/ | |
134 /*************************************************************************/ | |
135 | |
136 | |
137 #undef PAIR_TAG | |
138 #define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \ | |
139 (FT_ULong)right ) | |
140 | |
141 | |
142 /*************************************************************************/ | |
143 /* */ | |
144 /* <Function> */ | |
145 /* tt_get_kerning */ | |
146 /* */ | |
147 /* <Description> */ | |
148 /* A driver method used to return the kerning vector between two */ | |
149 /* glyphs of the same face. */ | |
150 /* */ | |
151 /* <Input> */ | |
152 /* face :: A handle to the source face object. */ | |
153 /* */ | |
154 /* left_glyph :: The index of the left glyph in the kern pair. */ | |
155 /* */ | |
156 /* right_glyph :: The index of the right glyph in the kern pair. */ | |
157 /* */ | |
158 /* <Output> */ | |
159 /* kerning :: The kerning vector. This is in font units for */ | |
160 /* scalable formats, and in pixels for fixed-sizes */ | |
161 /* formats. */ | |
162 /* */ | |
163 /* <Return> */ | |
164 /* FreeType error code. 0 means success. */ | |
165 /* */ | |
166 /* <Note> */ | |
167 /* Only horizontal layouts (left-to-right & right-to-left) are */ | |
168 /* supported by this function. Other layouts, or more sophisticated */ | |
169 /* kernings, are out of scope of this method (the basic driver */ | |
170 /* interface is meant to be simple). */ | |
171 /* */ | |
172 /* They can be implemented by format-specific interfaces. */ | |
173 /* */ | |
174 static FT_Error | |
175 tt_get_kerning( FT_Face ttface, /* TT_Face */ | |
176 FT_UInt left_glyph, | |
177 FT_UInt right_glyph, | |
178 FT_Vector* kerning ) | |
179 { | |
180 TT_Face face = (TT_Face)ttface; | |
181 SFNT_Service sfnt = (SFNT_Service)face->sfnt; | |
182 | |
183 | |
184 kerning->x = 0; | |
185 kerning->y = 0; | |
186 | |
187 if ( sfnt ) | |
188 kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph ); | |
189 | |
190 return 0; | |
191 } | |
192 | |
193 | |
194 #undef PAIR_TAG | |
195 | |
196 | |
197 static FT_Error | |
198 tt_get_advances( FT_Face ttface, | |
199 FT_UInt start, | |
200 FT_UInt count, | |
201 FT_Int32 flags, | |
202 FT_Fixed *advances ) | |
203 { | |
204 FT_UInt nn; | |
205 TT_Face face = (TT_Face) ttface; | |
206 | |
207 | |
208 /* XXX: TODO: check for sbits */ | |
209 | |
210 if ( flags & FT_LOAD_VERTICAL_LAYOUT ) | |
211 { | |
212 for ( nn = 0; nn < count; nn++ ) | |
213 { | |
214 FT_Short tsb; | |
215 FT_UShort ah; | |
216 | |
217 | |
218 TT_Get_VMetrics( face, start + nn, &tsb, &ah ); | |
219 advances[nn] = ah; | |
220 } | |
221 } | |
222 else | |
223 { | |
224 for ( nn = 0; nn < count; nn++ ) | |
225 { | |
226 FT_Short lsb; | |
227 FT_UShort aw; | |
228 | |
229 | |
230 TT_Get_HMetrics( face, start + nn, &lsb, &aw ); | |
231 advances[nn] = aw; | |
232 } | |
233 } | |
234 | |
235 return FT_Err_Ok; | |
236 } | |
237 | |
238 /*************************************************************************/ | |
239 /*************************************************************************/ | |
240 /*************************************************************************/ | |
241 /**** ****/ | |
242 /**** ****/ | |
243 /**** S I Z E S ****/ | |
244 /**** ****/ | |
245 /**** ****/ | |
246 /*************************************************************************/ | |
247 /*************************************************************************/ | |
248 /*************************************************************************/ | |
249 | |
250 | |
251 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS | |
252 | |
253 static FT_Error | |
254 tt_size_select( FT_Size size, | |
255 FT_ULong strike_index ) | |
256 { | |
257 TT_Face ttface = (TT_Face)size->face; | |
258 TT_Size ttsize = (TT_Size)size; | |
259 FT_Error error = FT_Err_Ok; | |
260 | |
261 | |
262 ttsize->strike_index = strike_index; | |
263 | |
264 if ( FT_IS_SCALABLE( size->face ) ) | |
265 { | |
266 /* use the scaled metrics, even when tt_size_reset fails */ | |
267 FT_Select_Metrics( size->face, strike_index ); | |
268 | |
269 tt_size_reset( ttsize ); | |
270 } | |
271 else | |
272 { | |
273 SFNT_Service sfnt = (SFNT_Service) ttface->sfnt; | |
274 FT_Size_Metrics* metrics = &size->metrics; | |
275 | |
276 | |
277 error = sfnt->load_strike_metrics( ttface, strike_index, metrics ); | |
278 if ( error ) | |
279 ttsize->strike_index = 0xFFFFFFFFUL; | |
280 } | |
281 | |
282 return error; | |
283 } | |
284 | |
285 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ | |
286 | |
287 | |
288 static FT_Error | |
289 tt_size_request( FT_Size size, | |
290 FT_Size_Request req ) | |
291 { | |
292 TT_Size ttsize = (TT_Size)size; | |
293 FT_Error error = FT_Err_Ok; | |
294 | |
295 | |
296 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS | |
297 | |
298 if ( FT_HAS_FIXED_SIZES( size->face ) ) | |
299 { | |
300 TT_Face ttface = (TT_Face)size->face; | |
301 SFNT_Service sfnt = (SFNT_Service) ttface->sfnt; | |
302 FT_ULong strike_index; | |
303 | |
304 | |
305 error = sfnt->set_sbit_strike( ttface, req, &strike_index ); | |
306 | |
307 if ( error ) | |
308 ttsize->strike_index = 0xFFFFFFFFUL; | |
309 else | |
310 return tt_size_select( size, strike_index ); | |
311 } | |
312 | |
313 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ | |
314 | |
315 FT_Request_Metrics( size->face, req ); | |
316 | |
317 if ( FT_IS_SCALABLE( size->face ) ) | |
318 { | |
319 error = tt_size_reset( ttsize ); | |
320 ttsize->root.metrics = ttsize->metrics; | |
321 } | |
322 | |
323 return error; | |
324 } | |
325 | |
326 | |
327 /*************************************************************************/ | |
328 /* */ | |
329 /* <Function> */ | |
330 /* tt_glyph_load */ | |
331 /* */ | |
332 /* <Description> */ | |
333 /* A driver method used to load a glyph within a given glyph slot. */ | |
334 /* */ | |
335 /* <Input> */ | |
336 /* slot :: A handle to the target slot object where the glyph */ | |
337 /* will be loaded. */ | |
338 /* */ | |
339 /* size :: A handle to the source face size at which the glyph */ | |
340 /* must be scaled, loaded, etc. */ | |
341 /* */ | |
342 /* glyph_index :: The index of the glyph in the font file. */ | |
343 /* */ | |
344 /* load_flags :: A flag indicating what to load for this glyph. The */ | |
345 /* FT_LOAD_XXX constants can be used to control the */ | |
346 /* glyph loading process (e.g., whether the outline */ | |
347 /* should be scaled, whether to load bitmaps or not, */ | |
348 /* whether to hint the outline, etc). */ | |
349 /* */ | |
350 /* <Return> */ | |
351 /* FreeType error code. 0 means success. */ | |
352 /* */ | |
353 static FT_Error | |
354 tt_glyph_load( FT_GlyphSlot ttslot, /* TT_GlyphSlot */ | |
355 FT_Size ttsize, /* TT_Size */ | |
356 FT_UInt glyph_index, | |
357 FT_Int32 load_flags ) | |
358 { | |
359 TT_GlyphSlot slot = (TT_GlyphSlot)ttslot; | |
360 TT_Size size = (TT_Size)ttsize; | |
361 FT_Face face = ttslot->face; | |
362 FT_Error error; | |
363 | |
364 | |
365 if ( !slot ) | |
366 return FT_THROW( Invalid_Slot_Handle ); | |
367 | |
368 if ( !size ) | |
369 return FT_THROW( Invalid_Size_Handle ); | |
370 | |
371 if ( !face ) | |
372 return FT_THROW( Invalid_Argument ); | |
373 | |
374 #ifdef FT_CONFIG_OPTION_INCREMENTAL | |
375 if ( glyph_index >= (FT_UInt)face->num_glyphs && | |
376 !face->internal->incremental_interface ) | |
377 #else | |
378 if ( glyph_index >= (FT_UInt)face->num_glyphs ) | |
379 #endif | |
380 return FT_THROW( Invalid_Argument ); | |
381 | |
382 if ( load_flags & FT_LOAD_NO_HINTING ) | |
383 { | |
384 /* both FT_LOAD_NO_HINTING and FT_LOAD_NO_AUTOHINT */ | |
385 /* are necessary to disable hinting for tricky fonts */ | |
386 | |
387 if ( FT_IS_TRICKY( face ) ) | |
388 load_flags &= ~FT_LOAD_NO_HINTING; | |
389 | |
390 if ( load_flags & FT_LOAD_NO_AUTOHINT ) | |
391 load_flags |= FT_LOAD_NO_HINTING; | |
392 } | |
393 | |
394 if ( load_flags & ( FT_LOAD_NO_RECURSE | FT_LOAD_NO_SCALE ) ) | |
395 { | |
396 load_flags |= FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE; | |
397 | |
398 if ( !FT_IS_TRICKY( face ) ) | |
399 load_flags |= FT_LOAD_NO_HINTING; | |
400 } | |
401 | |
402 /* now load the glyph outline if necessary */ | |
403 error = TT_Load_Glyph( size, slot, glyph_index, load_flags ); | |
404 | |
405 /* force drop-out mode to 2 - irrelevant now */ | |
406 /* slot->outline.dropout_mode = 2; */ | |
407 | |
408 return error; | |
409 } | |
410 | |
411 | |
412 /*************************************************************************/ | |
413 /*************************************************************************/ | |
414 /*************************************************************************/ | |
415 /**** ****/ | |
416 /**** ****/ | |
417 /**** D R I V E R I N T E R F A C E ****/ | |
418 /**** ****/ | |
419 /**** ****/ | |
420 /*************************************************************************/ | |
421 /*************************************************************************/ | |
422 /*************************************************************************/ | |
423 | |
424 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT | |
425 FT_DEFINE_SERVICE_MULTIMASTERSREC( | |
426 tt_service_gx_multi_masters, | |
427 (FT_Get_MM_Func) NULL, | |
428 (FT_Set_MM_Design_Func) NULL, | |
429 (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, | |
430 (FT_Get_MM_Var_Func) TT_Get_MM_Var, | |
431 (FT_Set_Var_Design_Func)TT_Set_Var_Design ) | |
432 #endif | |
433 | |
434 static const FT_Service_TrueTypeEngineRec tt_service_truetype_engine = | |
435 { | |
436 #ifdef TT_USE_BYTECODE_INTERPRETER | |
437 | |
438 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING | |
439 FT_TRUETYPE_ENGINE_TYPE_UNPATENTED | |
440 #else | |
441 FT_TRUETYPE_ENGINE_TYPE_PATENTED | |
442 #endif | |
443 | |
444 #else /* !TT_USE_BYTECODE_INTERPRETER */ | |
445 | |
446 FT_TRUETYPE_ENGINE_TYPE_NONE | |
447 | |
448 #endif /* TT_USE_BYTECODE_INTERPRETER */ | |
449 }; | |
450 | |
451 FT_DEFINE_SERVICE_TTGLYFREC( | |
452 tt_service_truetype_glyf, | |
453 (TT_Glyf_GetLocationFunc)tt_face_get_location ) | |
454 | |
455 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT | |
456 FT_DEFINE_SERVICEDESCREC5( | |
457 tt_services, | |
458 FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE, | |
459 FT_SERVICE_ID_MULTI_MASTERS, &TT_SERVICE_GX_MULTI_MASTERS_GET, | |
460 FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, | |
461 FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET, | |
462 FT_SERVICE_ID_PROPERTIES, &TT_SERVICE_PROPERTIES_GET ) | |
463 #else | |
464 FT_DEFINE_SERVICEDESCREC4( | |
465 tt_services, | |
466 FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE, | |
467 FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, | |
468 FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET, | |
469 FT_SERVICE_ID_PROPERTIES, &TT_SERVICE_PROPERTIES_GET ) | |
470 #endif | |
471 | |
472 | |
473 FT_CALLBACK_DEF( FT_Module_Interface ) | |
474 tt_get_interface( FT_Module driver, /* TT_Driver */ | |
475 const char* tt_interface ) | |
476 { | |
477 FT_Library library; | |
478 FT_Module_Interface result; | |
479 FT_Module sfntd; | |
480 SFNT_Service sfnt; | |
481 | |
482 | |
483 /* TT_SERVICES_GET derefers `library' in PIC mode */ | |
484 #ifdef FT_CONFIG_OPTION_PIC | |
485 if ( !driver ) | |
486 return NULL; | |
487 library = driver->library; | |
488 if ( !library ) | |
489 return NULL; | |
490 #endif | |
491 | |
492 result = ft_service_list_lookup( TT_SERVICES_GET, tt_interface ); | |
493 if ( result != NULL ) | |
494 return result; | |
495 | |
496 #ifndef FT_CONFIG_OPTION_PIC | |
497 if ( !driver ) | |
498 return NULL; | |
499 library = driver->library; | |
500 if ( !library ) | |
501 return NULL; | |
502 #endif | |
503 | |
504 /* only return the default interface from the SFNT module */ | |
505 sfntd = FT_Get_Module( library, "sfnt" ); | |
506 if ( sfntd ) | |
507 { | |
508 sfnt = (SFNT_Service)( sfntd->clazz->module_interface ); | |
509 if ( sfnt ) | |
510 return sfnt->get_interface( driver, tt_interface ); | |
511 } | |
512 | |
513 return 0; | |
514 } | |
515 | |
516 | |
517 /* The FT_DriverInterface structure is defined in ftdriver.h. */ | |
518 | |
519 #ifdef TT_USE_BYTECODE_INTERPRETER | |
520 #define TT_HINTER_FLAG FT_MODULE_DRIVER_HAS_HINTER | |
521 #else | |
522 #define TT_HINTER_FLAG 0 | |
523 #endif | |
524 | |
525 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS | |
526 #define TT_SIZE_SELECT tt_size_select | |
527 #else | |
528 #define TT_SIZE_SELECT 0 | |
529 #endif | |
530 | |
531 FT_DEFINE_DRIVER( | |
532 tt_driver_class, | |
533 | |
534 FT_MODULE_FONT_DRIVER | | |
535 FT_MODULE_DRIVER_SCALABLE | | |
536 TT_HINTER_FLAG, | |
537 | |
538 sizeof ( TT_DriverRec ), | |
539 | |
540 "truetype_xyq", /* driver name */ | |
541 0x10000L, /* driver version == 1.0 */ | |
542 0x20000L, /* driver requires FreeType 2.0 or above */ | |
543 | |
544 (void*)0, /* driver specific interface */ | |
545 | |
546 tt_driver_init, | |
547 tt_driver_done, | |
548 tt_get_interface, | |
549 | |
550 sizeof ( TT_FaceRec ), | |
551 sizeof ( TT_SizeRec ), | |
552 sizeof ( FT_GlyphSlotRec ), | |
553 | |
554 tt_face_init, | |
555 tt_face_done, | |
556 tt_size_init, | |
557 tt_size_done, | |
558 tt_slot_init, | |
559 0, /* FT_Slot_DoneFunc */ | |
560 | |
561 tt_glyph_load, | |
562 | |
563 tt_get_kerning, | |
564 0, /* FT_Face_AttachFunc */ | |
565 tt_get_advances, | |
566 | |
567 tt_size_request, | |
568 TT_SIZE_SELECT | |
569 ) | |
570 | |
571 | |
572 /* END */ | |
OLD | NEW |