Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
/***************************************************************************/
2
/*                                                                         */
3
/*  sfdriver.c                                                             */
4
/*                                                                         */
5
/*    High-level SFNT driver interface (body).                             */
6
/*                                                                         */
7
/*  Copyright 1996-2007, 2009-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_SFNT_H
22
#include FT_INTERNAL_OBJECTS_H
23
 
24
#include "sfdriver.h"
25
#include "ttload.h"
26
#include "sfobjs.h"
27
#include "sfntpic.h"
28
 
29
#include "sferrors.h"
30
 
31
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
32
#include "ttsbit.h"
33
#endif
34
 
35
#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
36
#include "ttpost.h"
37
#endif
38
 
39
#ifdef TT_CONFIG_OPTION_BDF
40
#include "ttbdf.h"
41
#include FT_SERVICE_BDF_H
42
#endif
43
 
44
#include "ttcmap.h"
45
#include "ttkern.h"
46
#include "ttmtx.h"
47
 
48
#include FT_SERVICE_GLYPH_DICT_H
49
#include FT_SERVICE_POSTSCRIPT_NAME_H
50
#include FT_SERVICE_SFNT_H
51
#include FT_SERVICE_TT_CMAP_H
52
 
53
 
54
  /*************************************************************************/
55
  /*                                                                       */
56
  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
57
  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
58
  /* messages during execution.                                            */
59
  /*                                                                       */
60
#undef  FT_COMPONENT
61
#define FT_COMPONENT  trace_sfdriver
62
 
63
 
64
  /*
65
   *  SFNT TABLE SERVICE
66
   *
67
   */
68
 
69
  static void*
70
  get_sfnt_table( TT_Face      face,
71
                  FT_Sfnt_Tag  tag )
72
  {
73
    void*  table;
74
 
75
 
76
    switch ( tag )
77
    {
78
    case ft_sfnt_head:
79
      table = &face->header;
80
      break;
81
 
82
    case ft_sfnt_hhea:
83
      table = &face->horizontal;
84
      break;
85
 
86
    case ft_sfnt_vhea:
87
      table = face->vertical_info ? &face->vertical : 0;
88
      break;
89
 
90
    case ft_sfnt_os2:
91
      table = face->os2.version == 0xFFFFU ? 0 : &face->os2;
92
      break;
93
 
94
    case ft_sfnt_post:
95
      table = &face->postscript;
96
      break;
97
 
98
    case ft_sfnt_maxp:
99
      table = &face->max_profile;
100
      break;
101
 
102
    case ft_sfnt_pclt:
103
      table = face->pclt.Version ? &face->pclt : 0;
104
      break;
105
 
106
    default:
107
      table = 0;
108
    }
109
 
110
    return table;
111
  }
112
 
113
 
114
  static FT_Error
115
  sfnt_table_info( TT_Face    face,
116
                   FT_UInt    idx,
117
                   FT_ULong  *tag,
118
                   FT_ULong  *offset,
119
                   FT_ULong  *length )
120
  {
121
    if ( !offset || !length )
122
      return FT_THROW( Invalid_Argument );
123
 
124
    if ( !tag )
125
      *length = face->num_tables;
126
    else
127
    {
128
      if ( idx >= face->num_tables )
129
        return FT_THROW( Table_Missing );
130
 
131
      *tag    = face->dir_tables[idx].Tag;
132
      *offset = face->dir_tables[idx].Offset;
133
      *length = face->dir_tables[idx].Length;
134
    }
135
 
136
    return FT_Err_Ok;
137
  }
138
 
139
 
140
  FT_DEFINE_SERVICE_SFNT_TABLEREC(
141
    sfnt_service_sfnt_table,
142
    (FT_SFNT_TableLoadFunc)tt_face_load_any,
143
    (FT_SFNT_TableGetFunc) get_sfnt_table,
144
    (FT_SFNT_TableInfoFunc)sfnt_table_info )
145
 
146
 
147
#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
148
 
149
  /*
150
   *  GLYPH DICT SERVICE
151
   *
152
   */
153
 
154
  static FT_Error
155
  sfnt_get_glyph_name( TT_Face     face,
156
                       FT_UInt     glyph_index,
157
                       FT_Pointer  buffer,
158
                       FT_UInt     buffer_max )
