Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4349 | Serge | 1 | /***************************************************************************/ |
2 | /* */ |
||
3 | /* ttmtx.c */ |
||
4 | /* */ |
||
5 | /* Load the metrics tables common to TTF and OTF fonts (body). */ |
||
6 | /* */ |
||
7 | /* Copyright 2006-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 | #include FT_INTERNAL_STREAM_H |
||
22 | #include FT_TRUETYPE_TAGS_H |
||
23 | #include "ttmtx.h" |
||
24 | |||
25 | #include "sferrors.h" |
||
26 | |||
27 | |||
28 | /*************************************************************************/ |
||
29 | /* */ |
||
30 | /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
||
31 | /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ |
||
32 | /* messages during execution. */ |
||
33 | /* */ |
||
34 | #undef FT_COMPONENT |
||
35 | #define FT_COMPONENT trace_ttmtx |
||
36 | |||
37 | |||
38 | /*************************************************************************/ |
||
39 | /* */ |
||
40 | /* |
||
41 | /* tt_face_load_hmtx */ |
||
42 | /* */ |
||
43 | /* |
||
44 | /* Load the `hmtx' or `vmtx' table into a face object. */ |
||
45 | /* */ |
||
46 | /* */ |
||
47 | /* face :: A handle to the target face object. */ |
||
48 | /* */ |
||
49 | /* stream :: The input stream. */ |
||
50 | /* */ |
||
51 | /* vertical :: A boolean flag. If set, load `vmtx'. */ |
||
52 | /* */ |
||
53 | /* |
||
54 | /* FreeType error code. 0 means success. */ |
||
55 | /* */ |
||
56 | FT_LOCAL_DEF( FT_Error ) |
||
57 | tt_face_load_hmtx( TT_Face face, |
||
58 | FT_Stream stream, |
||
59 | FT_Bool vertical ) |
||
60 | { |
||
61 | FT_Error error; |
||
62 | FT_ULong tag, table_size; |
||
63 | FT_ULong* ptable_offset; |
||
64 | FT_ULong* ptable_size; |
||
65 | |||
66 | |||
67 | if ( vertical ) |
||
68 | { |
||
69 | tag = TTAG_vmtx; |
||
70 | ptable_offset = &face->vert_metrics_offset; |
||
71 | ptable_size = &face->vert_metrics_size; |
||
72 | } |
||
73 | else |
||
74 | { |
||
75 | tag = TTAG_hmtx; |
||
76 | ptable_offset = &face->horz_metrics_offset; |
||
77 | ptable_size = &face->horz_metrics_size; |
||
78 | } |
||
79 | |||
80 | error = face->goto_table( face, tag, stream, &table_size ); |
||
81 | if ( error ) |
||
82 | goto Fail; |
||
83 | |||
84 | *ptable_size = table_size; |
||
85 | *ptable_offset = FT_STREAM_POS(); |
||
86 | |||
87 | Fail: |
||
88 | return error; |
||
89 | } |
||
90 | |||
91 | |||
92 | /*************************************************************************/ |
||
93 | /* */ |
||
94 | /* |
||
95 | /* tt_face_load_hhea */ |
||
96 | /* */ |
||
97 | /* |
||
98 | /* Load the `hhea' or 'vhea' table into a face object. */ |
||
99 | /* */ |
||
100 | /* */ |
||
101 | /* face :: A handle to the target face object. */ |
||
102 | /* */ |
||
103 | /* stream :: The input stream. */ |
||
104 | /* */ |
||
105 | /* vertical :: A boolean flag. If set, load `vhea'. */ |
||
106 | /* */ |
||
107 | /* |
||
108 | /* FreeType error code. 0 means success. */ |
||
109 | /* */ |
||
110 | FT_LOCAL_DEF( FT_Error ) |
||
111 | tt_face_load_hhea( TT_Face face, |
||
112 | FT_Stream stream, |
||
113 | FT_Bool vertical ) |
||
114 | { |
||
115 | FT_Error error; |
||
116 | TT_HoriHeader* header; |
||
117 | |||
118 | static const FT_Frame_Field metrics_header_fields[] = |
||
119 | { |
||
120 | #undef FT_STRUCTURE |
||
121 | #define FT_STRUCTURE TT_HoriHeader |
||
122 | |||
123 | FT_FRAME_START( 36 ), |
||
124 | FT_FRAME_ULONG ( Version ), |
||
125 | FT_FRAME_SHORT ( Ascender ), |
||
126 | FT_FRAME_SHORT ( Descender ), |
||
127 | FT_FRAME_SHORT ( Line_Gap ), |
||
128 | FT_FRAME_USHORT( advance_Width_Max ), |
||
129 | FT_FRAME_SHORT ( min_Left_Side_Bearing ), |
||
130 | FT_FRAME_SHORT ( min_Right_Side_Bearing ), |
||
131 | FT_FRAME_SHORT ( xMax_Extent ), |
||
132 | FT_FRAME_SHORT ( caret_Slope_Rise ), |
||
133 | FT_FRAME_SHORT ( caret_Slope_Run ), |
||
134 | FT_FRAME_SHORT ( caret_Offset ), |
||
135 | FT_FRAME_SHORT ( Reserved[0] ), |
||
136 | FT_FRAME_SHORT ( Reserved[1] ), |
||
137 | FT_FRAME_SHORT ( Reserved[2] ), |
||
138 | FT_FRAME_SHORT ( Reserved[3] ), |
||
139 | FT_FRAME_SHORT ( metric_Data_Format ), |
||
140 | FT_FRAME_USHORT( number_Of_HMetrics ), |
||
141 | FT_FRAME_END |
||
142 | }; |
||
143 | |||
144 | |||
145 | if ( vertical ) |
||
146 | { |
||
147 | void *v = &face->vertical; |
||
148 | |||
149 | |||
150 | error = face->goto_table( face, TTAG_vhea, stream, 0 ); |
||
151 | if ( error ) |
||
152 | goto Fail; |
||
153 | |||
154 | header = (TT_HoriHeader*)v; |
||
155 | } |
||
156 | else |
||
157 | { |
||
158 | error = face->goto_table( face, TTAG_hhea, stream, 0 ); |
||
159 | if ( error ) |
||
160 | goto Fail; |
||
161 | |||
162 | header = &face->horizontal; |
||
163 | } |
||
164 | |||
165 | if ( FT_STREAM_READ_FIELDS( metrics_header_fields, header ) ) |
||
166 | goto Fail; |
||
167 | |||
168 | FT_TRACE3(( "Ascender: %5d\n", header->Ascender )); |
||
169 | FT_TRACE3(( "Descender: %5d\n", header->Descender )); |
||
170 | FT_TRACE3(( "number_Of_Metrics: %5u\n", header->number_Of_HMetrics )); |
||
171 | |||
172 | header->long_metrics = NULL; |
||
173 | header->short_metrics = NULL; |
||
174 | |||
175 | Fail: |
||
176 | return error; |
||
177 | } |
||
178 | |||
179 | |||
180 | /*************************************************************************/ |
||
181 | /* */ |
||
182 | /* |
||
183 | /* tt_face_get_metrics */ |
||
184 | /* */ |
||
185 | /* |
||
186 | /* Returns the horizontal or vertical metrics in font units for a */ |
||
187 | /* given glyph. The metrics are the left side bearing (resp. top */ |
||
188 | /* side bearing) and advance width (resp. advance height). */ |
||
189 | /* */ |
||
190 | /* */ |
||
191 | /* header :: A pointer to either the horizontal or vertical metrics */ |
||
192 | /* structure. */ |
||
193 | /* */ |
||
194 | /* idx :: The glyph index. */ |
||
195 | /* */ |
||
196 | /* |
||
197 | /* bearing :: The bearing, either left side or top side. */ |
||
198 | /* */ |
||
199 | /* advance :: The advance width resp. advance height. */ |
||
200 | /* */ |
||
201 | FT_LOCAL_DEF( FT_Error ) |
||
202 | tt_face_get_metrics( TT_Face face, |
||
203 | FT_Bool vertical, |
||
204 | FT_UInt gindex, |
||
205 | FT_Short *abearing, |
||
206 | FT_UShort *aadvance ) |
||
207 | { |
||
208 | FT_Error error; |
||
209 | FT_Stream stream = face->root.stream; |
||
210 | TT_HoriHeader* header; |
||
211 | FT_ULong table_pos, table_size, table_end; |
||
212 | FT_UShort k; |
||
213 | |||
214 | |||
215 | if ( vertical ) |
||
216 | { |
||
217 | void* v = &face->vertical; |
||
218 | |||
219 | |||
220 | header = (TT_HoriHeader*)v; |
||
221 | table_pos = face->vert_metrics_offset; |
||
222 | table_size = face->vert_metrics_size; |
||
223 | } |
||
224 | else |
||
225 | { |
||
226 | header = &face->horizontal; |
||
227 | table_pos = face->horz_metrics_offset; |
||
228 | table_size = face->horz_metrics_size; |
||
229 | } |
||
230 | |||
231 | table_end = table_pos + table_size; |
||
232 | |||
233 | k = header->number_Of_HMetrics; |
||
234 | |||
235 | if ( k > 0 ) |
||
236 | { |
||
237 | if ( gindex < (FT_UInt)k ) |
||
238 | { |
||
239 | table_pos += 4 * gindex; |
||
240 | if ( table_pos + 4 > table_end ) |
||
241 | goto NoData; |
||
242 | |||
243 | if ( FT_STREAM_SEEK( table_pos ) || |
||
244 | FT_READ_USHORT( *aadvance ) || |
||
245 | FT_READ_SHORT( *abearing ) ) |
||
246 | goto NoData; |
||
247 | } |
||
248 | else |
||
249 | { |
||
250 | table_pos += 4 * ( k - 1 ); |
||
251 | if ( table_pos + 4 > table_end ) |
||
252 | goto NoData; |
||
253 | |||
254 | if ( FT_STREAM_SEEK( table_pos ) || |
||
255 | FT_READ_USHORT( *aadvance ) ) |
||
256 | goto NoData; |
||
257 | |||
258 | table_pos += 4 + 2 * ( gindex - k ); |
||
259 | if ( table_pos + 2 > table_end ) |
||
260 | *abearing = 0; |
||
261 | else |
||
262 | { |
||
263 | if ( !FT_STREAM_SEEK( table_pos ) ) |
||
264 | (void)FT_READ_SHORT( *abearing ); |
||
265 | } |
||
266 | } |
||
267 | } |
||
268 | else |
||
269 | { |
||
270 | NoData: |
||
271 | *abearing = 0; |
||
272 | *aadvance = 0; |
||
273 | } |
||
274 | |||
275 | return FT_Err_Ok; |
||
276 | } |
||
277 | |||
278 | |||
279 | /* END */> |