~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/3rdparty/freetype/src/cff/cffdrivr.c

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************/
 
2
/*                                                                         */
 
3
/*  cffdrivr.c                                                             */
 
4
/*                                                                         */
 
5
/*    OpenType font driver implementation (body).                          */
 
6
/*                                                                         */
 
7
/*  Copyright 1996-2001, 2002, 2003, 2004 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_FREETYPE_H
 
21
#include FT_INTERNAL_DEBUG_H
 
22
#include FT_INTERNAL_STREAM_H
 
23
#include FT_INTERNAL_SFNT_H
 
24
#include FT_TRUETYPE_IDS_H
 
25
#include FT_SERVICE_POSTSCRIPT_CMAPS_H
 
26
#include FT_SERVICE_POSTSCRIPT_INFO_H
 
27
#include FT_SERVICE_TT_CMAP_H
 
28
 
 
29
#include "cffdrivr.h"
 
30
#include "cffgload.h"
 
31
#include "cffload.h"
 
32
#include "cffcmap.h"
 
33
 
 
34
#include "cfferrs.h"
 
35
 
 
36
#include FT_SERVICE_XFREE86_NAME_H
 
37
#include FT_SERVICE_GLYPH_DICT_H
 
38
 
 
39
  /*************************************************************************/
 
40
  /*                                                                       */
 
41
  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
 
42
  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
 
43
  /* messages during execution.                                            */
 
44
  /*                                                                       */
 
45
#undef  FT_COMPONENT
 
46
#define FT_COMPONENT  trace_cffdriver
 
47
 
 
48
 
 
49
  /*************************************************************************/
 
50
  /*************************************************************************/
 
51
  /*************************************************************************/
 
52
  /****                                                                 ****/
 
53
  /****                                                                 ****/
 
54
  /****                          F A C E S                              ****/
 
55
  /****                                                                 ****/
 
56
  /****                                                                 ****/
 
57
  /*************************************************************************/
 
58
  /*************************************************************************/
 
59
  /*************************************************************************/
 
60
 
 
61
 
 
62
#undef  PAIR_TAG
 
63
#define PAIR_TAG( left, right )  ( ( (FT_ULong)left << 16 ) | \
 
64
                                     (FT_ULong)right        )
 
65
 
 
66
 
 
67
  /*************************************************************************/
 
68
  /*                                                                       */
 
69
  /* <Function>                                                            */
 
70
  /*    Get_Kerning                                                        */
 
71
  /*                                                                       */
 
72
  /* <Description>                                                         */
 
73
  /*    A driver method used to return the kerning vector between two      */
 
74
  /*    glyphs of the same face.                                           */
 
75
  /*                                                                       */
 
76
  /* <Input>                                                               */
 
77
  /*    face        :: A handle to the source face object.                 */
 
78
  /*                                                                       */
 
79
  /*    left_glyph  :: The index of the left glyph in the kern pair.       */
 
80
  /*                                                                       */
 
81
  /*    right_glyph :: The index of the right glyph in the kern pair.      */
 
82
  /*                                                                       */
 
83
  /* <Output>                                                              */
 
84
  /*    kerning     :: The kerning vector.  This is in font units for      */
 
85
  /*                   scalable formats, and in pixels for fixed-sizes     */
 
86
  /*                   formats.                                            */
 
87
  /*                                                                       */
 
88
  /* <Return>                                                              */
 
89
  /*    FreeType error code.  0 means success.                             */
 
90
  /*                                                                       */
 
91
  /* <Note>                                                                */
 
92
  /*    Only horizontal layouts (left-to-right & right-to-left) are        */
 
93
  /*    supported by this function.  Other layouts, or more sophisticated  */
 
94
  /*    kernings, are out of scope of this method (the basic driver        */
 
95
  /*    interface is meant to be simple).                                  */
 
96
  /*                                                                       */
 
97
  /*    They can be implemented by format-specific interfaces.             */
 
98
  /*                                                                       */
 
99
  FT_CALLBACK_DEF( FT_Error )
 
100
  Get_Kerning( FT_Face     ttface,          /* TT_Face */
 
101
               FT_UInt     left_glyph,
 
102
               FT_UInt     right_glyph,
 
103
               FT_Vector*  kerning )
 
