• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***************************************************************************/
2 /*                                                                         */
3 /*  ftadvanc.c                                                             */
4 /*                                                                         */
5 /*    Quick computation of advance widths (body).                          */
6 /*                                                                         */
7 /*  Copyright 2008, 2009 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_ADVANCES_H
21 #include FT_INTERNAL_OBJECTS_H
22 
23 
24   static FT_Error
_ft_face_scale_advances(FT_Face face,FT_Fixed * advances,FT_UInt count,FT_Int32 flags)25   _ft_face_scale_advances( FT_Face    face,
26                            FT_Fixed*  advances,
27                            FT_UInt    count,
28                            FT_Int32   flags )
29   {
30     FT_Fixed  scale;
31     FT_UInt   nn;
32 
33 
34     if ( flags & FT_LOAD_NO_SCALE )
35       return FT_Err_Ok;
36 
37     if ( face->size == NULL )
38       return FT_Err_Invalid_Size_Handle;
39 
40     if ( flags & FT_LOAD_VERTICAL_LAYOUT )
41       scale = face->size->metrics.y_scale;
42     else
43       scale = face->size->metrics.x_scale;
44 
45     /* this must be the same scaling as to get linear{Hori,Vert}Advance */
46     /* (see `FT_Load_Glyph' implementation in src/base/ftobjs.c)        */
47 
48     for ( nn = 0; nn < count; nn++ )
49       advances[nn] = FT_MulDiv( advances[nn], scale, 64 );
50 
51     return FT_Err_Ok;
52   }
53 
54 
55    /* at the moment, we can perform fast advance retrieval only in */
56    /* the following cases:                                         */
57    /*                                                              */
58    /*  - unscaled load                                             */
59    /*  - unhinted load                                             */
60    /*  - light-hinted load                                         */
61 
62 #define LOAD_ADVANCE_FAST_CHECK( flags )                            \
63           ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING )    || \
64             FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT )
65 
66 
67   /* documentation is in ftadvanc.h */
68 
69   FT_EXPORT_DEF( FT_Error )
FT_Get_Advance(FT_Face face,FT_UInt gindex,FT_Int32 flags,FT_Fixed * padvance)70   FT_Get_Advance( FT_Face    face,
71                   FT_UInt    gindex,
72                   FT_Int32   flags,
73                   FT_Fixed  *padvance )
74   {
75     FT_Face_GetAdvancesFunc  func;
76 
77 
78     if ( !face )
79       return FT_Err_Invalid_Face_Handle;
80 
81     if ( gindex >= (FT_UInt)face->num_glyphs )
82       return FT_Err_Invalid_Glyph_Index;
83 
84     func = face->driver->clazz->get_advances;
85     if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) )
86     {
87       FT_Error  error;
88 
89 
90       error = func( face, gindex, 1, flags, padvance );
91       if ( !error )
92         return _ft_face_scale_advances( face, padvance, 1, flags );
93 
94       if ( error != FT_ERROR_BASE( FT_Err_Unimplemented_Feature ) )
95         return error;
96     }
97 
98     return FT_Get_Advances( face, gindex, 1, flags, padvance );
99   }
100 
101 
102   /* documentation is in ftadvanc.h */
103 
104   FT_EXPORT_DEF( FT_Error )
FT_Get_Advances(FT_Face face,FT_UInt start,FT_UInt count,FT_Int32 flags,FT_Fixed * padvances)105   FT_Get_Advances( FT_Face    face,
106                    FT_UInt    start,
107                    FT_UInt    count,
108                    FT_Int32   flags,
109                    FT_Fixed  *padvances )
110   {
111     FT_Face_GetAdvancesFunc  func;
112     FT_UInt                  num, end, nn;
113     FT_Error                 error = FT_Err_Ok;
114 
115 
116     if ( !face )
117       return FT_Err_Invalid_Face_Handle;
118 
119     num = (FT_UInt)face->num_glyphs;
120     end = start + count;
121     if ( start >= num || end < start || end > num )
122       return FT_Err_Invalid_Glyph_Index;
123 
124     if ( count == 0 )
125       return FT_Err_Ok;
126 
127     func = face->driver->clazz->get_advances;
128     if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) )
129     {
130       error = func( face, start, count, flags, padvances );
131       if ( !error )
132         goto Exit;
133 
134       if ( error != FT_ERROR_BASE( FT_Err_Unimplemented_Feature ) )
135         return error;
136     }
137 
138     error = FT_Err_Ok;
139 
140     if ( flags & FT_ADVANCE_FLAG_FAST_ONLY )
141       return FT_Err_Unimplemented_Feature;
142 
143     flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
144     for ( nn = 0; nn < count; nn++ )
145     {
146       error = FT_Load_Glyph( face, start + nn, flags );
147       if ( error )
148         break;
149 
150       padvances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )
151                       ? face->glyph->advance.y
152                       : face->glyph->advance.x;
153     }
154 
155     if ( error )
156       return error;
157 
158   Exit:
159     return _ft_face_scale_advances( face, padvances, count, flags );
160   }
161 
162 
163 /* END */
164