[FREETYPE] Update to v2.7.1. Patch by Katayama Hirofumi MZ, verified by me. CORE...
[reactos.git] / reactos / sdk / lib / 3rdparty / freetype / src / base / ftadvanc.c
1 /***************************************************************************/
2 /* */
3 /* ftadvanc.c */
4 /* */
5 /* Quick computation of advance widths (body). */
6 /* */
7 /* Copyright 2008-2016 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_INTERNAL_DEBUG_H
21
22 #include FT_ADVANCES_H
23 #include FT_INTERNAL_OBJECTS_H
24
25
26 static FT_Error
27 _ft_face_scale_advances( FT_Face face,
28 FT_Fixed* advances,
29 FT_UInt count,
30 FT_Int32 flags )
31 {
32 FT_Fixed scale;
33 FT_UInt nn;
34
35
36 if ( flags & FT_LOAD_NO_SCALE )
37 return FT_Err_Ok;
38
39 if ( !face->size )
40 return FT_THROW( Invalid_Size_Handle );
41
42 if ( flags & FT_LOAD_VERTICAL_LAYOUT )
43 scale = face->size->metrics.y_scale;
44 else
45 scale = face->size->metrics.x_scale;
46
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) */
49
50 for ( nn = 0; nn < count; nn++ )
51 advances[nn] = FT_MulDiv( advances[nn], scale, 64 );
52
53 return FT_Err_Ok;
54 }
55
56
57 /* at the moment, we can perform fast advance retrieval only in */
58 /* the following cases: */
59 /* */
60 /* - unscaled load */
61 /* - unhinted load */
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) */
66
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 )
70
71
72 /* documentation is in ftadvanc.h */
73
74 FT_EXPORT_DEF( FT_Error )
75 FT_Get_Advance( FT_Face face,
76 FT_UInt gindex,
77 FT_Int32 flags,
78 FT_Fixed *padvance )
79 {
80 FT_Face_GetAdvancesFunc func;
81
82
83 if ( !face )
84 return FT_THROW( Invalid_Face_Handle );
85
86 if ( !padvance )
87 return FT_THROW( Invalid_Argument );
88
89 if ( gindex >= (FT_UInt)face->num_glyphs )
90 return FT_THROW( Invalid_Glyph_Index );
91
92 func = face->driver->clazz->get_advances;
93 if ( func && LOAD_ADVANCE_FAST_CHECK( face, flags ) )
94 {
95 FT_Error error;
96
97
98 error = func( face, gindex, 1, flags, padvance );
99 if ( !error )
100 return _ft_face_scale_advances( face, padvance, 1, flags );
101
102 if ( FT_ERR_NEQ( error, Unimplemented_Feature ) )
103 return error;
104 }
105
106 return FT_Get_Advances( face, gindex, 1, flags, padvance );
107 }
108
109
110 /* documentation is in ftadvanc.h */
111
112 FT_EXPORT_DEF( FT_Error )
113 FT_Get_Advances( FT_Face face,
114 FT_UInt start,
115 FT_UInt count,
116 FT_Int32 flags,
117 FT_Fixed *padvances )
118 {
119 FT_Face_GetAdvancesFunc func;
120 FT_UInt num, end, nn;
121 FT_Error error = FT_Err_Ok;
122
123
124 if ( !face )
125 return FT_THROW( Invalid_Face_Handle );
126
127 if ( !padvances )
128 return FT_THROW( Invalid_Argument );
129
130 num = (FT_UInt)face->num_glyphs;
131 end = start + count;
132 if ( start >= num || end < start || end > num )
133 return FT_THROW( Invalid_Glyph_Index );
134
135 if ( count == 0 )
136 return FT_Err_Ok;
137
138 func = face->driver->clazz->get_advances;
139 if ( func && LOAD_ADVANCE_FAST_CHECK( face, flags ) )
140 {
141 error = func( face, start, count, flags, padvances );
142 if ( !error )
143 return _ft_face_scale_advances( face, padvances, count, flags );
144
145 if ( FT_ERR_NEQ( error, Unimplemented_Feature ) )
146 return error;
147 }
148
149 error = FT_Err_Ok;
150
151 if ( flags & FT_ADVANCE_FLAG_FAST_ONLY )
152 return FT_THROW( Unimplemented_Feature );
153
154 flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
155 for ( nn = 0; nn < count; nn++ )
156 {
157 error = FT_Load_Glyph( face, start + nn, flags );
158 if ( error )
159 break;
160
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;
165 }
166
167 return error;
168 }
169
170
171 /* END */