1 /***************************************************************************/
5 /* Quick computation of advance widths (body). */
7 /* Copyright 2008-2016 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 */
63 /* - neither a MM nor a GX font */
65 #define LOAD_ADVANCE_FAST_CHECK( face, flags ) \
66 ( ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) || \
67 FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT ) && \
68 !FT_HAS_MULTIPLE_MASTERS( face ) )
71 /* documentation is in ftadvanc.h */
73 FT_EXPORT_DEF( FT_Error
)
74 FT_Get_Advance( FT_Face face
,
79 FT_Face_GetAdvancesFunc func
;
83 return FT_THROW( Invalid_Face_Handle
);
86 return FT_THROW( Invalid_Argument
);
88 if ( gindex
>= (FT_UInt
)face
->num_glyphs
)
89 return FT_THROW( Invalid_Glyph_Index
);
91 func
= face
->driver
->clazz
->get_advances
;
92 if ( func
&& LOAD_ADVANCE_FAST_CHECK( face
, flags
) )
97 error
= func( face
, gindex
, 1, flags
, padvance
);
99 return _ft_face_scale_advances( face
, padvance
, 1, flags
);
101 if ( FT_ERR_NEQ( error
, Unimplemented_Feature
) )
105 return FT_Get_Advances( face
, gindex
, 1, flags
, padvance
);
109 /* documentation is in ftadvanc.h */
111 FT_EXPORT_DEF( FT_Error
)
112 FT_Get_Advances( FT_Face face
,
116 FT_Fixed
*padvances
)
118 FT_Face_GetAdvancesFunc func
;
119 FT_UInt num
, end
, nn
;
120 FT_Error error
= FT_Err_Ok
;
124 return FT_THROW( Invalid_Face_Handle
);
127 return FT_THROW( Invalid_Argument
);
129 num
= (FT_UInt
)face
->num_glyphs
;
131 if ( start
>= num
|| end
< start
|| end
> num
)
132 return FT_THROW( Invalid_Glyph_Index
);
137 func
= face
->driver
->clazz
->get_advances
;
138 if ( func
&& LOAD_ADVANCE_FAST_CHECK( face
, flags
) )
140 error
= func( face
, start
, count
, flags
, padvances
);
142 return _ft_face_scale_advances( face
, padvances
, count
, flags
);
144 if ( FT_ERR_NEQ( error
, Unimplemented_Feature
) )
150 if ( flags
& FT_ADVANCE_FLAG_FAST_ONLY
)
151 return FT_THROW( Unimplemented_Feature
);
153 flags
|= (FT_UInt32
)FT_LOAD_ADVANCE_ONLY
;
154 for ( nn
= 0; nn
< count
; nn
++ )
156 error
= FT_Load_Glyph( face
, start
+ nn
, flags
);
160 /* scale from 26.6 to 16.16 */
161 padvances
[nn
] = ( flags
& FT_LOAD_VERTICAL_LAYOUT
)
162 ? face
->glyph
->advance
.y
<< 10
163 : face
->glyph
->advance
.x
<< 10;