104
  {
 
105
    TT_Face        face = (TT_Face)ttface;
 
106
    TT_Kern0_Pair  pair;
 
107
 
 
108
 
 
109
    if ( !face )
 
110
      return CFF_Err_Invalid_Face_Handle;
 
111
 
 
112
    kerning->x = 0;
 
113
    kerning->y = 0;
 
114
 
 
115
    if ( face->kern_pairs )
 
116
    {
 
117
      /* there are some kerning pairs in this font file! */
 
118
      FT_ULong  search_tag = PAIR_TAG( left_glyph, right_glyph );
 
119
      FT_Long   left, right;
 
120
 
 
121
 
 
122
      left  = 0;
 
123
      right = face->num_kern_pairs - 1;
 
124
 
 
125
      while ( left <= right )
 
126
      {
 
127
        FT_Long   middle = left + ( ( right - left ) >> 1 );
 
128
        FT_ULong  cur_pair;
 
129
 
 
130
 
 
131
        pair     = face->kern_pairs + middle;
 
132
        cur_pair = PAIR_TAG( pair->left, pair->right );
 
133
 
 
134
        if ( cur_pair == search_tag )
 
135
          goto Found;
 
136
 
 
137
        if ( cur_pair < search_tag )
 
138
          left = middle + 1;
 
139
        else
 
140
          right = middle - 1;
 
141
      }
 
142
    }
 
143
 
 
144
  Exit:
 
145
    return CFF_Err_Ok;
 
146
 
 
147
  Found:
 
148
    kerning->x = pair->value;
 
149
    goto Exit;
 
150
  }
 
151
 
 
152
 
 
153
#undef PAIR_TAG
 
154
 
 
155
 
 
156
  /*************************************************************************/
 
157
  /*                                                                       */
 
158
  /* <Function>                                                            */
 
159
  /*    Load_Glyph                                                         */
 
160
  /*                                                                       */
 
161
  /* <Description>                                                         */
 
162
  /*    A driver method used to load a glyph within a given glyph slot.    */
 
163
  /*                                                                       */
 
164
  /* <Input>                                                               */
 
165
  /*    slot        :: A handle to the target slot object where the glyph  */
 
166
  /*                   will be loaded.                                     */
 
167
  /*                                                                       */
 
168
  /*    size        :: A handle to the source face size at which the glyph */
 
169
  /*                   must be scaled, loaded, etc.                        */
 
170
  /*                                                                       */
 
171
  /*    glyph_index :: The index of the glyph in the font file.            */
 
172
  /*                                                                       */
 
173
  /*    load_flags  :: A flag indicating what to load for this glyph.  The */
 
174
  /*                   FT_LOAD_??? constants can be used to control the    */
 
175
  /*                   glyph loading process (e.g., whether the outline    */
 
176
  /*                   should be scaled, whether to load bitmaps or not,   */
 
177
  /*                   whether to hint the outline, etc).                  */
 
178
  /*                                                                       */
 
179
  /* <Return>                                                              */
 
180
  /*    FreeType error code.  0 means success.                             */
 
181
  /*                                                                       */
 
182
  FT_CALLBACK_DEF( FT_Error )
 
183
  Load_Glyph( FT_GlyphSlot  cffslot,        /* CFF_GlyphSlot */
 
184
              FT_Size       cffsize,        /* CFF_Size      */
 
185
              FT_UInt       glyph_index,
 
186
              FT_Int32      load_flags )
 
187
  {
 
188
    FT_Error  error;
 
189
    CFF_GlyphSlot  slot = (CFF_GlyphSlot)cffslot;
 
190
    CFF_Size       size = (CFF_Size)cffsize;
 
191
 
 
192
 
 
193
    if ( !slot )
 
194
      return CFF_Err_Invalid_Slot_Handle;
 
195
 
 
196
    /* check whether we want a scaled outline or bitmap */
 
197
    if ( !size )
 
198
      load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
 
199
 
 
200
    if ( load_flags & FT_LOAD_NO_SCALE )
 
201
      size = NULL;
 
202
 
 
203
    /* reset the size object if necessary */
 
204
    if ( size )
 
205
    {
 
206
      /* these two objects must have the same parent */
 
207
      if ( cffsize->face != cffslot->face )
 
208
        return CFF_Err_Invalid_Face_Handle;
 
209
    }
 
210
 
 
211
    /* now load the glyph outline if necessary */
 
212
    error = cff_slot_load( slot, size, glyph_index, load_flags );
 
213
 
 
214
    /* force drop-out mode to 2 - irrelevant now */
 
215
    /* slot->outline.dropout_mode = 2; */
 
216
 
 
217
    return error;
 
218
  }
 
219
 
 
220
 
 
221
 /*
 
222
  *  GLYPH DICT SERVICE
 
223
  *
 
224
  */
 
225
 
 
226
  static FT_Error
 
227
  cff_get_glyph_name( CFF_Face    face,
 
228
                      FT_UInt     glyph_index,
 
229
                      FT_Pointer  buffer,
 
230
                      FT_UInt     buffer_max )
 
