Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
3918 | Serge | 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 |
||
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 | |||
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 */><>><>>>> |