OLD | NEW |
| (Empty) |
1 /***************************************************************************/ | |
2 /* */ | |
3 /* ftadvanc.c */ | |
4 /* */ | |
5 /* Quick computation of advance widths (body). */ | |
6 /* */ | |
7 /* Copyright 2008, 2009, 2011, 2013 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 "../../include/ft2build.h" | |
20 #include "../../include/freetype/internal/ftdebug.h" | |
21 | |
22 #include "../../include/freetype/ftadvanc.h" | |
23 #include "../../include/freetype/internal/ftobjs.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 | |
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 ) | |
67 | |
68 | |
69 /* documentation is in ftadvanc.h */ | |
70 | |
71 FT_EXPORT_DEF( FT_Error ) | |
72 FT_Get_Advance( FT_Face face, | |
73 FT_UInt gindex, | |
74 FT_Int32 flags, | |
75 FT_Fixed *padvance ) | |
76 { | |
77 FT_Face_GetAdvancesFunc func; | |
78 | |
79 | |
80 if ( !face ) | |
81 return FT_THROW( Invalid_Face_Handle ); | |
82 | |
83 if ( gindex >= (FT_UInt)face->num_glyphs ) | |
84 return FT_THROW( Invalid_Glyph_Index ); | |
85 | |
86 func = face->driver->clazz->get_advances; | |
87 if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) ) | |
88 { | |
89 FT_Error error; | |
90 | |
91 | |
92 error = func( face, gindex, 1, flags, padvance ); | |
93 if ( !error ) | |
94 return _ft_face_scale_advances( face, padvance, 1, flags ); | |
95 | |
96 if ( FT_ERR_NEQ( error, Unimplemented_Feature ) ) | |
97 return error; | |
98 } | |
99 | |
100 return FT_Get_Advances( face, gindex, 1, flags, padvance ); | |
101 } | |
102 | |
103 | |
104 /* documentation is in ftadvanc.h */ | |
105 | |
106 FT_EXPORT_DEF( FT_Error ) | |
107 FT_Get_Advances( FT_Face face, | |
108 FT_UInt start, | |
109 FT_UInt count, | |
110 FT_Int32 flags, | |
111 FT_Fixed *padvances ) | |
112 { | |
113 FT_Face_GetAdvancesFunc func; | |
114 FT_UInt num, end, nn; | |
115 FT_Error error = FT_Err_Ok; | |
116 | |
117 | |
118 if ( !face ) | |
119 return FT_THROW( Invalid_Face_Handle ); | |
120 | |
121 num = (FT_UInt)face->num_glyphs; | |
122 end = start + count; | |
123 if ( start >= num || end < start || end > num ) | |
124 return FT_THROW( Invalid_Glyph_Index ); | |
125 | |
126 if ( count == 0 ) | |
127 return FT_Err_Ok; | |
128 | |
129 func = face->driver->clazz->get_advances; | |
130 if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) ) | |
131 { | |
132 error = func( face, start, count, flags, padvances ); | |
133 if ( !error ) | |
134 return _ft_face_scale_advances( face, padvances, count, flags ); | |
135 | |
136 if ( FT_ERR_NEQ( error, Unimplemented_Feature ) ) | |
137 return error; | |
138 } | |
139 | |
140 error = FT_Err_Ok; | |
141 | |
142 if ( flags & FT_ADVANCE_FLAG_FAST_ONLY ) | |
143 return FT_THROW( Unimplemented_Feature ); | |
144 | |
145 flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY; | |
146 for ( nn = 0; nn < count; nn++ ) | |
147 { | |
148 error = FT_Load_Glyph( face, start + nn, flags ); | |
149 if ( error ) | |
150 break; | |
151 | |
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; | |
156 } | |
157 | |
158 return error; | |
159 } | |
160 | |
161 | |
162 /* END */ | |
OLD | NEW |