[FREETYPE] Update to v2.6.3. CORE-10964
[reactos.git] / reactos / lib / 3rdparty / freetype / src / truetype / ttdriver.c
1 /***************************************************************************/
2 /* */
3 /* ttdriver.c */
4 /* */
5 /* TrueType font driver implementation (body). */
6 /* */
7 /* Copyright 1996-2016 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 #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, /* set_property */
121 (FT_Properties_GetFunc)tt_property_get ) /* get_property */
122
123
124 /*************************************************************************/
125 /*************************************************************************/
126 /*************************************************************************/
127 /**** ****/
128 /**** ****/
129 /**** F A C E S ****/
130 /**** ****/
131 /**** ****/
132 /*************************************************************************/
133 /*************************************************************************/
134 /*************************************************************************/
135
136
137 /*************************************************************************/
138 /* */
139 /* <Function> */
140 /* tt_get_kerning */
141 /* */
142 /* <Description> */
143 /* A driver method used to return the kerning vector between two */
144 /* glyphs of the same face. */
145 /* */
146 /* <Input> */
147 /* face :: A handle to the source face object. */
148 /* */
149 /* left_glyph :: The index of the left glyph in the kern pair. */
150 /* */
151 /* right_glyph :: The index of the right glyph in the kern pair. */
152 /* */
153 /* <Output> */
154 /* kerning :: The kerning vector. This is in font units for */
155 /* scalable formats, and in pixels for fixed-sizes */
156 /* formats. */
157 /* */
158 /* <Return> */
159 /* FreeType error code. 0 means success. */
160 /* */
161 /* <Note> */
162 /* Only horizontal layouts (left-to-right & right-to-left) are */
163 /* supported by this function. Other layouts, or more sophisticated */
164 /* kernings, are out of scope of this method (the basic driver */
165 /* interface is meant to be simple). */
166 /* */
167 /* They can be implemented by format-specific interfaces. */
168 /* */
169 static FT_Error
170 tt_get_kerning( FT_Face ttface, /* TT_Face */
171 FT_UInt left_glyph,
172 FT_UInt right_glyph,
173 FT_Vector* kerning )
174 {
175 TT_Face face = (TT_Face)ttface;
176 SFNT_Service sfnt = (SFNT_Service)face->sfnt;
177
178
179 kerning->x = 0;
180 kerning->y = 0;
181
182 if ( sfnt )
183 kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph );
184
185 return 0;
186 }
187
188
189 static FT_Error
190 tt_get_advances( FT_Face ttface,
191 FT_UInt start,
192 FT_UInt count,
193 FT_Int32 flags,
194 FT_Fixed *advances )
195 {
196 FT_UInt nn;
197 TT_Face face = (TT_Face) ttface;
198
199
200 /* XXX: TODO: check for sbits */
201
202 if ( flags & FT_LOAD_VERTICAL_LAYOUT )
203 {
204 for ( nn = 0; nn < count; nn++ )
205 {
206 FT_Short tsb;
207 FT_UShort ah;
208
209
210 /* since we don't need `tsb', we use zero for `yMax' parameter */
211 TT_Get_VMetrics( face, start + nn, 0, &tsb, &ah );
212 advances[nn] = ah;
213 }
214 }
215 else
216 {
217 for ( nn = 0; nn < count; nn++ )
218 {
219 FT_Short lsb;
220 FT_UShort aw;
221
222
223 TT_Get_HMetrics( face, start + nn, &lsb, &aw );
224 advances[nn] = aw;
225 }
226 }
227
228 return FT_Err_Ok;
229 }
230
231
232 /*************************************************************************/
233 /*************************************************************************/
234 /*************************************************************************/
235 /**** ****/
236 /**** ****/
237 /**** S I Z E S ****/
238 /**** ****/
239 /**** ****/
240 /*************************************************************************/
241 /*************************************************************************/
242 /*************************************************************************/
243
244
245 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
246
247 static FT_Error
248 tt_size_select( FT_Size size,
249 FT_ULong strike_index )
250 {
251 TT_Face ttface = (TT_Face)size->face;
252 TT_Size ttsize = (TT_Size)size;
253 FT_Error error = FT_Err_Ok;
254
255
256 ttsize->strike_index = strike_index;
257
258 if ( FT_IS_SCALABLE( size->face ) )
259 {
260 /* use the scaled metrics, even when tt_size_reset fails */
261 FT_Select_Metrics( size->face, strike_index );
262
263 tt_size_reset( ttsize ); /* ignore return value */
264 }
265 else
266 {
267 SFNT_Service sfnt = (SFNT_Service) ttface->sfnt;
268 FT_Size_Metrics* metrics = &size->metrics;
269
270
271 error = sfnt->load_strike_metrics( ttface, strike_index, metrics );
272 if ( error )
273 ttsize->strike_index = 0xFFFFFFFFUL;
274 }
275
276 return error;
277 }
278
279 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
280
281
282 static FT_Error
283 tt_size_request( FT_Size size,
284 FT_Size_Request req )
285 {
286 TT_Size ttsize = (TT_Size)size;
287 FT_Error error = FT_Err_Ok;
288
289
290 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
291
292 if ( FT_HAS_FIXED_SIZES( size->face ) )
293 {
294 TT_Face ttface = (TT_Face)size->face;
295 SFNT_Service sfnt = (SFNT_Service) ttface->sfnt;
296 FT_ULong strike_index;
297
298
299 error = sfnt->set_sbit_strike( ttface, req, &strike_index );
300
301 if ( error )
302 ttsize->strike_index = 0xFFFFFFFFUL;
303 else
304 return tt_size_select( size, strike_index );
305 }
306
307 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
308
309 FT_Request_Metrics( size->face, req );
310
311 if ( FT_IS_SCALABLE( size->face ) )
312 {
313 error = tt_size_reset( ttsize );
314 ttsize->root.metrics = ttsize->metrics;
315 }
316
317 return error;
318 }
319
320
321 /*************************************************************************/
322 /* */
323 /* <Function> */
324 /* tt_glyph_load */
325 /* */
326 /* <Description> */
327 /* A driver method used to load a glyph within a given glyph slot. */
328 /* */
329 /* <Input> */
330 /* slot :: A handle to the target slot object where the glyph */
331 /* will be loaded. */
332 /* */
333 /* size :: A handle to the source face size at which the glyph */
334 /* must be scaled, loaded, etc. */
335 /* */
336 /* glyph_index :: The index of the glyph in the font file. */
337 /* */
338 /* load_flags :: A flag indicating what to load for this glyph. The */
339 /* FT_LOAD_XXX constants can be used to control the */
340 /* glyph loading process (e.g., whether the outline */
341 /* should be scaled, whether to load bitmaps or not, */
342 /* whether to hint the outline, etc). */
343 /* */
344 /* <Return> */
345 /* FreeType error code. 0 means success. */
346 /* */
347 static FT_Error
348 tt_glyph_load( FT_GlyphSlot ttslot, /* TT_GlyphSlot */
349 FT_Size ttsize, /* TT_Size */
350 FT_UInt glyph_index,
351 FT_Int32 load_flags )
352 {
353 TT_GlyphSlot slot = (TT_GlyphSlot)ttslot;
354 TT_Size size = (TT_Size)ttsize;
355 FT_Face face = ttslot->face;
356 FT_Error error;
357
358
359 if ( !slot )
360 return FT_THROW( Invalid_Slot_Handle );
361
362 if ( !size )
363 return FT_THROW( Invalid_Size_Handle );
364
365 if ( !face )
366 return FT_THROW( Invalid_Face_Handle );
367
368 #ifdef FT_CONFIG_OPTION_INCREMENTAL
369 if ( glyph_index >= (FT_UInt)face->num_glyphs &&
370 !face->internal->incremental_interface )
371 #else
372 if ( glyph_index >= (FT_UInt)face->num_glyphs )
373 #endif
374 return FT_THROW( Invalid_Argument );
375
376 if ( load_flags & FT_LOAD_NO_HINTING )
377 {
378 /* both FT_LOAD_NO_HINTING and FT_LOAD_NO_AUTOHINT */
379 /* are necessary to disable hinting for tricky fonts */
380
381 if ( FT_IS_TRICKY( face ) )
382 load_flags &= ~FT_LOAD_NO_HINTING;
383
384 if ( load_flags & FT_LOAD_NO_AUTOHINT )
385 load_flags |= FT_LOAD_NO_HINTING;
386 }
387
388 if ( load_flags & ( FT_LOAD_NO_RECURSE | FT_LOAD_NO_SCALE ) )
389 {
390 load_flags |= FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE;
391
392 if ( !FT_IS_TRICKY( face ) )
393 load_flags |= FT_LOAD_NO_HINTING;
394 }
395
396 /* now load the glyph outline if necessary */
397 error = TT_Load_Glyph( size, slot, glyph_index, load_flags );
398
399 /* force drop-out mode to 2 - irrelevant now */
400 /* slot->outline.dropout_mode = 2; */
401
402 return error;
403 }
404
405
406 /*************************************************************************/
407 /*************************************************************************/
408 /*************************************************************************/
409 /**** ****/
410 /**** ****/
411 /**** D R I V E R I N T E R F A C E ****/
412 /**** ****/
413 /**** ****/
414 /*************************************************************************/
415 /*************************************************************************/
416 /*************************************************************************/
417
418 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
419 FT_DEFINE_SERVICE_MULTIMASTERSREC(
420 tt_service_gx_multi_masters,
421 (FT_Get_MM_Func) NULL, /* get_mm */
422 (FT_Set_MM_Design_Func) NULL, /* set_mm_design */
423 (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, /* set_mm_blend */
424 (FT_Get_MM_Var_Func) TT_Get_MM_Var, /* get_mm_var */
425 (FT_Set_Var_Design_Func)TT_Set_Var_Design ) /* set_var_design */
426 #endif
427
428
429 static const FT_Service_TrueTypeEngineRec tt_service_truetype_engine =
430 {
431 #ifdef TT_USE_BYTECODE_INTERPRETER
432
433 FT_TRUETYPE_ENGINE_TYPE_PATENTED
434
435 #else /* !TT_USE_BYTECODE_INTERPRETER */
436
437 FT_TRUETYPE_ENGINE_TYPE_NONE
438
439 #endif /* TT_USE_BYTECODE_INTERPRETER */
440 };
441
442
443 FT_DEFINE_SERVICE_TTGLYFREC(
444 tt_service_truetype_glyf,
445 (TT_Glyf_GetLocationFunc)tt_face_get_location ) /* get_location */
446
447
448 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
449 FT_DEFINE_SERVICEDESCREC5(
450 tt_services,
451 FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE,
452 FT_SERVICE_ID_MULTI_MASTERS, &TT_SERVICE_GX_MULTI_MASTERS_GET,
453 FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine,
454 FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET,
455 FT_SERVICE_ID_PROPERTIES, &TT_SERVICE_PROPERTIES_GET )
456 #else
457 FT_DEFINE_SERVICEDESCREC4(
458 tt_services,
459 FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE,
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 #endif
464
465
466 FT_CALLBACK_DEF( FT_Module_Interface )
467 tt_get_interface( FT_Module driver, /* TT_Driver */
468 const char* tt_interface )
469 {
470 FT_Library library;
471 FT_Module_Interface result;
472 FT_Module sfntd;
473 SFNT_Service sfnt;
474
475
476 /* TT_SERVICES_GET dereferences `library' in PIC mode */
477 #ifdef FT_CONFIG_OPTION_PIC
478 if ( !driver )
479 return NULL;
480 library = driver->library;
481 if ( !library )
482 return NULL;
483 #endif
484
485 result = ft_service_list_lookup( TT_SERVICES_GET, tt_interface );
486 if ( result != NULL )
487 return result;
488
489 #ifndef FT_CONFIG_OPTION_PIC
490 if ( !driver )
491 return NULL;
492 library = driver->library;
493 if ( !library )
494 return NULL;
495 #endif
496
497 /* only return the default interface from the SFNT module */
498 sfntd = FT_Get_Module( library, "sfnt" );
499 if ( sfntd )
500 {
501 sfnt = (SFNT_Service)( sfntd->clazz->module_interface );
502 if ( sfnt )
503 return sfnt->get_interface( driver, tt_interface );
504 }
505
506 return 0;
507 }
508
509
510 /* The FT_DriverInterface structure is defined in ftdriver.h. */
511
512 #ifdef TT_USE_BYTECODE_INTERPRETER
513 #define TT_HINTER_FLAG FT_MODULE_DRIVER_HAS_HINTER
514 #else
515 #define TT_HINTER_FLAG 0
516 #endif
517
518 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
519 #define TT_SIZE_SELECT tt_size_select
520 #else
521 #define TT_SIZE_SELECT 0
522 #endif
523
524 FT_DEFINE_DRIVER(
525 tt_driver_class,
526
527 FT_MODULE_FONT_DRIVER |
528 FT_MODULE_DRIVER_SCALABLE |
529 TT_HINTER_FLAG,
530
531 sizeof ( TT_DriverRec ),
532
533 "truetype", /* driver name */
534 0x10000L, /* driver version == 1.0 */
535 0x20000L, /* driver requires FreeType 2.0 or above */
536
537 0, /* module-specific interface */
538
539 tt_driver_init, /* FT_Module_Constructor module_init */
540 tt_driver_done, /* FT_Module_Destructor module_done */
541 tt_get_interface, /* FT_Module_Requester get_interface */
542
543 sizeof ( TT_FaceRec ),
544 sizeof ( TT_SizeRec ),
545 sizeof ( FT_GlyphSlotRec ),
546
547 tt_face_init, /* FT_Face_InitFunc init_face */
548 tt_face_done, /* FT_Face_DoneFunc done_face */
549 tt_size_init, /* FT_Size_InitFunc init_size */
550 tt_size_done, /* FT_Size_DoneFunc done_size */
551 tt_slot_init, /* FT_Slot_InitFunc init_slot */
552 0, /* FT_Slot_DoneFunc done_slot */
553
554 tt_glyph_load, /* FT_Slot_LoadFunc load_glyph */
555
556 tt_get_kerning, /* FT_Face_GetKerningFunc get_kerning */
557 0, /* FT_Face_AttachFunc attach_file */
558 tt_get_advances, /* FT_Face_GetAdvancesFunc get_advances */
559
560 tt_size_request, /* FT_Size_RequestFunc request_size */
561 TT_SIZE_SELECT /* FT_Size_SelectFunc select_size */
562 )
563
564
565 /* END */