231
  {
 
232
    CFF_Font            font   = (CFF_Font)face->extra.data;
 
233
    FT_Memory           memory = FT_FACE_MEMORY( face );
 
234
    FT_String*          gname;
 
235
    FT_UShort           sid;
 
236
    FT_Service_PsCMaps  psnames;
 
237
    FT_Error            error;
 
238
 
 
239
 
 
240
    FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
 
241
    if ( !psnames )
 
242
    {
 
243
      FT_ERROR(( "cff_get_glyph_name:" ));
 
244
      FT_ERROR(( " cannot get glyph name from CFF & CEF fonts\n" ));
 
245
      FT_ERROR(( "                   " ));
 
246
      FT_ERROR(( " without the `PSNames' module\n" ));
 
247
      error = CFF_Err_Unknown_File_Format;
 
248
      goto Exit;
 
249
    }
 
250
 
 
251
    /* first, locate the sid in the charset table */
 
252
    sid = font->charset.sids[glyph_index];
 
253
 
 
254
    /* now, lookup the name itself */
 
255
    gname = cff_index_get_sid_string( &font->string_index, sid, psnames );
 
256
 
 
257
    if ( gname && buffer_max > 0 )
 
258
    {
 
259
      FT_UInt  len = (FT_UInt)ft_strlen( gname );
 
260
 
 
261
 
 
262
      if ( len >= buffer_max )
 
263
        len = buffer_max - 1;
 
264
 
 
265
      FT_MEM_COPY( buffer, gname, len );
 
266
      ((FT_Byte*)buffer)[len] = 0;
 
267
    }
 
268
 
 
269
    FT_FREE( gname );
 
270
    error = CFF_Err_Ok;
 
271
 
 
272
    Exit:
 
273
      return error;
 
274
  }
 
275
 
 
276
 
 
277
  static FT_UInt
 
278
  cff_get_name_index( CFF_Face    face,
 
279
                      FT_String*  glyph_name )
 
280
  {
 
281
    CFF_Font            cff;
 
282
    CFF_Charset         charset;
 
283
    FT_Service_PsCMaps  psnames;
 
284
    FT_Memory           memory = FT_FACE_MEMORY( face );
 
285
    FT_String*          name;
 
286
    FT_UShort           sid;
 
287
    FT_UInt             i;
 
288
    FT_Int              result;
 
289
 
 
290
 
 
291
    cff     = (CFF_FontRec *)face->extra.data;
 
292
    charset = &cff->charset;
 
293
 
 
294
    FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
 
295
    if ( !psnames )
 
296
      return 0;
 
297
 
 
298
    for ( i = 0; i < cff->num_glyphs; i++ )
 
299
    {
 
300
      sid = charset->sids[i];
 
301
 
 
302
      if ( sid > 390 )
 
303
        name = cff_index_get_name( &cff->string_index, sid - 391 );
 
304
      else
 
305
        name = (FT_String *)psnames->adobe_std_strings( sid );
 
306
 
 
307
      result = ft_strcmp( glyph_name, name );
 
308
 
 
309
      if ( sid > 390 )
 
310
        FT_FREE( name );
 
311
 
 
312
      if ( !result )
 
313
        return i;
 
314
    }
 
315
 
 
316
    return 0;
 
317
  }
 
318
 
 
319
 
 
320
  static const FT_Service_GlyphDictRec  cff_service_glyph_dict =
 
321
  {
 
322
    (FT_GlyphDict_GetNameFunc)  cff_get_glyph_name,
 
323
    (FT_GlyphDict_NameIndexFunc)cff_get_name_index,
 
324
  };
 
325
 
 
326
 
 
327
 /*
 
328
  *  POSTSCRIPT INFO SERVICE
 
329
  *
 
330
  */
 
331
 
 
332
  static FT_Int
 
333
  cff_ps_has_glyph_names( FT_Face  face )
 
334
  {
 
335
    return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0;
 
336
  }
 
337
 
 
338
 
 
339
  static const FT_Service_PsInfoRec  cff_service_ps_info =
 
340
  {
 
341
    (PS_GetFontInfoFunc)  NULL,         /* unsupported with CFF fonts */
 
342
    (PS_HasGlyphNamesFunc)cff_ps_has_glyph_names
 
343
  };
 
344
 
 
345
 
 
346
  /*
 
347
   * TT CMAP INFO
 
348
   *
 
349
   * If the charmap is a synthetic Unicode encoding cmap or 
 
350
   * a Type 1 standard (or expert) encoding cmap, hide TT CMAP INFO 
 
351
   * service defined in SFNT module.
 
352
   *
 
353
   * Otherwise call the service function in the sfnt module.
 
354
   *
 
355
   */
 
356
  static FT_Error
 
357
  cff_get_cmap_info( FT_CharMap    charmap,
 
358
                     TT_CMapInfo  *cmap_info )
 
