Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4349 | Serge | 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 |
||
20 | #include FT_INTERNAL_DEBUG_H |
||
21 | #include FT_INTERNAL_STREAM_H |
||
22 | #include FT_INTERNAL_SFNT_H |
||
23 | #include FT_SERVICE_XFREE86_NAME_H |
||
24 | |||
25 | #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
||
26 | #include FT_MULTIPLE_MASTERS_H |
||
27 | #include FT_SERVICE_MULTIPLE_MASTERS_H |
||
28 | #endif |
||
29 | |||
30 | #include FT_SERVICE_TRUETYPE_ENGINE_H |
||
31 | #include FT_SERVICE_TRUETYPE_GLYF_H |
||
32 | #include FT_SERVICE_PROPERTIES_H |
||
33 | #include FT_TRUETYPE_DRIVER_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 | /* |
||
145 | /* tt_get_kerning */ |
||
146 | /* */ |
||
147 | /* |
||
148 | /* A driver method used to return the kerning vector between two */ |
||
149 | /* glyphs of the same face. */ |
||
150 | /* */ |
||
151 | /* */ |
||
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 | /* |
||
159 | /* kerning :: The kerning vector. This is in font units for */ |
||
160 | /* scalable formats, and in pixels for fixed-sizes */ |
||
161 | /* formats. */ |
||
162 | /* */ |
||
163 | /* |
||
164 | /* FreeType error code. 0 means success. */ |
||
165 | /* */ |
||
166 | /* |
||
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 | /* |
||
330 | /* tt_glyph_load */ |
||
331 | /* */ |
||
332 | /* |
||
333 | /* A driver method used to load a glyph within a given glyph slot. */ |
||
334 | /* */ |
||
335 | /* */ |
||
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 | /* |
||
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", /* 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 */>>><> |