1 /***************************************************************************/
5 /* Quick computation of advance widths (body). */
7 /* Copyright 2008, 2009, 2011, 2013, 2014 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
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. */
16 /***************************************************************************/
20 #include FT_INTERNAL_DEBUG_H
22 #include FT_ADVANCES_H
23 #include FT_INTERNAL_OBJECTS_H
27 _ft_face_scale_advances( FT_Face face,
36 if ( flags & FT_LOAD_NO_SCALE )
39 if ( face->size == NULL )
40 return FT_THROW( Invalid_Size_Handle );
42 if ( flags & FT_LOAD_VERTICAL_LAYOUT )
43 scale = face->size->metrics.y_scale;
45 scale = face->size->metrics.x_scale;
47 /* this must be the same scaling as to get linear{Hori,Vert}Advance */
48 /* (see `FT_Load_Glyph' implementation in src/base/ftobjs.c) */
50 for ( nn = 0; nn < count; nn++ )
51 advances[nn] = FT_MulDiv( advances[nn], scale, 64 );
57 /* at the moment, we can perform fast advance retrieval only in */
58 /* the following cases: */
62 /* - light-hinted load */
64 #define LOAD_ADVANCE_FAST_CHECK( flags ) \
65 ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) || \
66 FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT )
69 /* documentation is in ftadvanc.h */
71 FT_EXPORT_DEF( FT_Error )
72 FT_Get_Advance( FT_Face face,
77 FT_Face_GetAdvancesFunc func;
81 return FT_THROW( Invalid_Face_Handle );
84 return FT_THROW( Invalid_Argument );
86 if ( gindex >= (FT_UInt)face->num_glyphs )
87 return FT_THROW( Invalid_Glyph_Index );
89 func = face->driver->clazz->get_advances;
90 if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) )
95 error = func( face, gindex, 1, flags, padvance );
97 return _ft_face_scale_advances( face, padvance, 1, flags );
99 if ( FT_ERR_NEQ( error, Unimplemented_Feature ) )
103 return FT_Get_Advances( face, gindex, 1, flags, padvance );
107 /* documentation is in ftadvanc.h */
109 FT_EXPORT_DEF( FT_Error )
110 FT_Get_Advances( FT_Face face,
114 FT_Fixed *padvances )
116 FT_Face_GetAdvancesFunc func;
117 FT_UInt num, end, nn;
118 FT_Error error = FT_Err_Ok;
122 return FT_THROW( Invalid_Face_Handle );
125 return FT_THROW( Invalid_Argument );
127 num = (FT_UInt)face->num_glyphs;
129 if ( start >= num || end < start || end > num )
130 return FT_THROW( Invalid_Glyph_Index );
135 func = face->driver->clazz->get_advances;
136 if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) )
138 error = func( face, start, count, flags, padvances );
140 return _ft_face_scale_advances( face, padvances, count, flags );
142 if ( FT_ERR_NEQ( error, Unimplemented_Feature ) )
148 if ( flags & FT_ADVANCE_FLAG_FAST_ONLY )
149 return FT_THROW( Unimplemented_Feature );
151 flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
152 for ( nn = 0; nn < count; nn++ )
154 error = FT_Load_Glyph( face, start + nn, flags );
158 /* scale from 26.6 to 16.16 */
159 padvances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )
160 ? face->glyph->advance.y << 10
161 : face->glyph->advance.x << 10;