1 /***************************************************************************/
5 /* Quick computation of advance widths (body). */
7 /* Copyright 2008, 2009, 2011, 2013 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
);
83 if ( gindex
>= (FT_UInt
)face
->num_glyphs
)
84 return FT_THROW( Invalid_Glyph_Index
);
86 func
= face
->driver
->clazz
->get_advances
;
87 if ( func
&& LOAD_ADVANCE_FAST_CHECK( flags
) )
92 error
= func( face
, gindex
, 1, flags
, padvance
);
94 return _ft_face_scale_advances( face
, padvance
, 1, flags
);
96 if ( FT_ERR_NEQ( error
, Unimplemented_Feature
) )
100 return FT_Get_Advances( face
, gindex
, 1, flags
, padvance
);
104 /* documentation is in ftadvanc.h */
106 FT_EXPORT_DEF( FT_Error
)
107 FT_Get_Advances( FT_Face face
,
111 FT_Fixed
*padvances
)
113 FT_Face_GetAdvancesFunc func
;
114 FT_UInt num
, end
, nn
;
115 FT_Error error
= FT_Err_Ok
;
119 return FT_THROW( Invalid_Face_Handle
);
121 num
= (FT_UInt
)face
->num_glyphs
;
123 if ( start
>= num
|| end
< start
|| end
> num
)
124 return FT_THROW( Invalid_Glyph_Index
);
129 func
= face
->driver
->clazz
->get_advances
;
130 if ( func
&& LOAD_ADVANCE_FAST_CHECK( flags
) )
132 error
= func( face
, start
, count
, flags
, padvances
);
134 return _ft_face_scale_advances( face
, padvances
, count
, flags
);
136 if ( FT_ERR_NEQ( error
, Unimplemented_Feature
) )
142 if ( flags
& FT_ADVANCE_FLAG_FAST_ONLY
)
143 return FT_THROW( Unimplemented_Feature
);
145 flags
|= (FT_UInt32
)FT_LOAD_ADVANCE_ONLY
;
146 for ( nn
= 0; nn
< count
; nn
++ )
148 error
= FT_Load_Glyph( face
, start
+ nn
, flags
);
152 /* scale from 26.6 to 16.16 */
153 padvances
[nn
] = ( flags
& FT_LOAD_VERTICAL_LAYOUT
)
154 ? face
->glyph
->advance
.y
<< 10
155 : face
->glyph
->advance
.x
<< 10;