update for HEAD-2003050101
[reactos.git] / lib / freetype / src / truetype / ttdriver.c
1 /***************************************************************************/
2 /*                                                                         */
3 /*  ttdriver.c                                                             */
4 /*                                                                         */
5 /*    TrueType 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_INTERNAL_DEBUG_H
21 #include FT_INTERNAL_STREAM_H
22 #include FT_INTERNAL_SFNT_H
23 #include FT_TRUETYPE_IDS_H
24
25 #include "ttdriver.h"
26 #include "ttgload.h"
27
28 #include "tterrors.h"
29
30
31   /*************************************************************************/
32   /*                                                                       */
33   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
34   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
35   /* messages during execution.                                            */
36   /*                                                                       */
37 #undef  FT_COMPONENT
38 #define FT_COMPONENT  trace_ttdriver
39
40
41   /*************************************************************************/
42   /*************************************************************************/
43   /*************************************************************************/
44   /****                                                                 ****/
45   /****                                                                 ****/
46   /****                          F A C E S                              ****/
47   /****                                                                 ****/
48   /****                                                                 ****/
49   /*************************************************************************/
50   /*************************************************************************/
51   /*************************************************************************/
52
53
54 #undef  PAIR_TAG
55 #define PAIR_TAG( left, right )  ( ( (FT_ULong)left << 16 ) | \
56                                      (FT_ULong)right        )
57
58
59   /*************************************************************************/
60   /*                                                                       */
61   /* <Function>                                                            */
62   /*    Get_Kerning                                                        */
63   /*                                                                       */
64   /* <Description>                                                         */
65   /*    A driver method used to return the kerning vector between two      */
66   /*    glyphs of the same face.                                           */
67   /*                                                                       */
68   /* <Input>                                                               */
69   /*    face        :: A handle to the source face object.                 */
70   /*                                                                       */
71   /*    left_glyph  :: The index of the left glyph in the kern pair.       */
72   /*                                                                       */
73   /*    right_glyph :: The index of the right glyph in the kern pair.      */
74   /*                                                                       */
75   /* <Output>                                                              */
76   /*    kerning     :: The kerning vector.  This is in font units for      */
77   /*                   scalable formats, and in pixels for fixed-sizes     */
78   /*                   formats.                                            */
79   /*                                                                       */
80   /* <Return>                                                              */
81   /*    FreeType error code.  0 means success.                             */
82   /*                                                                       */
83   /* <Note>                                                                */
84   /*    Only horizontal layouts (left-to-right & right-to-left) are        */
85   /*    supported by this function.  Other layouts, or more sophisticated  */
86   /*    kernings, are out of scope of this method (the basic driver        */
87   /*    interface is meant to be simple).                                  */
88   /*                                                                       */
89   /*    They can be implemented by format-specific interfaces.             */
90   /*                                                                       */
91   static FT_Error
92   Get_Kerning( TT_Face     face,
93                FT_UInt     left_glyph,
94                FT_UInt     right_glyph,
95                FT_Vector*  kerning )
96   {
97     TT_Kern0_Pair  pair;
98
99
100     if ( !face )
101       return TT_Err_Invalid_Face_Handle;
102
103     kerning->x = 0;
104     kerning->y = 0;
105
106     if ( face->kern_pairs )
107     {
108       /* there are some kerning pairs in this font file! */
109       FT_ULong  search_tag = PAIR_TAG( left_glyph, right_glyph );
110       FT_Long   left, right;
111
112
113       left  = 0;
114       right = face->num_kern_pairs - 1;
115
116       while ( left <= right )
117       {
118         FT_Int    middle = left + ( ( right - left ) >> 1 );
119         FT_ULong  cur_pair;
120
121
122         pair     = face->kern_pairs + middle;
123         cur_pair = PAIR_TAG( pair->left, pair->right );
124
125         if ( cur_pair == search_tag )
126           goto Found;
127
128         if ( cur_pair < search_tag )
129           left = middle + 1;
130         else
131           right = middle - 1;
132       }
133     }
134
135   Exit:
136     return TT_Err_Ok;
137
138   Found:
139     kerning->x = pair->value;
140     goto Exit;
141   }
142
143
144 #undef PAIR_TAG
145
146
147   /*************************************************************************/
148   /*************************************************************************/
149   /*************************************************************************/
150   /****                                                                 ****/
151   /****                                                                 ****/
152   /****                           S I Z E S                             ****/
153   /****                                                                 ****/
154   /****                                                                 ****/
155   /*************************************************************************/
156   /*************************************************************************/
157   /*************************************************************************/
158
159
160   /*************************************************************************/
161   /*                                                                       */
162   /* <Function>                                                            */
163   /*    Set_Char_Sizes                                                     */
164   /*                                                                       */
165   /* <Description>                                                         */
166   /*    A driver method used to reset a size's character sizes (horizontal */
167   /*    and vertical) expressed in fractional points.                      */
168   /*                                                                       */
169   /* <Input>                                                               */
170   /*    char_width      :: The character width expressed in 26.6           */
171   /*                       fractional points.                              */
172   /*                                                                       */
173   /*    char_height     :: The character height expressed in 26.6          */
174   /*                       fractional points.                              */
175   /*                                                                       */
176   /*    horz_resolution :: The horizontal resolution of the output device. */
177   /*                                                                       */
178   /*    vert_resolution :: The vertical resolution of the output device.   */
179   /*                                                                       */
180   /* <InOut>                                                               */
181   /*    size            :: A handle to the target size object.             */
182   /*                                                                       */
183   /* <Return>                                                              */
184   /*    FreeType error code.  0 means success.                             */
185   /*                                                                       */
186   static FT_Error
187   Set_Char_Sizes( TT_Size     size,
188                   FT_F26Dot6  char_width,
189                   FT_F26Dot6  char_height,
190                   FT_UInt     horz_resolution,
191                   FT_UInt     vert_resolution )
192   {
193     FT_Size_Metrics*  metrics  = &size->root.metrics;
194     FT_Size_Metrics*  metrics2 = &size->metrics;
195     TT_Face           face     = (TT_Face)size->root.face;
196     FT_Long           dim_x, dim_y;
197
198
199     *metrics2 = *metrics;
200
201     /* This bit flag, when set, indicates that the pixel size must be */
202     /* truncated to an integer.  Nearly all TrueType fonts have this  */
203     /* bit set, as hinting won't work really well otherwise.          */
204     /*                                                                */
205     if ( ( face->header.Flags & 8 ) != 0 )
206     {
207      /* we need to use rounding in the following computations. Otherwise,
208       * the resulting hinted outlines will be very slightly distorted
209       */
210       dim_x = ( ( char_width  * horz_resolution + (36+32*72) ) / 72 ) & -64;
211       dim_y = ( ( char_height * vert_resolution + (36+32*72) ) / 72 ) & -64;
212     }
213     else
214     {
215       dim_x = ( ( char_width  * horz_resolution + 36 ) / 72 );
216       dim_y = ( ( char_height * vert_resolution + 36 ) / 72 );
217     }
218
219     /* we only modify "metrics2", not "metrics", so these changes have */
220     /* no effect on the result of the auto-hinter when it is used      */
221     /*                                                                 */
222     metrics2->x_ppem  = (FT_UShort)( dim_x >> 6 );
223     metrics2->y_ppem  = (FT_UShort)( dim_y >> 6 );
224     metrics2->x_scale = FT_DivFix( dim_x, face->root.units_per_EM );
225     metrics2->y_scale = FT_DivFix( dim_y, face->root.units_per_EM );
226
227     size->ttmetrics.valid = FALSE;
228 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
229     size->strike_index    = 0xFFFF;
230 #endif
231
232     return tt_size_reset( size );
233   }
234
235
236   /*************************************************************************/
237   /*                                                                       */
238   /* <Function>                                                            */
239   /*    Set_Pixel_Sizes                                                    */
240   /*                                                                       */
241   /* <Description>                                                         */
242   /*    A driver method used to reset a size's character sizes (horizontal */
243   /*    and vertical) expressed in integer pixels.                         */
244   /*                                                                       */
245   /* <Input>                                                               */
246   /*    pixel_width  :: The character width expressed in integer pixels.   */
247   /*                                                                       */
248   /*    pixel_height :: The character height expressed in integer pixels.  */
249   /*                                                                       */
250   /* <InOut>                                                               */
251   /*    size         :: A handle to the target size object.                */
252   /*                                                                       */
253   /* <Return>                                                              */
254   /*    FreeType error code.  0 means success.                             */
255   /*                                                                       */
256   static FT_Error
257   Set_Pixel_Sizes( TT_Size  size,
258                    FT_UInt  pixel_width,
259                    FT_UInt  pixel_height )
260   {
261     FT_UNUSED( pixel_width );
262     FT_UNUSED( pixel_height );
263
264     /* many things have been pre-computed by the base layer */
265
266     size->metrics         = size->root.metrics;
267     size->ttmetrics.valid = FALSE;
268 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
269     size->strike_index    = 0xFFFF;
270 #endif
271
272     return tt_size_reset( size );
273   }
274
275
276   /*************************************************************************/
277   /*                                                                       */
278   /* <Function>                                                            */
279   /*    Load_Glyph                                                         */
280   /*                                                                       */
281   /* <Description>                                                         */
282   /*    A driver method used to load a glyph within a given glyph slot.    */
283   /*                                                                       */
284   /* <Input>                                                               */
285   /*    slot        :: A handle to the target slot object where the glyph  */
286   /*                   will be loaded.                                     */
287   /*                                                                       */
288   /*    size        :: A handle to the source face size at which the glyph */
289   /*                   must be scaled, loaded, etc.                        */
290   /*                                                                       */
291   /*    glyph_index :: The index of the glyph in the font file.            */
292   /*                                                                       */
293   /*    load_flags  :: A flag indicating what to load for this glyph.  The */
294   /*                   FTLOAD_??? constants can be used to control the     */
295   /*                   glyph loading process (e.g., whether the outline    */
296   /*                   should be scaled, whether to load bitmaps or not,   */
297   /*                   whether to hint the outline, etc).                  */
298   /*                                                                       */
299   /* <Return>                                                              */
300   /*    FreeType error code.  0 means success.                             */
301   /*                                                                       */
302   static FT_Error
303   Load_Glyph( TT_GlyphSlot  slot,
304               TT_Size       size,
305               FT_UShort     glyph_index,
306               FT_Int32      load_flags )
307   {
308     FT_Error  error;
309
310
311     if ( !slot )
312       return TT_Err_Invalid_Slot_Handle;
313
314     /* check whether we want a scaled outline or bitmap */
315     if ( !size )
316       load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
317
318     if ( load_flags & FT_LOAD_NO_SCALE )
319       size = NULL;
320
321     /* reset the size object if necessary */
322     if ( size )
323     {
324       /* these two object must have the same parent */
325       if ( size->root.face != slot->face )
326         return TT_Err_Invalid_Face_Handle;
327
328       if ( !size->ttmetrics.valid )
329       {
330         if ( FT_SET_ERROR( tt_size_reset( size ) ) )
331           return error;
332       }
333     }
334
335     /* now load the glyph outline if necessary */
336     error = TT_Load_Glyph( size, slot, glyph_index, load_flags );
337
338     /* force drop-out mode to 2 - irrelevant now */
339     /* slot->outline.dropout_mode = 2; */
340
341     return error;
342   }
343
344
345   /*************************************************************************/
346   /*************************************************************************/
347   /*************************************************************************/
348   /****                                                                 ****/
349   /****                                                                 ****/
350   /****                D R I V E R  I N T E R F A C E                   ****/
351   /****                                                                 ****/
352   /****                                                                 ****/
353   /*************************************************************************/
354   /*************************************************************************/
355   /*************************************************************************/
356
357
358   static FT_Module_Interface
359   tt_get_interface( TT_Driver    driver,
360                     const char*  tt_interface )
361   {
362     FT_Module     sfntd = FT_Get_Module( driver->root.root.library,
363                                          "sfnt" );
364     SFNT_Service  sfnt;
365
366
367     /* only return the default interface from the SFNT module */
368     if ( sfntd )
369     {
370       sfnt = (SFNT_Service)( sfntd->clazz->module_interface );
371       if ( sfnt )
372         return sfnt->get_interface( FT_MODULE( driver ), tt_interface );
373     }
374
375     return 0;
376   }
377
378
379   /* The FT_DriverInterface structure is defined in ftdriver.h. */
380
381   FT_CALLBACK_TABLE_DEF
382   const FT_Driver_ClassRec  tt_driver_class =
383   {
384     {
385       ft_module_font_driver     |
386       ft_module_driver_scalable |
387 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
388       ft_module_driver_has_hinter,
389 #else
390       0,
391 #endif
392
393       sizeof ( TT_DriverRec ),
394
395       "truetype",      /* driver name                           */
396       0x10000L,        /* driver version == 1.0                 */
397       0x20000L,        /* driver requires FreeType 2.0 or above */
398
399       (void*)0,        /* driver specific interface */
400
401       (FT_Module_Constructor)tt_driver_init,
402       (FT_Module_Destructor) tt_driver_done,
403       (FT_Module_Requester)  tt_get_interface,
404     },
405
406     sizeof ( TT_FaceRec ),
407     sizeof ( TT_SizeRec ),
408     sizeof ( FT_GlyphSlotRec ),
409
410
411     (FT_Face_InitFunc)        tt_face_init,
412     (FT_Face_DoneFunc)        tt_face_done,
413     (FT_Size_InitFunc)        tt_size_init,
414     (FT_Size_DoneFunc)        tt_size_done,
415     (FT_Slot_InitFunc)        0,
416     (FT_Slot_DoneFunc)        0,
417
418     (FT_Size_ResetPointsFunc) Set_Char_Sizes,
419     (FT_Size_ResetPixelsFunc) Set_Pixel_Sizes,
420     (FT_Slot_LoadFunc)        Load_Glyph,
421
422     (FT_Face_GetKerningFunc)  Get_Kerning,
423     (FT_Face_AttachFunc)      0,
424     (FT_Face_GetAdvancesFunc) 0
425   };
426
427
428 /* END */