1 /***************************************************************************/ |
|
2 /* */ |
|
3 /* ttdriver.c */ |
|
4 /* */ |
|
5 /* TrueType font driver implementation (body). */ |
|
6 /* */ |
|
7 /* Copyright 1996-2011 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_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 |
|
33 #include "ttdriver.h" |
|
34 #include "ttgload.h" |
|
35 #include "ttpload.h" |
|
36 |
|
37 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
|
38 #include "ttgxvar.h" |
|
39 #endif |
|
40 |
|
41 #include "tterrors.h" |
|
42 |
|
43 #include "ttpic.h" |
|
44 |
|
45 /*************************************************************************/ |
|
46 /* */ |
|
47 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
|
48 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ |
|
49 /* messages during execution. */ |
|
50 /* */ |
|
51 #undef FT_COMPONENT |
|
52 #define FT_COMPONENT trace_ttdriver |
|
53 |
|
54 |
|
55 /*************************************************************************/ |
|
56 /*************************************************************************/ |
|
57 /*************************************************************************/ |
|
58 /**** ****/ |
|
59 /**** ****/ |
|
60 /**** F A C E S ****/ |
|
61 /**** ****/ |
|
62 /**** ****/ |
|
63 /*************************************************************************/ |
|
64 /*************************************************************************/ |
|
65 /*************************************************************************/ |
|
66 |
|
67 |
|
68 #undef PAIR_TAG |
|
69 #define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \ |
|
70 (FT_ULong)right ) |
|
71 |
|
72 |
|
73 /*************************************************************************/ |
|
74 /* */ |
|
75 /* <Function> */ |
|
76 /* tt_get_kerning */ |
|
77 /* */ |
|
78 /* <Description> */ |
|
79 /* A driver method used to return the kerning vector between two */ |
|
80 /* glyphs of the same face. */ |
|
81 /* */ |
|
82 /* <Input> */ |
|
83 /* face :: A handle to the source face object. */ |
|
84 /* */ |
|
85 /* left_glyph :: The index of the left glyph in the kern pair. */ |
|
86 /* */ |
|
87 /* right_glyph :: The index of the right glyph in the kern pair. */ |
|
88 /* */ |
|
89 /* <Output> */ |
|
90 /* kerning :: The kerning vector. This is in font units for */ |
|
91 /* scalable formats, and in pixels for fixed-sizes */ |
|
92 /* formats. */ |
|
93 /* */ |
|
94 /* <Return> */ |
|
95 /* FreeType error code. 0 means success. */ |
|
96 /* */ |
|
97 /* <Note> */ |
|
98 /* Only horizontal layouts (left-to-right & right-to-left) are */ |
|
99 /* supported by this function. Other layouts, or more sophisticated */ |
|
100 /* kernings, are out of scope of this method (the basic driver */ |
|
101 /* interface is meant to be simple). */ |
|
102 /* */ |
|
103 /* They can be implemented by format-specific interfaces. */ |
|
104 /* */ |
|
105 static FT_Error |
|
106 tt_get_kerning( FT_Face ttface, /* TT_Face */ |
|
107 FT_UInt left_glyph, |
|
108 FT_UInt right_glyph, |
|
109 FT_Vector* kerning ) |
|
110 { |
|
111 TT_Face face = (TT_Face)ttface; |
|
112 SFNT_Service sfnt = (SFNT_Service)face->sfnt; |
|
113 |
|
114 |
|
115 kerning->x = 0; |
|
116 kerning->y = 0; |
|
117 |
|
118 if ( sfnt ) |
|
119 kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph ); |
|
120 |
|
121 return 0; |
|
122 } |
|
123 |
|
124 |
|
125 #undef PAIR_TAG |
|
126 |
|
127 |
|
128 static FT_Error |
|
129 tt_get_advances( FT_Face ttface, |
|
130 FT_UInt start, |
|
131 FT_UInt count, |
|
132 FT_Int32 flags, |
|
133 FT_Fixed *advances ) |
|
134 { |
|
135 FT_UInt nn; |
|
136 TT_Face face = (TT_Face) ttface; |
|
137 |
|
138 |
|
139 /* XXX: TODO: check for sbits */ |
|
140 |
|
141 if ( flags & FT_LOAD_VERTICAL_LAYOUT ) |
|
142 { |
|
143 for ( nn = 0; nn < count; nn++ ) |
|
144 { |
|
145 FT_Short tsb; |
|
146 FT_UShort ah; |
|
147 |
|
148 |
|
149 TT_Get_VMetrics( face, start + nn, &tsb, &ah ); |
|
150 advances[nn] = ah; |
|
151 } |
|
152 } |
|
153 else |
|
154 { |
|
155 for ( nn = 0; nn < count; nn++ ) |
|
156 { |
|
157 FT_Short lsb; |
|
158 FT_UShort aw; |
|
159 |
|
160 |
|
161 TT_Get_HMetrics( face, start + nn, &lsb, &aw ); |
|
162 advances[nn] = aw; |
|
163 } |
|
164 } |
|
165 |
|
166 return TT_Err_Ok; |
|
167 } |
|
168 |
|
169 /*************************************************************************/ |
|
170 /*************************************************************************/ |
|
171 /*************************************************************************/ |
|
172 /**** ****/ |
|
173 /**** ****/ |
|
174 /**** S I Z E S ****/ |
|
175 /**** ****/ |
|
176 /**** ****/ |
|
177 /*************************************************************************/ |
|
178 /*************************************************************************/ |
|
179 /*************************************************************************/ |
|
180 |
|
181 |
|
182 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS |
|
183 |
|
184 static FT_Error |
|
185 tt_size_select( FT_Size size, |
|
186 FT_ULong strike_index ) |
|
187 { |
|
188 TT_Face ttface = (TT_Face)size->face; |
|
189 TT_Size ttsize = (TT_Size)size; |
|
190 FT_Error error = TT_Err_Ok; |
|
191 |
|
192 |
|
193 ttsize->strike_index = strike_index; |
|
194 |
|
195 if ( FT_IS_SCALABLE( size->face ) ) |
|
196 { |
|
197 /* use the scaled metrics, even when tt_size_reset fails */ |
|
198 FT_Select_Metrics( size->face, strike_index ); |
|
199 |
|
200 tt_size_reset( ttsize ); |
|
201 } |
|
202 else |
|
203 { |
|
204 SFNT_Service sfnt = (SFNT_Service) ttface->sfnt; |
|
205 FT_Size_Metrics* metrics = &size->metrics; |
|
206 |
|
207 |
|
208 error = sfnt->load_strike_metrics( ttface, strike_index, metrics ); |
|
209 if ( error ) |
|
210 ttsize->strike_index = 0xFFFFFFFFUL; |
|
211 } |
|
212 |
|
213 return error; |
|
214 } |
|
215 |
|
216 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ |
|
217 |
|
218 |
|
219 static FT_Error |
|
220 tt_size_request( FT_Size size, |
|
221 FT_Size_Request req ) |
|
222 { |
|
223 TT_Size ttsize = (TT_Size)size; |
|
224 FT_Error error = TT_Err_Ok; |
|
225 |
|
226 |
|
227 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS |
|
228 |
|
229 if ( FT_HAS_FIXED_SIZES( size->face ) ) |
|
230 { |
|
231 TT_Face ttface = (TT_Face)size->face; |
|
232 SFNT_Service sfnt = (SFNT_Service) ttface->sfnt; |
|
233 FT_ULong strike_index; |
|
234 |
|
235 |
|
236 error = sfnt->set_sbit_strike( ttface, req, &strike_index ); |
|
237 |
|
238 if ( error ) |
|
239 ttsize->strike_index = 0xFFFFFFFFUL; |
|
240 else |
|
241 return tt_size_select( size, strike_index ); |
|
242 } |
|
243 |
|
244 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ |
|
245 |
|
246 FT_Request_Metrics( size->face, req ); |
|
247 |
|
248 if ( FT_IS_SCALABLE( size->face ) ) |
|
249 error = tt_size_reset( ttsize ); |
|
250 |
|
251 return error; |
|
252 } |
|
253 |
|
254 |
|
255 /*************************************************************************/ |
|
256 /* */ |
|
257 /* <Function> */ |
|
258 /* Load_Glyph */ |
|
259 /* */ |
|
260 /* <Description> */ |
|
261 /* A driver method used to load a glyph within a given glyph slot. */ |
|
262 /* */ |
|
263 /* <Input> */ |
|
264 /* slot :: A handle to the target slot object where the glyph */ |
|
265 /* will be loaded. */ |
|
266 /* */ |
|
267 /* size :: A handle to the source face size at which the glyph */ |
|
268 /* must be scaled, loaded, etc. */ |
|
269 /* */ |
|
270 /* glyph_index :: The index of the glyph in the font file. */ |
|
271 /* */ |
|
272 /* load_flags :: A flag indicating what to load for this glyph. The */ |
|
273 /* FT_LOAD_XXX constants can be used to control the */ |
|
274 /* glyph loading process (e.g., whether the outline */ |
|
275 /* should be scaled, whether to load bitmaps or not, */ |
|
276 /* whether to hint the outline, etc). */ |
|
277 /* */ |
|
278 /* <Return> */ |
|
279 /* FreeType error code. 0 means success. */ |
|
280 /* */ |
|
281 static FT_Error |
|
282 Load_Glyph( FT_GlyphSlot ttslot, /* TT_GlyphSlot */ |
|
283 FT_Size ttsize, /* TT_Size */ |
|
284 FT_UInt glyph_index, |
|
285 FT_Int32 load_flags ) |
|
286 { |
|
287 TT_GlyphSlot slot = (TT_GlyphSlot)ttslot; |
|
288 TT_Size size = (TT_Size)ttsize; |
|
289 FT_Face face = ttslot->face; |
|
290 FT_Error error; |
|
291 |
|
292 |
|
293 if ( !slot ) |
|
294 return TT_Err_Invalid_Slot_Handle; |
|
295 |
|
296 if ( !size ) |
|
297 return TT_Err_Invalid_Size_Handle; |
|
298 |
|
299 if ( !face ) |
|
300 return TT_Err_Invalid_Argument; |
|
301 |
|
302 #ifdef FT_CONFIG_OPTION_INCREMENTAL |
|
303 if ( glyph_index >= (FT_UInt)face->num_glyphs && |
|
304 !face->internal->incremental_interface ) |
|
305 #else |
|
306 if ( glyph_index >= (FT_UInt)face->num_glyphs ) |
|
307 #endif |
|
308 return TT_Err_Invalid_Argument; |
|
309 |
|
310 if ( load_flags & FT_LOAD_NO_HINTING ) |
|
311 { |
|
312 /* both FT_LOAD_NO_HINTING and FT_LOAD_NO_AUTOHINT */ |
|
313 /* are necessary to disable hinting for tricky fonts */ |
|
314 |
|
315 if ( FT_IS_TRICKY( face ) ) |
|
316 load_flags &= ~FT_LOAD_NO_HINTING; |
|
317 |
|
318 if ( load_flags & FT_LOAD_NO_AUTOHINT ) |
|
319 load_flags |= FT_LOAD_NO_HINTING; |
|
320 } |
|
321 |
|
322 if ( load_flags & ( FT_LOAD_NO_RECURSE | FT_LOAD_NO_SCALE ) ) |
|
323 { |
|
324 load_flags |= FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE; |
|
325 |
|
326 if ( !FT_IS_TRICKY( face ) ) |
|
327 load_flags |= FT_LOAD_NO_HINTING; |
|
328 } |
|
329 |
|
330 /* now load the glyph outline if necessary */ |
|
331 error = TT_Load_Glyph( size, slot, glyph_index, load_flags ); |
|
332 |
|
333 /* force drop-out mode to 2 - irrelevant now */ |
|
334 /* slot->outline.dropout_mode = 2; */ |
|
335 |
|
336 return error; |
|
337 } |
|
338 |
|
339 |
|
340 /*************************************************************************/ |
|
341 /*************************************************************************/ |
|
342 /*************************************************************************/ |
|
343 /**** ****/ |
|
344 /**** ****/ |
|
345 /**** D R I V E R I N T E R F A C E ****/ |
|
346 /**** ****/ |
|
347 /**** ****/ |
|
348 /*************************************************************************/ |
|
349 /*************************************************************************/ |
|
350 /*************************************************************************/ |
|
351 |
|
352 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
|
353 FT_DEFINE_SERVICE_MULTIMASTERSREC(tt_service_gx_multi_masters, |
|
354 (FT_Get_MM_Func) NULL, |
|
355 (FT_Set_MM_Design_Func) NULL, |
|
356 (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, |
|
357 (FT_Get_MM_Var_Func) TT_Get_MM_Var, |
|
358 (FT_Set_Var_Design_Func)TT_Set_Var_Design |
|
359 ) |
|
360 #endif |
|
361 |
|
362 static const FT_Service_TrueTypeEngineRec tt_service_truetype_engine = |
|
363 { |
|
364 #ifdef TT_USE_BYTECODE_INTERPRETER |
|
365 |
|
366 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING |
|
367 FT_TRUETYPE_ENGINE_TYPE_UNPATENTED |
|
368 #else |
|
369 FT_TRUETYPE_ENGINE_TYPE_PATENTED |
|
370 #endif |
|
371 |
|
372 #else /* !TT_USE_BYTECODE_INTERPRETER */ |
|
373 |
|
374 FT_TRUETYPE_ENGINE_TYPE_NONE |
|
375 |
|
376 #endif /* TT_USE_BYTECODE_INTERPRETER */ |
|
377 }; |
|
378 |
|
379 FT_DEFINE_SERVICE_TTGLYFREC(tt_service_truetype_glyf, |
|
380 (TT_Glyf_GetLocationFunc)tt_face_get_location |
|
381 ) |
|
382 |
|
383 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
|
384 FT_DEFINE_SERVICEDESCREC4(tt_services, |
|
385 FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE, |
|
386 FT_SERVICE_ID_MULTI_MASTERS, &FT_TT_SERVICE_GX_MULTI_MASTERS_GET, |
|
387 FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, |
|
388 FT_SERVICE_ID_TT_GLYF, &FT_TT_SERVICE_TRUETYPE_GLYF_GET |
|
389 ) |
|
390 #else |
|
391 FT_DEFINE_SERVICEDESCREC3(tt_services, |
|
392 FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE, |
|
393 FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, |
|
394 FT_SERVICE_ID_TT_GLYF, &FT_TT_SERVICE_TRUETYPE_GLYF_GET |
|
395 ) |
|
396 #endif |
|
397 |
|
398 FT_CALLBACK_DEF( FT_Module_Interface ) |
|
399 tt_get_interface( FT_Module driver, /* TT_Driver */ |
|
400 const char* tt_interface ) |
|
401 { |
|
402 FT_Module_Interface result; |
|
403 FT_Module sfntd; |
|
404 SFNT_Service sfnt; |
|
405 |
|
406 result = ft_service_list_lookup( FT_TT_SERVICES_GET, tt_interface ); |
|
407 if ( result != NULL ) |
|
408 return result; |
|
409 |
|
410 if ( !driver ) |
|
411 return NULL; |
|
412 |
|
413 /* only return the default interface from the SFNT module */ |
|
414 sfntd = FT_Get_Module( driver->library, "sfnt" ); |
|
415 if ( sfntd ) |
|
416 { |
|
417 sfnt = (SFNT_Service)( sfntd->clazz->module_interface ); |
|
418 if ( sfnt ) |
|
419 return sfnt->get_interface( driver, tt_interface ); |
|
420 } |
|
421 |
|
422 return 0; |
|
423 } |
|
424 |
|
425 |
|
426 /* The FT_DriverInterface structure is defined in ftdriver.h. */ |
|
427 |
|
428 #ifdef TT_USE_BYTECODE_INTERPRETER |
|
429 #define TT_HINTER_FLAG FT_MODULE_DRIVER_HAS_HINTER |
|
430 #else |
|
431 #define TT_HINTER_FLAG 0 |
|
432 #endif |
|
433 |
|
434 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS |
|
435 #define TT_SIZE_SELECT tt_size_select |
|
436 #else |
|
437 #define TT_SIZE_SELECT 0 |
|
438 #endif |
|
439 |
|
440 FT_DEFINE_DRIVER(tt_driver_class, |
|
441 |
|
442 |
|
443 FT_MODULE_FONT_DRIVER | |
|
444 FT_MODULE_DRIVER_SCALABLE | |
|
445 TT_HINTER_FLAG, |
|
446 |
|
447 sizeof ( TT_DriverRec ), |
|
448 |
|
449 "truetype", /* driver name */ |
|
450 0x10000L, /* driver version == 1.0 */ |
|
451 0x20000L, /* driver requires FreeType 2.0 or above */ |
|
452 |
|
453 (void*)0, /* driver specific interface */ |
|
454 |
|
455 tt_driver_init, |
|
456 tt_driver_done, |
|
457 tt_get_interface, |
|
458 |
|
459 sizeof ( TT_FaceRec ), |
|
460 sizeof ( TT_SizeRec ), |
|
461 sizeof ( FT_GlyphSlotRec ), |
|
462 |
|
463 tt_face_init, |
|
464 tt_face_done, |
|
465 tt_size_init, |
|
466 tt_size_done, |
|
467 tt_slot_init, |
|
468 0, /* FT_Slot_DoneFunc */ |
|
469 |
|
470 ft_stub_set_char_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */ |
|
471 ft_stub_set_pixel_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */ |
|
472 |
|
473 Load_Glyph, |
|
474 |
|
475 tt_get_kerning, |
|
476 0, /* FT_Face_AttachFunc */ |
|
477 tt_get_advances, |
|
478 |
|
479 tt_size_request, |
|
480 TT_SIZE_SELECT |
|
481 ) |
|
482 |
|
483 |
|
484 /* END */ |
|