cffdrivr.c revision ee451cb395940862dad63c85adfe8f2fd55e864c
1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  cffdrivr.c                                                             */
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*    OpenType font driver implementation (body).                          */
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  Copyright 1996-2013 by                                                 */
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  This file is part of the FreeType project, and may only be used,       */
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  modified, and distributed under the terms of the FreeType project      */
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  this file you indicate that you have read the license and              */
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*  understand and accept it fully.                                        */
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*                                                                         */
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/ft2build.h"
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/freetype.h"
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftdebug.h"
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftstream.h"
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/sfnt.h"
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/services/svcid.h"
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/services/svpsinfo.h"
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/services/svpostnm.h"
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/services/svttcmap.h"
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "cffdrivr.h"
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "cffgload.h"
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "cffload.h"
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "cffcmap.h"
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "cffparse.h"
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "cfferrs.h"
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "cffpic.h"
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/services/svxf86nm.h"
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/services/svgldict.h"
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/services/svprop.h"
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/ftcffdrv.h"
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* messages during execution.                                            */
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef  FT_COMPONENT
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_COMPONENT  trace_cffdriver
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /****                                                                 ****/
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /****                                                                 ****/
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /****                          F A C E S                              ****/
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /****                                                                 ****/
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /****                                                                 ****/
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef  PAIR_TAG
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define PAIR_TAG( left, right )  ( ( (FT_ULong)left << 16 ) | \
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                     (FT_ULong)right        )
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* <Function>                                                            */
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    cff_get_kerning                                                    */
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* <Description>                                                         */
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    A driver method used to return the kerning vector between two      */
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    glyphs of the same face.                                           */
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* <Input>                                                               */
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    face        :: A handle to the source face object.                 */
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    left_glyph  :: The index of the left glyph in the kern pair.       */
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    right_glyph :: The index of the right glyph in the kern pair.      */
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* <Output>                                                              */
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    kerning     :: The kerning vector.  This is in font units for      */
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                   scalable formats, and in pixels for fixed-sizes     */
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                   formats.                                            */
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* <Return>                                                              */
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    FreeType error code.  0 means success.                             */
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* <Note>                                                                */
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    Only horizontal layouts (left-to-right & right-to-left) are        */
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    supported by this function.  Other layouts, or more sophisticated  */
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    kernings, are out of scope of this method (the basic driver        */
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    interface is meant to be simple).                                  */
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    They can be implemented by format-specific interfaces.             */
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_CALLBACK_DEF( FT_Error )
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  cff_get_kerning( FT_Face     ttface,          /* TT_Face */
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                   FT_UInt     left_glyph,
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                   FT_UInt     right_glyph,
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                   FT_Vector*  kerning )
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TT_Face       face = (TT_Face)ttface;
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    kerning->x = 0;
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    kerning->y = 0;
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( sfnt )
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph );
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FT_Err_Ok;
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef PAIR_TAG
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* <Function>                                                            */
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    cff_glyph_load                                                     */
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* <Description>                                                         */
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    A driver method used to load a glyph within a given glyph slot.    */
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* <Input>                                                               */
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    slot        :: A handle to the target slot object where the glyph  */
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                   will be loaded.                                     */
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    size        :: A handle to the source face size at which the glyph */
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                   must be scaled, loaded, etc.                        */
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    glyph_index :: The index of the glyph in the font file.            */
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    load_flags  :: A flag indicating what to load for this glyph.  The */
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                   FT_LOAD_??? constants can be used to control the    */
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                   glyph loading process (e.g., whether the outline    */
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                   should be scaled, whether to load bitmaps or not,   */
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                   whether to hint the outline, etc).                  */
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* <Return>                                                              */
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*    FreeType error code.  0 means success.                             */
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*                                                                       */
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_CALLBACK_DEF( FT_Error )
155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  cff_glyph_load( FT_GlyphSlot  cffslot,      /* CFF_GlyphSlot */
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                  FT_Size       cffsize,      /* CFF_Size      */
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                  FT_UInt       glyph_index,
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                  FT_Int32      load_flags )
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error       error;
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFF_GlyphSlot  slot = (CFF_GlyphSlot)cffslot;
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFF_Size       size = (CFF_Size)cffsize;
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( !slot )
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return FT_THROW( Invalid_Slot_Handle );
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* check whether we want a scaled outline or bitmap */
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( !size )
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* reset the size object if necessary */
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( load_flags & FT_LOAD_NO_SCALE )
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      size = NULL;
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( size )
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      /* these two objects must have the same parent */
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( cffsize->face != cffslot->face )
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FT_THROW( Invalid_Face_Handle );
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* now load the glyph outline if necessary */
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    error = cff_slot_load( slot, size, glyph_index, load_flags );
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* force drop-out mode to 2 - irrelevant now */
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* slot->outline.dropout_mode = 2; */
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return error;
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_CALLBACK_DEF( FT_Error )
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  cff_get_advances( FT_Face    face,
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FT_UInt    start,
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FT_UInt    count,
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FT_Int32   flags,
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FT_Fixed*  advances )
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_UInt       nn;
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error      error = FT_Err_Ok;
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_GlyphSlot  slot  = face->glyph;
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for ( nn = 0; nn < count; nn++ )
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      error = cff_glyph_load( slot, face->size, start + nn, flags );
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( error )
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        break;
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      advances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                     ? slot->linearVertAdvance
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                     : slot->linearHoriAdvance;
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return error;
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *  GLYPH DICT SERVICE
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   */
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static FT_Error
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  cff_get_glyph_name( CFF_Face    face,
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                      FT_UInt     glyph_index,
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                      FT_Pointer  buffer,
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                      FT_UInt     buffer_max )
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFF_Font    font   = (CFF_Font)face->extra.data;
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_String*  gname;
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_UShort   sid;
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error    error;
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( !font->psnames )
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_ERROR(( "cff_get_glyph_name:"
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                 " cannot get glyph name from CFF & CEF fonts\n"
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                 "                   "
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                 " without the `PSNames' module\n" ));
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      error = FT_THROW( Missing_Module );
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      goto Exit;
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* first, locate the sid in the charset table */
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    sid = font->charset.sids[glyph_index];
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* now, lookup the name itself */
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    gname = cff_index_get_sid_string( font, sid );
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( gname )
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_STRCPYN( buffer, gname, buffer_max );
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    error = FT_Err_Ok;
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  Exit:
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return error;
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static FT_UInt
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  cff_get_name_index( CFF_Face    face,
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                      FT_String*  glyph_name )
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFF_Font            cff;
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFF_Charset         charset;
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Service_PsCMaps  psnames;
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_String*          name;
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_UShort           sid;
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_UInt             i;
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cff     = (CFF_FontRec *)face->extra.data;
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    charset = &cff->charset;
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( !psnames )
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return 0;
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for ( i = 0; i < cff->num_glyphs; i++ )
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      sid = charset->sids[i];
287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( sid > 390 )
289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        name = cff_index_get_string( cff, sid - 391 );
290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      else
291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        name = (FT_String *)psnames->adobe_std_strings( sid );
292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( !name )
294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        continue;
295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( !ft_strcmp( glyph_name, name ) )
297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return i;
298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return 0;
301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_DEFINE_SERVICE_GLYPHDICTREC(
305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cff_service_glyph_dict,
306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (FT_GlyphDict_GetNameFunc)  cff_get_glyph_name,
307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (FT_GlyphDict_NameIndexFunc)cff_get_name_index
308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  )
309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*
312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *  POSTSCRIPT INFO SERVICE
313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   */
315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static FT_Int
317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  cff_ps_has_glyph_names( FT_Face  face )
318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0;
320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static FT_Error
324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  cff_ps_get_font_info( CFF_Face         face,
325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        PS_FontInfoRec*  afont_info )
326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFF_Font  cff   = (CFF_Font)face->extra.data;
328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error  error = FT_Err_Ok;
329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( cff && cff->font_info == NULL )
332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      CFF_FontRecDict  dict   = &cff->top_font.font_dict;
334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      PS_FontInfoRec  *font_info = NULL;
335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_Memory        memory = face->root.memory;
336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) )
339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        goto Fail;
340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      font_info->version     = cff_index_get_sid_string( cff,
342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                         dict->version );
343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      font_info->notice      = cff_index_get_sid_string( cff,
344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                         dict->notice );
345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      font_info->full_name   = cff_index_get_sid_string( cff,
346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                         dict->full_name );
347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      font_info->family_name = cff_index_get_sid_string( cff,
348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                         dict->family_name );
349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      font_info->weight      = cff_index_get_sid_string( cff,
350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                         dict->weight );
351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      font_info->italic_angle        = dict->italic_angle;
352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      font_info->is_fixed_pitch      = dict->is_fixed_pitch;
353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      font_info->underline_position  = (FT_Short)dict->underline_position;
354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      font_info->underline_thickness = (FT_Short)dict->underline_thickness;
355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      cff->font_info = font_info;
357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( cff )
360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      *afont_info = *cff->font_info;
361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  Fail:
363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return error;
364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_DEFINE_SERVICE_PSINFOREC(
368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cff_service_ps_info,
369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (PS_GetFontInfoFunc)   cff_ps_get_font_info,
370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (PS_GetFontExtraFunc)  NULL,
371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names,
372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (PS_GetFontPrivateFunc)NULL,        /* unsupported with CFF fonts */
373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (PS_GetFontValueFunc)  NULL         /* not implemented            */
374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  )
375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*
378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *  POSTSCRIPT NAME SERVICE
379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   */
381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static const char*
383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  cff_get_ps_name( CFF_Face  face )
384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFF_Font  cff = (CFF_Font)face->extra.data;
386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return (const char*)cff->font_name;
389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_DEFINE_SERVICE_PSFONTNAMEREC(
393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cff_service_ps_name,
394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (FT_PsName_GetFunc)cff_get_ps_name
395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  )
396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*
399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   * TT CMAP INFO
400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   * If the charmap is a synthetic Unicode encoding cmap or
402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   * a Type 1 standard (or expert) encoding cmap, hide TT CMAP INFO
403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   * service defined in SFNT module.
404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   * Otherwise call the service function in the sfnt module.
406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   */
408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static FT_Error
409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  cff_get_cmap_info( FT_CharMap    charmap,
410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                     TT_CMapInfo  *cmap_info )
411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_CMap   cmap  = FT_CMAP( charmap );
413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error  error = FT_Err_Ok;
414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Face     face    = FT_CMAP_FACE( cmap );
416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Library  library = FT_FACE_LIBRARY( face );
417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmap_info->language = 0;
420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmap_info->format   = 0;
421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( cmap->clazz != &CFF_CMAP_ENCODING_CLASS_REC_GET &&
423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov         cmap->clazz != &CFF_CMAP_UNICODE_CLASS_REC_GET  )
424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_Module           sfnt    = FT_Get_Module( library, "sfnt" );
426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_Service_TTCMaps  service =
427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        (FT_Service_TTCMaps)ft_module_get_service( sfnt,
428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                   FT_SERVICE_ID_TT_CMAP );
429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( service && service->get_cmap_info )
432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        error = service->get_cmap_info( charmap, cmap_info );
433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return error;
436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_DEFINE_SERVICE_TTCMAPSREC(
440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cff_service_get_cmap_info,
441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (TT_CMap_Info_GetFunc)cff_get_cmap_info
442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  )
443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*
446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *  CID INFO SERVICE
447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   */
449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static FT_Error
450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  cff_get_ros( CFF_Face      face,
451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov               const char*  *registry,
452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov               const char*  *ordering,
453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov               FT_Int       *supplement )
454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error  error = FT_Err_Ok;
456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFF_Font  cff   = (CFF_Font)face->extra.data;
457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( cff )
460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      CFF_FontRecDict  dict = &cff->top_font.font_dict;
462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( dict->cid_registry == 0xFFFFU )
465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      {
466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        error = FT_THROW( Invalid_Argument );
467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        goto Fail;
468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      }
469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( registry )
471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      {
472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if ( cff->registry == NULL )
473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          cff->registry = cff_index_get_sid_string( cff,
474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                    dict->cid_registry );
475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *registry = cff->registry;
476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      }
477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( ordering )
479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      {
480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if ( cff->ordering == NULL )
481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          cff->ordering = cff_index_get_sid_string( cff,
482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                                    dict->cid_ordering );
483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *ordering = cff->ordering;
484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      }
485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      /*
487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       * XXX: According to Adobe TechNote #5176, the supplement in CFF
488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       *      can be a real number. We truncate it to fit public API
489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       *      since freetype-2.3.6.
490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       */
491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( supplement )
492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      {
493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if ( dict->cid_supplement < FT_INT_MIN ||
494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov             dict->cid_supplement > FT_INT_MAX )
495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          FT_TRACE1(( "cff_get_ros: too large supplement %d is truncated\n",
496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                      dict->cid_supplement ));
497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *supplement = (FT_Int)dict->cid_supplement;
498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      }
499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  Fail:
502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return error;
503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static FT_Error
507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  cff_get_is_cid( CFF_Face  face,
508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                  FT_Bool  *is_cid )
509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error  error = FT_Err_Ok;
511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFF_Font  cff   = (CFF_Font)face->extra.data;
512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *is_cid = 0;
515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( cff )
517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      CFF_FontRecDict  dict = &cff->top_font.font_dict;
519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( dict->cid_registry != 0xFFFFU )
522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *is_cid = 1;
523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return error;
526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static FT_Error
530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  cff_get_cid_from_glyph_index( CFF_Face  face,
531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                FT_UInt   glyph_index,
532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                FT_UInt  *cid )
533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error  error = FT_Err_Ok;
535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFF_Font  cff;
536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cff = (CFF_Font)face->extra.data;
539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( cff )
541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_UInt          c;
543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      CFF_FontRecDict  dict = &cff->top_font.font_dict;
544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( dict->cid_registry == 0xFFFFU )
547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      {
548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        error = FT_THROW( Invalid_Argument );
549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        goto Fail;
550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      }
551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( glyph_index > cff->num_glyphs )
553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      {
554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        error = FT_THROW( Invalid_Argument );
555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        goto Fail;
556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      }
557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      c = cff->charset.sids[glyph_index];
559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( cid )
561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *cid = c;
562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  Fail:
565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return error;
566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_DEFINE_SERVICE_CIDREC(
570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cff_service_cid_info,
571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros,
572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (FT_CID_GetIsInternallyCIDKeyedFunc)      cff_get_is_cid,
573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (FT_CID_GetCIDFromGlyphIndexFunc)         cff_get_cid_from_glyph_index
574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  )
575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*
578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *  PROPERTY SERVICE
579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   *
580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   */
581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static FT_Error
582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  cff_property_set( FT_Module    module,         /* CFF_Driver */
583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    const char*  property_name,
584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    const void*  value )
585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error    error  = FT_Err_Ok;
587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFF_Driver  driver = (CFF_Driver)module;
588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( !ft_strcmp( property_name, "hinting-engine" ) )
591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_UInt*  hinting_engine = (FT_UInt*)value;
593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef CFF_CONFIG_OPTION_OLD_ENGINE
596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      if ( *hinting_engine != FT_CFF_HINTING_ADOBE )
597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        error = FT_ERR( Unimplemented_Feature );
598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      else
599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        driver->hinting_engine = *hinting_engine;
601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return error;
603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    else if ( !ft_strcmp( property_name, "no-stem-darkening" ) )
605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_Bool*  no_stem_darkening = (FT_Bool*)value;
607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      driver->no_stem_darkening = *no_stem_darkening;
610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return error;
612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_TRACE0(( "cff_property_set: missing property `%s'\n",
615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                property_name ));
616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FT_THROW( Missing_Property );
617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  static FT_Error
621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  cff_property_get( FT_Module    module,         /* CFF_Driver */
622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    const char*  property_name,
623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    const void*  value )
624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Error    error  = FT_Err_Ok;
626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFF_Driver  driver = (CFF_Driver)module;
627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_UInt  hinting_engine    = driver->hinting_engine;
629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Bool  no_stem_darkening = driver->no_stem_darkening;
630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( !ft_strcmp( property_name, "hinting-engine" ) )
633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_UInt*  val = (FT_UInt*)value;
635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      *val = hinting_engine;
638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return error;
640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    else if ( !ft_strcmp( property_name, "no-stem-darkening" ) )
642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_Bool*  val = (FT_Bool*)value;
644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      *val = no_stem_darkening;
647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return error;
649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_TRACE0(( "cff_property_get: missing property `%s'\n",
652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                property_name ));
653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FT_THROW( Missing_Property );
654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_DEFINE_SERVICE_PROPERTIESREC(
658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cff_service_properties,
659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (FT_Properties_SetFunc)cff_property_set,
660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (FT_Properties_GetFunc)cff_property_get )
661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /****                                                                 ****/
667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /****                                                                 ****/
668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /****                D R I V E R  I N T E R F A C E                   ****/
669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /****                                                                 ****/
670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /****                                                                 ****/
671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /*************************************************************************/
674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_DEFINE_SERVICEDESCREC7(
677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cff_services,
678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_SERVICE_ID_XF86_NAME,            FT_XF86_FORMAT_CFF,
679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_SERVICE_ID_POSTSCRIPT_INFO,      &CFF_SERVICE_PS_INFO_GET,
680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET,
681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_SERVICE_ID_GLYPH_DICT,           &CFF_SERVICE_GLYPH_DICT_GET,
682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_SERVICE_ID_TT_CMAP,              &CFF_SERVICE_GET_CMAP_INFO_GET,
683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_SERVICE_ID_CID,                  &CFF_SERVICE_CID_INFO_GET,
684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_SERVICE_ID_PROPERTIES,           &CFF_SERVICE_PROPERTIES_GET
685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  )
686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else
687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_DEFINE_SERVICEDESCREC6(
688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cff_services,
689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_SERVICE_ID_XF86_NAME,            FT_XF86_FORMAT_CFF,
690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_SERVICE_ID_POSTSCRIPT_INFO,      &CFF_SERVICE_PS_INFO_GET,
691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET,
692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_SERVICE_ID_TT_CMAP,              &CFF_SERVICE_GET_CMAP_INFO_GET,
693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_SERVICE_ID_CID,                  &CFF_SERVICE_CID_INFO_GET,
694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_SERVICE_ID_PROPERTIES,           &CFF_SERVICE_PROPERTIES_GET
695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  )
696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_CALLBACK_DEF( FT_Module_Interface )
700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  cff_get_interface( FT_Module    driver,       /* CFF_Driver */
701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                     const char*  module_interface )
702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Library           library;
704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Module            sfnt;
705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FT_Module_Interface  result;
706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* CFF_SERVICES_GET derefers `library' in PIC mode */
709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_PIC
710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( !driver )
711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return NULL;
712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    library = driver->library;
713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( !library )
714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return NULL;
715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    result = ft_service_list_lookup( CFF_SERVICES_GET, module_interface );
718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( result != NULL )
719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return result;
720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* `driver' is not yet evaluated in non-PIC mode */
722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FT_CONFIG_OPTION_PIC
723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( !driver )
724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return NULL;
725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    library = driver->library;
726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ( !library )
727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return NULL;
728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* we pass our request to the `sfnt' module */
731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    sfnt = FT_Get_Module( library, "sfnt" );
732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return sfnt ? sfnt->clazz->get_interface( sfnt, module_interface ) : 0;
734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  /* The FT_DriverInterface structure is defined in ftdriver.h. */
738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CFF_SIZE_SELECT cff_size_select
741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else
742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CFF_SIZE_SELECT 0
743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  FT_DEFINE_DRIVER(
746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cff_driver_class,
747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_MODULE_FONT_DRIVER       |
749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_MODULE_DRIVER_SCALABLE   |
750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FT_MODULE_DRIVER_HAS_HINTER,
751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      sizeof ( CFF_DriverRec ),
753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      "cff",
754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      0x10000L,
755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      0x20000L,
756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      0,   /* module-specific interface */
758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      cff_driver_init,
760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      cff_driver_done,
761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      cff_get_interface,
762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* now the specific driver fields */
764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    sizeof ( TT_FaceRec ),
765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    sizeof ( CFF_SizeRec ),
766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    sizeof ( CFF_GlyphSlotRec ),
767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cff_face_init,
769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cff_face_done,
770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cff_size_init,
771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cff_size_done,
772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cff_slot_init,
773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cff_slot_done,
774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cff_glyph_load,
776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cff_get_kerning,
778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0,                       /* FT_Face_AttachFunc */
779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cff_get_advances,
780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cff_size_request,
782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFF_SIZE_SELECT
784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  )
785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* END */
788