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
)
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 /* - if a variations font, it must have an `HVAR' or `VVAR' */
64 /* table (thus the old MM or GX fonts don't qualify; this */
65 /* gets checked by the driver-specific functions) */
67 #define LOAD_ADVANCE_FAST_CHECK( face, flags ) \
68 ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) || \
69 FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT )
72 /* documentation is in ftadvanc.h */
74 FT_EXPORT_DEF( FT_Error
)
75 FT_Get_Advance( FT_Face face
,
80 FT_Face_GetAdvancesFunc func
;
84 return FT_THROW( Invalid_Face_Handle
);
87 return FT_THROW( Invalid_Argument
);
89 if ( gindex
>= (FT_UInt
)face
->num_glyphs
)
90 return FT_THROW( Invalid_Glyph_Index
);
92 func
= face
->driver
->clazz
->get_advances
;
93 if ( func
&& LOAD_ADVANCE_FAST_CHECK( face
, flags
) )
98 error
= func( face
, gindex
, 1, flags
, padvance
);
100 return _ft_face_scale_advances( face
, padvance
, 1, flags
);
102 if ( FT_ERR_NEQ( error
, Unimplemented_Feature
) )
106 return FT_Get_Advances( face
, gindex
, 1, flags
, padvance
);
110 /* documentation is in ftadvanc.h */
112 FT_EXPORT_DEF( FT_Error
)
113 FT_Get_Advances( FT_Face face
,
117 FT_Fixed
*padvances
)
119 FT_Face_GetAdvancesFunc func
;
120 FT_UInt num
, end
, nn
;
121 FT_Error error
= FT_Err_Ok
;
125 return FT_THROW( Invalid_Face_Handle
);
128 return FT_THROW( Invalid_Argument
);
130 num
= (FT_UInt
)face
->num_glyphs
;
132 if ( start
>= num
|| end
< start
|| end
> num
)
133 return FT_THROW( Invalid_Glyph_Index
);
138 func
= face
->driver
->clazz
->get_advances
;
139 if ( func
&& LOAD_ADVANCE_FAST_CHECK( face
, flags
) )
141 error
= func( face
, start
, count
, flags
, padvances
);
143 return _ft_face_scale_advances( face
, padvances
, count
, flags
);
145 if ( FT_ERR_NEQ( error
, Unimplemented_Feature
) )
151 if ( flags
& FT_ADVANCE_FLAG_FAST_ONLY
)
152 return FT_THROW( Unimplemented_Feature
);
154 flags
|= (FT_UInt32
)FT_LOAD_ADVANCE_ONLY
;
155 for ( nn
= 0; nn
< count
; nn
++ )
157 error
= FT_Load_Glyph( face
, start
+ nn
, flags
);
161 /* scale from 26.6 to 16.16 */
162 padvances
[nn
] = ( flags
& FT_LOAD_VERTICAL_LAYOUT
)
163 ? face
->glyph
->advance
.y
* 1024
164 : face
->glyph
->advance
.x
* 1024;