159
  {
160
    FT_String*  gname;
161
    FT_Error    error;
162
 
163
 
164
    error = tt_face_get_ps_name( face, glyph_index, &gname );
165
    if ( !error )
166
      FT_STRCPYN( buffer, gname, buffer_max );
167
 
168
    return error;
169
  }
170
 
171
 
172
  static FT_UInt
173
  sfnt_get_name_index( TT_Face     face,
174
                       FT_String*  glyph_name )
175
  {
176
    FT_Face  root = &face->root;
177
 
178
    FT_UInt  i, max_gid = FT_UINT_MAX;
179
 
180
 
181
    if ( root->num_glyphs < 0 )
182
      return 0;
183
    else if ( (FT_ULong)root->num_glyphs < FT_UINT_MAX )
184
      max_gid = (FT_UInt)root->num_glyphs;
185
    else
186
      FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n",
187
                  FT_UINT_MAX, root->num_glyphs ));
188
 
189
    for ( i = 0; i < max_gid; i++ )
190
    {
191
      FT_String*  gname;
192
      FT_Error    error = tt_face_get_ps_name( face, i, &gname );
193
 
194
 
195
      if ( error )
196
        continue;
197
 
198
      if ( !ft_strcmp( glyph_name, gname ) )
199
        return i;
200
    }
201
 
202
    return 0;
203
  }
204
 
205
 
