1/***************************************************************************/
2/*                                                                         */
3/*  ttdriver.c                                                             */
4/*                                                                         */
5/*    TrueType font driver implementation (body).                          */
6/*                                                                         */
7/*  Copyright 1996-2015 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,
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  /*************************************************************************/
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  /****                           S I Z E S                             ****/
237  /****                                                                 ****/
238  /****                                                                 ****/
239  /*************************************************************************/
240  /*************************************************************************/
241  /*************************************************************************/
242
243
244#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
245
246  static FT_Error
247  tt_size_select( FT_Size   size,
248                  FT_ULong  strike_index )
249  {
250    TT_Face   ttface = (TT_Face)size->face;
251    TT_Size   ttsize = (TT_Size)size;
252    FT_Error  error  = FT_Err_Ok;
253
254
255    ttsize->strike_index = strike_index;
256
257    if ( FT_IS_SCALABLE( size->face ) )
258    {
259      /* use the scaled metrics, even when tt_size_reset fails */
260      FT_Select_Metrics( size->face, strike_index );
261
262      tt_size_reset( ttsize ); /* ignore return value */
263    }
264    else
265    {
266      SFNT_Service      sfnt    = (SFNT_Service) ttface->sfnt;
267      FT_Size_Metrics*  metrics = &size->metrics;
268
269
270      error = sfnt->load_strike_metrics( ttface, strike_index, metrics );
271      if ( error )
272        ttsize->strike_index = 0xFFFFFFFFUL;
273    }
274
275    return error;
276  }
277
278#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
279
280
281  static FT_Error
282  tt_size_request( FT_Size          size,
283                   FT_Size_Request  req )
284  {
285    TT_Size   ttsize = (TT_Size)size;
286    FT_Error  error  = FT_Err_Ok;
287
288
289#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
290
291    if ( FT_HAS_FIXED_SIZES( size->face ) )
292    {
293      TT_Face       ttface = (TT_Face)size->face;
294      SFNT_Service  sfnt   = (SFNT_Service) ttface->sfnt;
295      FT_ULong      strike_index;
296
297
298      error = sfnt->set_sbit_strike( ttface, req, &strike_index );
299
300      if ( error )
301        ttsize->strike_index = 0xFFFFFFFFUL;
302      else
303        return tt_size_select( size, strike_index );
304    }
305
306#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
307
308    FT_Request_Metrics( size->face, req );
309
310    if ( FT_IS_SCALABLE( size->face ) )
311    {
312      error = tt_size_reset( ttsize );
313      ttsize->root.metrics = ttsize->metrics;
314    }
315
316    return error;
317  }
318
319
320  /*************************************************************************/
321  /*                                                                       */
322  /* <Function>                                                            */
323  /*    tt_glyph_load                                                      */
324  /*                                                                       */
325  /* <Description>                                                         */
326  /*    A driver method used to load a glyph within a given glyph slot.    */
327  /*                                                                       */
328  /* <Input>                                                               */
329  /*    slot        :: A handle to the target slot object where the glyph  */
330  /*                   will be loaded.                                     */
331  /*                                                                       */
332  /*    size        :: A handle to the source face size at which the glyph */
333  /*                   must be scaled, loaded, etc.                        */
334  /*                                                                       */
335  /*    glyph_index :: The index of the glyph in the font file.            */
336  /*                                                                       */
337  /*    load_flags  :: A flag indicating what to load for this glyph.  The */
338  /*                   FT_LOAD_XXX constants can be used to control the    */
339  /*                   glyph loading process (e.g., whether the outline    */
340  /*                   should be scaled, whether to load bitmaps or not,   */
341  /*                   whether to hint the outline, etc).                  */
342  /*                                                                       */
343  /* <Return>                                                              */
344  /*    FreeType error code.  0 means success.                             */
345  /*                                                                       */
346  static FT_Error
347  tt_glyph_load( FT_GlyphSlot  ttslot,      /* TT_GlyphSlot */
348                 FT_Size       ttsize,      /* TT_Size      */
349                 FT_UInt       glyph_index,
350                 FT_Int32      load_flags )
351  {
352    TT_GlyphSlot  slot = (TT_GlyphSlot)ttslot;
353    TT_Size       size = (TT_Size)ttsize;
354    FT_Face       face = ttslot->face;
355    FT_Error      error;
356
357
358    if ( !slot )
359      return FT_THROW( Invalid_Slot_Handle );
360
361    if ( !size )
362      return FT_THROW( Invalid_Size_Handle );
363
364    if ( !face )
365      return FT_THROW( Invalid_Face_Handle );
366
367#ifdef FT_CONFIG_OPTION_INCREMENTAL
368    if ( glyph_index >= (FT_UInt)face->num_glyphs &&
369         !face->internal->incremental_interface   )
370#else
371    if ( glyph_index >= (FT_UInt)face->num_glyphs )
372#endif
373      return FT_THROW( Invalid_Argument );
374
375    if ( load_flags & FT_LOAD_NO_HINTING )
376    {
377      /* both FT_LOAD_NO_HINTING and FT_LOAD_NO_AUTOHINT   */
378      /* are necessary to disable hinting for tricky fonts */
379
380      if ( FT_IS_TRICKY( face ) )
381        load_flags &= ~FT_LOAD_NO_HINTING;
382
383      if ( load_flags & FT_LOAD_NO_AUTOHINT )
384        load_flags |= FT_LOAD_NO_HINTING;
385    }
386
387    if ( load_flags & ( FT_LOAD_NO_RECURSE | FT_LOAD_NO_SCALE ) )
388    {
389      load_flags |= FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE;
390
391      if ( !FT_IS_TRICKY( face ) )
392        load_flags |= FT_LOAD_NO_HINTING;
393    }
394
395    /* now load the glyph outline if necessary */
396    error = TT_Load_Glyph( size, slot, glyph_index, load_flags );
397
398    /* force drop-out mode to 2 - irrelevant now */
399    /* slot->outline.dropout_mode = 2; */
400
401    return error;
402  }
403
404
405  /*************************************************************************/
406  /*************************************************************************/
407  /*************************************************************************/
408  /****                                                                 ****/
409  /****                                                                 ****/
410  /****                D R I V E R  I N T E R F A C E                   ****/
411  /****                                                                 ****/
412  /****                                                                 ****/
413  /*************************************************************************/
414  /*************************************************************************/
415  /*************************************************************************/
416
417#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
418  FT_DEFINE_SERVICE_MULTIMASTERSREC(
419    tt_service_gx_multi_masters,
420    (FT_Get_MM_Func)        NULL,
421    (FT_Set_MM_Design_Func) NULL,
422    (FT_Set_MM_Blend_Func)  TT_Set_MM_Blend,
423    (FT_Get_MM_Var_Func)    TT_Get_MM_Var,
424    (FT_Set_Var_Design_Func)TT_Set_Var_Design )
425#endif
426
427  static const FT_Service_TrueTypeEngineRec  tt_service_truetype_engine =
428  {
429#ifdef TT_USE_BYTECODE_INTERPRETER
430
431#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
432    FT_TRUETYPE_ENGINE_TYPE_UNPATENTED
433#else
434    FT_TRUETYPE_ENGINE_TYPE_PATENTED
435#endif
436
437#else /* !TT_USE_BYTECODE_INTERPRETER */
438
439    FT_TRUETYPE_ENGINE_TYPE_NONE
440
441#endif /* TT_USE_BYTECODE_INTERPRETER */
442  };
443
444  FT_DEFINE_SERVICE_TTGLYFREC(
445    tt_service_truetype_glyf,
446    (TT_Glyf_GetLocationFunc)tt_face_get_location )
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      (void*)0,        /* driver specific interface */
538
539      tt_driver_init,
540      tt_driver_done,
541      tt_get_interface,
542
543    sizeof ( TT_FaceRec ),
544    sizeof ( TT_SizeRec ),
545    sizeof ( FT_GlyphSlotRec ),
546
547    tt_face_init,
548    tt_face_done,
549    tt_size_init,
550    tt_size_done,
551    tt_slot_init,
552    0,                       /* FT_Slot_DoneFunc */
553
554    tt_glyph_load,
555
556    tt_get_kerning,
557    0,                       /* FT_Face_AttachFunc */
558    tt_get_advances,
559
560    tt_size_request,
561    TT_SIZE_SELECT
562  )
563
564
565/* END */
566