[FREETYPE] Update to v2.6.3. CORE-10964
[reactos.git] / reactos / 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 == NULL )
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 /* - neither a MM nor a GX font */
64
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 ) )
69
70
71 /* documentation is in ftadvanc.h */
72
73 FT_EXPORT_DEF( FT_Error )
74 FT_Get_Advance( FT_Face face,
75 FT_UInt gindex,
76 FT_Int32 flags,
77 FT_Fixed *padvance )
78 {
79 FT_Face_GetAdvancesFunc func;
80
81
82 if ( !face )
83 return FT_THROW( Invalid_Face_Handle );
84
85 if ( !padvance )
86 return FT_THROW( Invalid_Argument );
87
88 if ( gindex >= (FT_UInt)face->num_glyphs )
89 return FT_THROW( Invalid_Glyph_Index );
90
91 func = face->driver->clazz->get_advances;
92 if ( func && LOAD_ADVANCE_FAST_CHECK( face, flags ) )
93 {
94 FT_Error error;
95
96
97 error = func( face, gindex, 1, flags, padvance );
98 if ( !error )
99 return _ft_face_scale_advances( face, padvance, 1, flags );
100
101 if ( FT_ERR_NEQ( error, Unimplemented_Feature ) )
102 return error;
103 }
104
105 return FT_Get_Advances( face, gindex, 1, flags, padvance );
106 }
107
108
109 /* documentation is in ftadvanc.h */
110
111 FT_EXPORT_DEF( FT_Error )
112 FT_Get_Advances( FT_Face face,
113 FT_UInt start,
114 FT_UInt count,
115 FT_Int32 flags,
116 FT_Fixed *padvances )
117 {
118 FT_Face_GetAdvancesFunc func;
119 FT_UInt num, end, nn;
120 FT_Error error = FT_Err_Ok;
121
122
123 if ( !face )
124 return FT_THROW( Invalid_Face_Handle );
125
126 if ( !padvances )
127 return FT_THROW( Invalid_Argument );
128
129 num = (FT_UInt)face->num_glyphs;
130 end = start + count;
131 if ( start >= num || end < start || end > num )
132 return FT_THROW( Invalid_Glyph_Index );
133
134 if ( count == 0 )
135 return FT_Err_Ok;
136
137 func = face->driver->clazz->get_advances;
138 if ( func && LOAD_ADVANCE_FAST_CHECK( face, flags ) )
139 {
140 error = func( face, start, count, flags, padvances );
141 if ( !error )
142 return _ft_face_scale_advances( face, padvances, count, flags );
143
144 if ( FT_ERR_NEQ( error, Unimplemented_Feature ) )
145 return error;
146 }
147
148 error = FT_Err_Ok;
149
150 if ( flags & FT_ADVANCE_FLAG_FAST_ONLY )
151 return FT_THROW( Unimplemented_Feature );
152
153 flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
154 for ( nn = 0; nn < count; nn++ )
155 {
156 error = FT_Load_Glyph( face, start + nn, flags );
157 if ( error )
158 break;
159
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;
164 }
165
166 return error;
167 }
168
169
170 /* END */