Subversion Repositories Kolibri OS

Rev

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 */