This commit was manufactured by cvs2svn to create branch 'captive'.
[reactos.git] / lib / freetype / src / cff / cffdrivr.c
1 /***************************************************************************/
2 /*                                                                         */
3 /*  cffdrivr.c                                                             */
4 /*                                                                         */
5 /*    OpenType font driver implementation (body).                          */
6 /*                                                                         */
7 /*  Copyright 1996-2001, 2002 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_INTERNAL_POSTSCRIPT_NAMES_H
26
27 #include "cffdrivr.h"
28 #include "cffgload.h"
29 #include "cffload.h"
30
31 #include "cfferrs.h"
32
33
34   /*************************************************************************/
35   /*                                                                       */
36   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
37   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
38   /* messages during execution.                                            */
39   /*                                                                       */
40 #undef  FT_COMPONENT
41 #define FT_COMPONENT  trace_cffdriver
42
43
44   /*************************************************************************/
45   /*************************************************************************/
46   /*************************************************************************/
47   /****                                                                 ****/
48   /****                                                                 ****/
49   /****                          F A C E S                              ****/
50   /****                                                                 ****/
51   /****                                                                 ****/
52   /*************************************************************************/
53   /*************************************************************************/
54   /*************************************************************************/
55
56
57 #undef  PAIR_TAG
58 #define PAIR_TAG( left, right )  ( ( (FT_ULong)left << 16 ) | \
59                                      (FT_ULong)right        )
60
61
62   /*************************************************************************/
63   /*                                                                       */
64   /* <Function>                                                            */
65   /*    Get_Kerning                                                        */
66   /*                                                                       */
67   /* <Description>                                                         */
68   /*    A driver method used to return the kerning vector between two      */
69   /*    glyphs of the same face.                                           */
70   /*                                                                       */
71   /* <Input>                                                               */
72   /*    face        :: A handle to the source face object.                 */
73   /*                                                                       */
74   /*    left_glyph  :: The index of the left glyph in the kern pair.       */
75   /*                                                                       */
76   /*    right_glyph :: The index of the right glyph in the kern pair.      */
77   /*                                                                       */
78   /* <Output>                                                              */
79   /*    kerning     :: The kerning vector.  This is in font units for      */
80   /*                   scalable formats, and in pixels for fixed-sizes     */
81   /*                   formats.                                            */
82   /*                                                                       */
83   /* <Return>                                                              */
84   /*    FreeType error code.  0 means success.                             */
85   /*                                                                       */
86   /* <Note>                                                                */
87   /*    Only horizontal layouts (left-to-right & right-to-left) are        */
88   /*    supported by this function.  Other layouts, or more sophisticated  */
89   /*    kernings, are out of scope of this method (the basic driver        */
90   /*    interface is meant to be simple).                                  */
91   /*                                                                       */
92   /*    They can be implemented by format-specific interfaces.             */
93   /*                                                                       */
94   static FT_Error
95   Get_Kerning( TT_Face     face,
96                FT_UInt     left_glyph,
97                FT_UInt     right_glyph,
98                FT_Vector*  kerning )
99   {
100     TT_Kern0_Pair  pair;
101
102
103     if ( !face )
104       return CFF_Err_Invalid_Face_Handle;
105
106     kerning->x = 0;
107     kerning->y = 0;
108
109     if ( face->kern_pairs )
110     {
111       /* there are some kerning pairs in this font file! */
112       FT_ULong  search_tag = PAIR_TAG( left_glyph, right_glyph );
113       FT_Long   left, right;
114
115
116       left  = 0;
117       right = face->num_kern_pairs - 1;
118
119       while ( left <= right )
120       {
121         FT_Long   middle = left + ( ( right - left ) >> 1 );
122         FT_ULong  cur_pair;
123
124
125         pair     = face->kern_pairs + middle;
126         cur_pair = PAIR_TAG( pair->left, pair->right );
127
128         if ( cur_pair == search_tag )
129           goto Found;
130
131         if ( cur_pair < search_tag )
132           left = middle + 1;
133         else
134           right = middle - 1;
135       }
136     }
137
138   Exit:
139     return CFF_Err_Ok;
140
141   Found:
142     kerning->x = pair->value;
143     goto Exit;
144   }
145
146
147 #undef PAIR_TAG
148
149
150   /*************************************************************************/
151   /*                                                                       */
152   /* <Function>                                                            */
153   /*    Load_Glyph                                                         */
154   /*                                                                       */
155   /* <Description>                                                         */
156   /*    A driver method used to load a glyph within a given glyph slot.    */
157   /*                                                                       */
158   /* <Input>                                                               */
159   /*    slot        :: A handle to the target slot object where the glyph  */
160   /*                   will be loaded.                                     */
161   /*                                                                       */
162   /*    size        :: A handle to the source face size at which the glyph */
163   /*                   must be scaled, loaded, etc.                        */
164   /*                                                                       */
165   /*    glyph_index :: The index of the glyph in the font file.            */
166   /*                                                                       */
167   /*    load_flags  :: A flag indicating what to load for this glyph.  The */
168   /*                   FTLOAD_??? constants can be used to control the     */
169   /*                   glyph loading process (e.g., whether the outline    */
170   /*                   should be scaled, whether to load bitmaps or not,   */
171   /*                   whether to hint the outline, etc).                  */
172   /*                                                                       */
173   /* <Return>                                                              */
174   /*    FreeType error code.  0 means success.                             */
175   /*                                                                       */
176   static FT_Error
177   Load_Glyph( CFF_GlyphSlot  slot,
178               CFF_Size       size,
179               FT_UShort      glyph_index,
180               FT_Int32       load_flags )
181   {
182     FT_Error  error;
183
184
185     if ( !slot )
186       return CFF_Err_Invalid_Slot_Handle;
187
188     /* check whether we want a scaled outline or bitmap */
189     if ( !size )
190       load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
191
192     if ( load_flags & FT_LOAD_NO_SCALE )
193       size = NULL;
194
195     /* reset the size object if necessary */
196     if ( size )
197     {
198       /* these two object must have the same parent */
199       if ( size->face != slot->root.face )
200         return CFF_Err_Invalid_Face_Handle;
201     }
202
203     /* now load the glyph outline if necessary */
204     error = cff_slot_load( slot, size, glyph_index, load_flags );
205
206     /* force drop-out mode to 2 - irrelevant now */
207     /* slot->outline.dropout_mode = 2; */
208
209     return error;
210   }
211
212
213   /*************************************************************************/
214   /*************************************************************************/
215   /*************************************************************************/
216   /****                                                                 ****/
217   /****                                                                 ****/
218   /****             C H A R A C T E R   M A P P I N G S                 ****/
219   /****                                                                 ****/
220   /****                                                                 ****/
221   /*************************************************************************/
222   /*************************************************************************/
223   /*************************************************************************/
224
225   static FT_Error
226   cff_get_glyph_name( CFF_Face    face,
227                       FT_UInt     glyph_index,
228                       FT_Pointer  buffer,
229                       FT_UInt     buffer_max )
230   {
231     CFF_Font         font   = (CFF_Font)face->extra.data;
232     FT_Memory        memory = FT_FACE_MEMORY( face );
233     FT_String*       gname;
234     FT_UShort        sid;
235     PSNames_Service  psnames;
236     FT_Error         error;
237
238
239     psnames = (PSNames_Service)FT_Get_Module_Interface(
240                 face->root.driver->root.library, "psnames" );
241
242     if ( !psnames )
243     {
244       FT_ERROR(( "cff_get_glyph_name:" ));
245       FT_ERROR(( " cannot open CFF & CEF fonts\n" ));
246       FT_ERROR(( "                   " ));
247       FT_ERROR(( " without the `PSNames' module\n" ));
248       error = CFF_Err_Unknown_File_Format;
249       goto Exit;
250     }
251
252     /* first, locate the sid in the charset table */
253     sid = font->charset.sids[glyph_index];
254
255     /* now, lookup the name itself */
256     gname = cff_index_get_sid_string( &font->string_index, sid, psnames );
257
258     if ( buffer_max > 0 )
259     {
260       FT_UInt  len = (FT_UInt)ft_strlen( gname );
261
262
263       if ( len >= buffer_max )
264         len = buffer_max - 1;
265
266       FT_MEM_COPY( buffer, gname, len );
267       ((FT_Byte*)buffer)[len] = 0;
268     }
269
270     FT_FREE ( gname );
271     error = CFF_Err_Ok;
272
273     Exit:
274       return error;
275   }
276
277
278
279   /*************************************************************************/
280   /*                                                                       */
281   /* <Function>                                                            */
282   /*    cff_get_name_index                                                 */
283   /*                                                                       */
284   /* <Description>                                                         */
285   /*    Uses the psnames module and the CFF font's charset to to return a  */
286   /*    a given glyph name's glyph index.                                  */
287   /*                                                                       */
288   /* <Input>                                                               */
289   /*    face       :: A handle to the source face object.                  */
290   /*                                                                       */
291   /*    glyph_name :: The glyph name.                                      */
292   /*                                                                       */
293   /* <Return>                                                              */
294   /*    Glyph index.  0 means `undefined character code'.                  */
295   /*                                                                       */
296   static FT_UInt
297   cff_get_name_index( CFF_Face    face,
298                       FT_String*  glyph_name )
299   {
300     CFF_Font         cff;
301     CFF_Charset      charset;
302     PSNames_Service  psnames;
303     FT_Memory        memory = FT_FACE_MEMORY( face );
304     FT_String*       name;
305     FT_UShort        sid;
306     FT_UInt          i;
307     FT_Int           result;
308
309
310     cff     = (CFF_FontRec *)face->extra.data;
311     charset = &cff->charset;
312
313     psnames = (PSNames_Service)FT_Get_Module_Interface(
314                 face->root.driver->root.library, "psnames" );
315
316     for ( i = 0; i < cff->num_glyphs; i++ )
317     {
318       sid = charset->sids[i];
319
320       if ( sid > 390 )
321         name = cff_index_get_name( &cff->string_index, sid - 391 );
322       else
323         name = (FT_String *)psnames->adobe_std_strings( sid );
324
325       result = ft_strcmp( glyph_name, name );
326
327       if ( sid > 390 )
328         FT_FREE( name );
329
330       if ( !result )
331         return i;
332     }
333
334     return 0;
335   }
336
337
338   /*************************************************************************/
339   /*************************************************************************/
340   /*************************************************************************/
341   /****                                                                 ****/
342   /****                                                                 ****/
343   /****                D R I V E R  I N T E R F A C E                   ****/
344   /****                                                                 ****/
345   /****                                                                 ****/
346   /*************************************************************************/
347   /*************************************************************************/
348   /*************************************************************************/
349
350   static FT_Module_Interface
351   cff_get_interface( CFF_Driver   driver,
352                      const char*  module_interface )
353   {
354     FT_Module  sfnt;
355
356
357 #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
358
359     if ( ft_strcmp( (const char*)module_interface, "glyph_name" ) == 0 )
360       return (FT_Module_Interface)cff_get_glyph_name;
361
362     if ( ft_strcmp( (const char*)module_interface, "name_index" ) == 0 )
363       return (FT_Module_Interface)cff_get_name_index;
364
365 #endif
366
367     /* we simply pass our request to the `sfnt' module */
368     sfnt = FT_Get_Module( driver->root.root.library, "sfnt" );
369
370     return sfnt ? sfnt->clazz->get_interface( sfnt, module_interface ) : 0;
371   }
372
373
374   /* The FT_DriverInterface structure is defined in ftdriver.h. */
375
376   FT_CALLBACK_TABLE_DEF
377   const FT_Driver_ClassRec  cff_driver_class =
378   {
379     /* begin with the FT_Module_Class fields */
380     {
381       ft_module_font_driver       |
382       ft_module_driver_scalable   |
383       ft_module_driver_has_hinter,
384
385       sizeof( CFF_DriverRec ),
386       "cff",
387       0x10000L,
388       0x20000L,
389
390       0,   /* module-specific interface */
391
392       (FT_Module_Constructor)cff_driver_init,
393       (FT_Module_Destructor) cff_driver_done,
394       (FT_Module_Requester)  cff_get_interface,
395     },
396
397     /* now the specific driver fields */
398     sizeof( TT_FaceRec ),
399     sizeof( FT_SizeRec ),
400     sizeof( CFF_GlyphSlotRec ),
401
402     (FT_Face_InitFunc)       cff_face_init,
403     (FT_Face_DoneFunc)       cff_face_done,
404     (FT_Size_InitFunc)       cff_size_init,
405     (FT_Size_DoneFunc)       cff_size_done,
406     (FT_Slot_InitFunc)       cff_slot_init,
407     (FT_Slot_DoneFunc)       cff_slot_done,
408
409     (FT_Size_ResetPointsFunc)cff_size_reset,
410     (FT_Size_ResetPixelsFunc)cff_size_reset,
411
412     (FT_Slot_LoadFunc)       Load_Glyph,
413
414     (FT_Face_GetKerningFunc) Get_Kerning,
415     (FT_Face_AttachFunc)     0,
416     (FT_Face_GetAdvancesFunc)0,
417   };
418
419
420 /* END */