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 <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#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  /* <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",      /* 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 */
573