359
  {
 
360
    FT_CMap   cmap  = FT_CMAP( charmap );
 
361
    FT_Error  error = CFF_Err_Ok;
 
362
 
 
363
 
 
364
    cmap_info->language = 0;
 
365
 
 
366
    if ( cmap->clazz != &cff_cmap_encoding_class_rec && 
 
367
         cmap->clazz != &cff_cmap_unicode_class_rec  )
 
368
    {
 
369
      FT_Face             face    = FT_CMAP_FACE( cmap );
 
370
      FT_Library          library = FT_FACE_LIBRARY( face );
 
371
      FT_Module           sfnt    = FT_Get_Module( library, "sfnt" );
 
372
      FT_Service_TTCMaps  service =
 
373
        (FT_Service_TTCMaps)ft_module_get_service( sfnt,
 
374
                                                   FT_SERVICE_ID_TT_CMAP );
 
375
 
 
376
 
 
377
      if ( service && service->get_cmap_info )
 
378
        error = service->get_cmap_info( charmap, cmap_info );
 
379
    }
 
380
 
 
381
    return error;
 
382
  }
 
383
 
 
384
 
 
385
  static const FT_Service_TTCMapsRec  cff_service_get_cmap_info =
 
386
  {
 
387
    (TT_CMap_Info_GetFunc)cff_get_cmap_info
 
388
  };
 
389
 
 
390
 
 
391
  /*************************************************************************/
 
392
  /*************************************************************************/
 
393
  /*************************************************************************/
 
394
  /****                                                                 ****/
 
395
  /****                                                                 ****/
 
396
  /****                D R I V E R  I N T E R F A C E                   ****/
 
397
  /****                                                                 ****/
 
398
  /****                                                                 ****/
 
399
  /*************************************************************************/
 
400
  /*************************************************************************/
 
401
  /*************************************************************************/
 
402
 
 
403
  static const FT_ServiceDescRec  cff_services[] =
 
404
  {
 
405
    { FT_SERVICE_ID_XF86_NAME,       FT_XF86_FORMAT_CFF },
 
406
    { FT_SERVICE_ID_POSTSCRIPT_INFO, &cff_service_ps_info },
 
407
#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
 
408
    { FT_SERVICE_ID_GLYPH_DICT,      &cff_service_glyph_dict },
 
409
#endif
 
410
    { FT_SERVICE_ID_TT_CMAP,         &cff_service_get_cmap_info },
 
411
    { NULL, NULL }
 
412
  };
 
413
 
 
414
 
 
415
  FT_CALLBACK_DEF( FT_Module_Interface )
 
416
  cff_get_interface( FT_Module    driver,       /* CFF_Driver */
 
417
                     const char*  module_interface )
 
418
  {
 
419
    FT_Module            sfnt;
 
420
    FT_Module_Interface  result;
 
421
 
 
422
 
 
423
    result = ft_service_list_lookup( cff_services, module_interface );
 
424
    if ( result != NULL )
 
425
      return  result;
 
426
 
 
427
    /* we pass our request to the `sfnt' module */
 
428
    sfnt = FT_Get_Module( driver->library, "sfnt" );
 
429
 
 
430
    return sfnt ? sfnt->clazz->get_interface( sfnt, module_interface ) : 0;
 
431
  }
 
432
 
 
433
 
 
434
  /* The FT_DriverInterface structure is defined in ftdriver.h. */
 
435
 
 
436
  FT_CALLBACK_TABLE_DEF
 
437
  const FT_Driver_ClassRec  cff_driver_class =
 
438
  {
 
439
    /* begin with the FT_Module_Class fields */
 
440
    {
 
441
      FT_MODULE_FONT_DRIVER       |
 
442
      FT_MODULE_DRIVER_SCALABLE   |
 
443
      FT_MODULE_DRIVER_HAS_HINTER,
 
444
 
 
445
      sizeof( CFF_DriverRec ),
 
446
      "cff",
 
447
      0x10000L,
 
448
      0x20000L,
 
449
 
 
450
      0,   /* module-specific interface */
 
451
 
 
452
      cff_driver_init,
 
453
      cff_driver_done,
 
454
      cff_get_interface,
 
455
    },
 
456
 
 
457
    /* now the specific driver fields */
 
458
    sizeof( TT_FaceRec ),
 
459
    sizeof( CFF_SizeRec ),
 
460
    sizeof( CFF_GlyphSlotRec ),
 
461
 
 
462
    cff_face_init,
 
463
    cff_face_done,
 
464
    cff_size_init,
 
465
    cff_size_done,
 
466
    cff_slot_init,
 
467
    cff_slot_done,
 
468
 
 
469
    cff_point_size_reset,
 
470
    cff_size_reset,
 
471
 
 
472
    Load_Glyph,
 
473
 
 
474
    Get_Kerning,
 
475
    0,                      /* FT_Face_AttachFunc      */
 
476
    0                       /* FT_Face_GetAdvancesFunc */
 
477
  };
 
478
 
 
479
 
 
480
/* END */