206
  FT_DEFINE_SERVICE_GLYPHDICTREC(
207
    sfnt_service_glyph_dict,
208
    (FT_GlyphDict_GetNameFunc)  sfnt_get_glyph_name,
209
    (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index )
210
 
211
 
212
#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
213
 
214
 
215
  /*
216
   *  POSTSCRIPT NAME SERVICE
217
   *
218
   */
219
 
220
  static const char*
221
  sfnt_get_ps_name( TT_Face  face )
222
  {
223
    FT_Int       n, found_win, found_apple;
224
    const char*  result = NULL;
225
 
226
 
227
    /* shouldn't happen, but just in case to avoid memory leaks */
228
    if ( face->postscript_name )
229
      return face->postscript_name;
230
 
231
    /* scan the name table to see whether we have a Postscript name here, */
232
    /* either in Macintosh or Windows platform encodings                  */
233
    found_win   = -1;
234
    found_apple = -1;
235
 
236
    for ( n = 0; n < face->num_names; n++ )
237
    {
238
      TT_NameEntryRec*  name = face->name_table.names + n;
239
 
240
 
241
      if ( name->nameID == 6 && name->stringLength > 0 )
242
      {
243
        if ( name->platformID == 3     &&
244
             name->encodingID == 1     &&
245
             name->languageID == 0x409 )
246
          found_win = n;
247
 
248
        if ( name->platformID == 1 &&
249
             name->encodingID == 0 &&
250
             name->languageID == 0 )
251
          found_apple = n;
252
      }
253
    }
254
 
255
    if ( found_win != -1 )
256
    {
257
      FT_Memory         memory = face->root.memory;
258
      TT_NameEntryRec*  name   = face->name_table.names + found_win;
259
      FT_UInt           len    = name->stringLength / 2;
260
      FT_Error          error  = FT_Err_Ok;
261
 
262
      FT_UNUSED( error );
263
 
264
 
265
      if ( !FT_ALLOC( result, name->stringLength + 1 ) )
266
      {
267
        FT_Stream   stream = face->name_table.stream;
268
        FT_String*  r      = (FT_String*)result;
269
        FT_Byte*    p      = (FT_Byte*)name->string;
270
 
271
 
272
        if ( FT_STREAM_SEEK( name->stringOffset ) ||
273
             FT_FRAME_ENTER( name->stringLength ) )
274
        {
275
          FT_FREE( result );
276
          name->stringLength = 0;
277
          name->stringOffset = 0;
278
          FT_FREE( name->string );
279
 
280
          goto Exit;
281
        }
282
 
283
        p = (FT_Byte*)stream->cursor;
284
 
285
        for ( ; len > 0; len--, p += 2 )
286
        {
287
          if ( p[0] == 0 && p[1] >= 32 && p[1] < 128 )
288
            *r++ = p[1];
289
        }
290
        *r = '\0';
291
 
292
        FT_FRAME_EXIT();
293
      }
294
      goto Exit;
295
    }
296
 
297
    if ( found_apple != -1 )
298
    {
299
      FT_Memory         memory = face->root.memory;
300
      TT_NameEntryRec*  name   = face->name_table.names + found_apple;
301
      FT_UInt           len    = name->stringLength;
302
      FT_Error          error  = FT_Err_Ok;
303
 
304
      FT_UNUSED( error );
305
 
306
 
307
      if ( !FT_ALLOC( result, len + 1 ) )
308
      {
309
        FT_Stream  stream = face->name_table.stream;
310
 
311
 
312
        if ( FT_STREAM_SEEK( name->stringOffset ) ||
313
             FT_STREAM_READ( result, len )        )
314
        {
315
          name->stringOffset = 0;
316
          name->stringLength = 0;
317
          FT_FREE( name->string );
318
          FT_FREE( result );
319
          goto Exit;
320
        }
321
        ((char*)result)[len] = '\0';
322
      }
323
    }
324
 
325
  Exit:
326
    face->postscript_name = result;
327
    return result;
328
  }
329
 
330
 
331
  FT_DEFINE_SERVICE_PSFONTNAMEREC(
332
    sfnt_service_ps_name,
333
    (FT_PsName_GetFunc)sfnt_get_ps_name )
334
 
335
 
336
  /*
337
   *  TT CMAP INFO
338
   */
339
  FT_DEFINE_SERVICE_TTCMAPSREC(
340
    tt_service_get_cmap_info,
341
    (TT_CMap_Info_GetFunc)tt_get_cmap_info )
342
 
343
 
344
#ifdef TT_CONFIG_OPTION_BDF
345
 
346
  static FT_Error
347
  sfnt_get_charset_id( TT_Face       face,
348
                       const char*  *acharset_encoding,
349
                       const char*  *acharset_registry )
350
  {
351
    BDF_PropertyRec  encoding, registry;
352
    FT_Error         error;
353
 
354
 
355
    /* XXX: I don't know whether this is correct, since
356
     *      tt_face_find_bdf_prop only returns something correct if we have
357
     *      previously selected a size that is listed in the BDF table.
358
     *      Should we change the BDF table format to include single offsets
359
     *      for `CHARSET_REGISTRY' and `CHARSET_ENCODING'?
360
     */
361
    error = tt_face_find_bdf_prop( face, "CHARSET_REGISTRY", ®istry );
362
    if ( !error )
363
    {
364
      error = tt_face_find_bdf_prop( face, "CHARSET_ENCODING", &encoding );
365
      if ( !error )
366
      {
367
        if ( registry.type == BDF_PROPERTY_TYPE_ATOM &&
368
             encoding.type == BDF_PROPERTY_TYPE_ATOM )
369
        {
370
          *acharset_encoding = encoding.u.atom;
371
          *acharset_registry = registry.u.atom;
372
        }
373
        else
374
          error = FT_THROW( Invalid_Argument );
375
      }
376
    }
377
 
378
    return error;
379
  }
380
 
381
 
382
  FT_DEFINE_SERVICE_BDFRec(
383
    sfnt_service_bdf,
384
    (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id,
385
    (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop )
386
 
387
 
388
#endif /* TT_CONFIG_OPTION_BDF */
389
 
390
 
391
  /*
392
   *  SERVICE LIST
393
   */
394
 
395
#if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF
396
  FT_DEFINE_SERVICEDESCREC5(
397
    sfnt_services,
398
    FT_SERVICE_ID_SFNT_TABLE,           &SFNT_SERVICE_SFNT_TABLE_GET,
399
    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET,
400
    FT_SERVICE_ID_GLYPH_DICT,           &SFNT_SERVICE_GLYPH_DICT_GET,
401
    FT_SERVICE_ID_BDF,                  &SFNT_SERVICE_BDF_GET,
402
    FT_SERVICE_ID_TT_CMAP,              &TT_SERVICE_CMAP_INFO_GET )
403
#elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES
404
  FT_DEFINE_SERVICEDESCREC4(
405
    sfnt_services,
406
    FT_SERVICE_ID_SFNT_TABLE,           &SFNT_SERVICE_SFNT_TABLE_GET,
407
    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET,
408
    FT_SERVICE_ID_GLYPH_DICT,           &SFNT_SERVICE_GLYPH_DICT_GET,
409
    FT_SERVICE_ID_TT_CMAP,              &TT_SERVICE_CMAP_INFO_GET )
410
#elif defined TT_CONFIG_OPTION_BDF
411
  FT_DEFINE_SERVICEDESCREC4(
412
    sfnt_services,
413
    FT_SERVICE_ID_SFNT_TABLE,           &SFNT_SERVICE_SFNT_TABLE_GET,
414
    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET,
415
    FT_SERVICE_ID_BDF,                  &SFNT_SERVICE_BDF_GET,
416
    FT_SERVICE_ID_TT_CMAP,              &TT_SERVICE_CMAP_INFO_GET )
417
#else
418
  FT_DEFINE_SERVICEDESCREC3(
419
    sfnt_services,
420
    FT_SERVICE_ID_SFNT_TABLE,           &SFNT_SERVICE_SFNT_TABLE_GET,
421
    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET,
422
    FT_SERVICE_ID_TT_CMAP,              &TT_SERVICE_CMAP_INFO_GET )
423
#endif
424
 
425
 
426
  FT_CALLBACK_DEF( FT_Module_Interface )
427
  sfnt_get_interface( FT_Module    module,
428
                      const char*  module_interface )
429
  {
430
    /* SFNT_SERVICES_GET derefers `library' in PIC mode */
431
#ifdef FT_CONFIG_OPTION_PIC
432
    FT_Library  library;
433
 
434
 
435
    if ( !module )
436
      return NULL;
437
    library = module->library;
438
    if ( !library )
439
      return NULL;
440
#else
441
    FT_UNUSED( module );
442
#endif
443
 
444
    return ft_service_list_lookup( SFNT_SERVICES_GET, module_interface );
445
  }
446
 
447
 
448
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
449
#define PUT_EMBEDDED_BITMAPS( a )  a
450
#else
451
#define PUT_EMBEDDED_BITMAPS( a )  NULL
452
#endif
453
 
454
#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
455
#define PUT_PS_NAMES( a )  a
456
#else
457
#define PUT_PS_NAMES( a )  NULL
458
#endif
459
 
460
  FT_DEFINE_SFNT_INTERFACE(
461
    sfnt_interface,
462
    tt_face_goto_table,
463
 
464
    sfnt_init_face,
465
    sfnt_load_face,
466
    sfnt_done_face,
467
    sfnt_get_interface,
468
 
469
    tt_face_load_any,
470
 
471
    tt_face_load_head,
472
    tt_face_load_hhea,
473
    tt_face_load_cmap,
474
    tt_face_load_maxp,
475
    tt_face_load_os2,
476
    tt_face_load_post,
477
 
478
    tt_face_load_name,
479
    tt_face_free_name,
480
 
481
    tt_face_load_kern,
482
    tt_face_load_gasp,
483
    tt_face_load_pclt,
484
 
485
    /* see `ttload.h' */
486
    PUT_EMBEDDED_BITMAPS( tt_face_load_bhed ),
487
 
488
    PUT_EMBEDDED_BITMAPS( tt_face_load_sbit_image ),
489
 
490
    /* see `ttpost.h' */
491
    PUT_PS_NAMES( tt_face_get_ps_name   ),
492
    PUT_PS_NAMES( tt_face_free_ps_names ),
493
 
494
    /* since version 2.1.8 */
495
    tt_face_get_kerning,
496
 
497
    /* since version 2.2 */
498
    tt_face_load_font_dir,
499
    tt_face_load_hmtx,
500
 
501
    /* see `ttsbit.h' and `sfnt.h' */
502
    PUT_EMBEDDED_BITMAPS( tt_face_load_eblc ),
503
    PUT_EMBEDDED_BITMAPS( tt_face_free_eblc ),
504
 
505
    PUT_EMBEDDED_BITMAPS( tt_face_set_sbit_strike     ),
506
    PUT_EMBEDDED_BITMAPS( tt_face_load_strike_metrics ),
507
 
508
    tt_face_get_metrics
509
  )
510
 
511
 
512
  FT_DEFINE_MODULE(
513
    sfnt_module_class,
514
 
515
    0,  /* not a font driver or renderer */
516
    sizeof ( FT_ModuleRec ),
517
 
518
    "sfnt",     /* driver name                            */
519
    0x10000L,   /* driver version 1.0                     */
520
    0x20000L,   /* driver requires FreeType 2.0 or higher */
521
 
522
    (const void*)&SFNT_INTERFACE_GET,  /* module specific interface */
523
 
524
    (FT_Module_Constructor)0,
525
    (FT_Module_Destructor) 0,
526
    (FT_Module_Requester)  sfnt_get_interface )
527
 
528
 
529
/* END */