OLD | NEW |
1 /***************************************************************************/ | 1 /***************************************************************************/ |
2 /* */ | 2 /* */ |
3 /* ttmtx.c */ | 3 /* ttmtx.c */ |
4 /* */ | 4 /* */ |
5 /* Load the metrics tables common to TTF and OTF fonts (body). */ | 5 /* Load the metrics tables common to TTF and OTF fonts (body). */ |
6 /* */ | 6 /* */ |
7 /* Copyright 2006-2009, 2011 by */ | 7 /* Copyright 2006-2009, 2011-2013 by */ |
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ | 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
9 /* */ | 9 /* */ |
10 /* This file is part of the FreeType project, and may only be used, */ | 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 */ | 11 /* modified, and distributed under the terms of the FreeType project */ |
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ | 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
13 /* this file you indicate that you have read the license and */ | 13 /* this file you indicate that you have read the license and */ |
14 /* understand and accept it fully. */ | 14 /* understand and accept it fully. */ |
15 /* */ | 15 /* */ |
16 /***************************************************************************/ | 16 /***************************************************************************/ |
17 | 17 |
(...skipping 10 matching lines...) Expand all Loading... |
28 /*************************************************************************/ | 28 /*************************************************************************/ |
29 /* */ | 29 /* */ |
30 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ | 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 */ | 31 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ |
32 /* messages during execution. */ | 32 /* messages during execution. */ |
33 /* */ | 33 /* */ |
34 #undef FT_COMPONENT | 34 #undef FT_COMPONENT |
35 #define FT_COMPONENT trace_ttmtx | 35 #define FT_COMPONENT trace_ttmtx |
36 | 36 |
37 | 37 |
38 /* | |
39 * Unfortunately, we can't enable our memory optimizations if | |
40 * FT_CONFIG_OPTION_OLD_INTERNALS is defined. This is because at least | |
41 * one rogue client (libXfont in the X.Org XServer) is directly accessing | |
42 * the metrics. | |
43 */ | |
44 | |
45 /*************************************************************************/ | 38 /*************************************************************************/ |
46 /* */ | 39 /* */ |
47 /* <Function> */ | 40 /* <Function> */ |
48 /* tt_face_load_hmtx */ | 41 /* tt_face_load_hmtx */ |
49 /* */ | 42 /* */ |
50 /* <Description> */ | 43 /* <Description> */ |
51 /* Load the `hmtx' or `vmtx' table into a face object. */ | 44 /* Load the `hmtx' or `vmtx' table into a face object. */ |
52 /* */ | 45 /* */ |
53 /* <Input> */ | 46 /* <Input> */ |
54 /* face :: A handle to the target face object. */ | 47 /* face :: A handle to the target face object. */ |
55 /* */ | 48 /* */ |
56 /* stream :: The input stream. */ | 49 /* stream :: The input stream. */ |
57 /* */ | 50 /* */ |
58 /* vertical :: A boolean flag. If set, load `vmtx'. */ | 51 /* vertical :: A boolean flag. If set, load `vmtx'. */ |
59 /* */ | 52 /* */ |
60 /* <Return> */ | 53 /* <Return> */ |
61 /* FreeType error code. 0 means success. */ | 54 /* FreeType error code. 0 means success. */ |
62 /* */ | 55 /* */ |
63 #ifndef FT_CONFIG_OPTION_OLD_INTERNALS | |
64 | |
65 FT_LOCAL_DEF( FT_Error ) | 56 FT_LOCAL_DEF( FT_Error ) |
66 tt_face_load_hmtx( TT_Face face, | 57 tt_face_load_hmtx( TT_Face face, |
67 FT_Stream stream, | 58 FT_Stream stream, |
68 FT_Bool vertical ) | 59 FT_Bool vertical ) |
69 { | 60 { |
70 FT_Error error; | 61 FT_Error error; |
71 FT_ULong tag, table_size; | 62 FT_ULong tag, table_size; |
72 FT_ULong* ptable_offset; | 63 FT_ULong* ptable_offset; |
73 FT_ULong* ptable_size; | 64 FT_ULong* ptable_size; |
74 | 65 |
(...skipping 15 matching lines...) Expand all Loading... |
90 if ( error ) | 81 if ( error ) |
91 goto Fail; | 82 goto Fail; |
92 | 83 |
93 *ptable_size = table_size; | 84 *ptable_size = table_size; |
94 *ptable_offset = FT_STREAM_POS(); | 85 *ptable_offset = FT_STREAM_POS(); |
95 | 86 |
96 Fail: | 87 Fail: |
97 return error; | 88 return error; |
98 } | 89 } |
99 | 90 |
100 #else /* !FT_CONFIG_OPTION_OLD_INTERNALS */ | |
101 | |
102 FT_LOCAL_DEF( FT_Error ) | |
103 tt_face_load_hmtx( TT_Face face, | |
104 FT_Stream stream, | |
105 FT_Bool vertical ) | |
106 { | |
107 FT_Error error; | |
108 FT_Memory memory = stream->memory; | |
109 | |
110 FT_ULong table_len; | |
111 FT_Long num_shorts, num_longs, num_shorts_checked; | |
112 | |
113 TT_LongMetrics* longs; | |
114 TT_ShortMetrics** shorts; | |
115 FT_Byte* p; | |
116 | |
117 | |
118 if ( vertical ) | |
119 { | |
120 void* lm = &face->vertical.long_metrics; | |
121 void** sm = &face->vertical.short_metrics; | |
122 | |
123 | |
124 error = face->goto_table( face, TTAG_vmtx, stream, &table_len ); | |
125 if ( error ) | |
126 goto Fail; | |
127 | |
128 num_longs = face->vertical.number_Of_VMetrics; | |
129 if ( (FT_ULong)num_longs > table_len / 4 ) | |
130 num_longs = (FT_Long)( table_len / 4 ); | |
131 | |
132 face->vertical.number_Of_VMetrics = 0; | |
133 | |
134 longs = (TT_LongMetrics*)lm; | |
135 shorts = (TT_ShortMetrics**)sm; | |
136 } | |
137 else | |
138 { | |
139 void* lm = &face->horizontal.long_metrics; | |
140 void** sm = &face->horizontal.short_metrics; | |
141 | |
142 | |
143 error = face->goto_table( face, TTAG_hmtx, stream, &table_len ); | |
144 if ( error ) | |
145 goto Fail; | |
146 | |
147 num_longs = face->horizontal.number_Of_HMetrics; | |
148 if ( (FT_ULong)num_longs > table_len / 4 ) | |
149 num_longs = (FT_Long)( table_len / 4 ); | |
150 | |
151 face->horizontal.number_Of_HMetrics = 0; | |
152 | |
153 longs = (TT_LongMetrics*)lm; | |
154 shorts = (TT_ShortMetrics**)sm; | |
155 } | |
156 | |
157 /* never trust derived values */ | |
158 | |
159 num_shorts = face->max_profile.numGlyphs - num_longs; | |
160 num_shorts_checked = ( table_len - num_longs * 4L ) / 2; | |
161 | |
162 if ( num_shorts < 0 ) | |
163 { | |
164 FT_TRACE0(( "tt_face_load_hmtx:" | |
165 " %cmtx has more metrics than glyphs.\n", | |
166 vertical ? 'v' : 'h' )); | |
167 | |
168 /* Adobe simply ignores this problem. So we shall do the same. */ | |
169 #if 0 | |
170 error = vertical ? SFNT_Err_Invalid_Vert_Metrics | |
171 : SFNT_Err_Invalid_Horiz_Metrics; | |
172 goto Exit; | |
173 #else | |
174 num_shorts = 0; | |
175 #endif | |
176 } | |
177 | |
178 if ( FT_QNEW_ARRAY( *longs, num_longs ) || | |
179 FT_QNEW_ARRAY( *shorts, num_shorts ) ) | |
180 goto Fail; | |
181 | |
182 if ( FT_FRAME_ENTER( table_len ) ) | |
183 goto Fail; | |
184 | |
185 p = stream->cursor; | |
186 | |
187 { | |
188 TT_LongMetrics cur = *longs; | |
189 TT_LongMetrics limit = cur + num_longs; | |
190 | |
191 | |
192 for ( ; cur < limit; cur++ ) | |
193 { | |
194 cur->advance = FT_NEXT_USHORT( p ); | |
195 cur->bearing = FT_NEXT_SHORT( p ); | |
196 } | |
197 } | |
198 | |
199 /* do we have an inconsistent number of metric values? */ | |
200 { | |
201 TT_ShortMetrics* cur = *shorts; | |
202 TT_ShortMetrics* limit = cur + | |
203 FT_MIN( num_shorts, num_shorts_checked ); | |
204 | |
205 | |
206 for ( ; cur < limit; cur++ ) | |
207 *cur = FT_NEXT_SHORT( p ); | |
208 | |
209 /* We fill up the missing left side bearings with the */ | |
210 /* last valid value. Since this will occur for buggy CJK */ | |
211 /* fonts usually only, nothing serious will happen. */ | |
212 if ( num_shorts > num_shorts_checked && num_shorts_checked > 0 ) | |
213 { | |
214 FT_Short val = (*shorts)[num_shorts_checked - 1]; | |
215 | |
216 | |
217 limit = *shorts + num_shorts; | |
218 for ( ; cur < limit; cur++ ) | |
219 *cur = val; | |
220 } | |
221 } | |
222 | |
223 FT_FRAME_EXIT(); | |
224 | |
225 if ( vertical ) | |
226 face->vertical.number_Of_VMetrics = (FT_UShort)num_longs; | |
227 else | |
228 face->horizontal.number_Of_HMetrics = (FT_UShort)num_longs; | |
229 | |
230 Fail: | |
231 return error; | |
232 } | |
233 | |
234 #endif /* !FT_CONFIG_OPTION_OLD_INTERNALS */ | |
235 | |
236 | 91 |
237 /*************************************************************************/ | 92 /*************************************************************************/ |
238 /* */ | 93 /* */ |
239 /* <Function> */ | 94 /* <Function> */ |
240 /* tt_face_load_hhea */ | 95 /* tt_face_load_hhea */ |
241 /* */ | 96 /* */ |
242 /* <Description> */ | 97 /* <Description> */ |
243 /* Load the `hhea' or 'vhea' table into a face object. */ | 98 /* Load the `hhea' or 'vhea' table into a face object. */ |
244 /* */ | 99 /* */ |
245 /* <Input> */ | 100 /* <Input> */ |
246 /* face :: A handle to the target face object. */ | 101 /* face :: A handle to the target face object. */ |
247 /* */ | 102 /* */ |
248 /* stream :: The input stream. */ | 103 /* stream :: The input stream. */ |
249 /* */ | 104 /* */ |
250 /* vertical :: A boolean flag. If set, load `vhea'. */ | 105 /* vertical :: A boolean flag. If set, load `vhea'. */ |
251 /* */ | 106 /* */ |
252 /* <Return> */ | 107 /* <Return> */ |
253 /* FreeType error code. 0 means success. */ | 108 /* FreeType error code. 0 means success. */ |
254 /* */ | 109 /* */ |
255 FT_LOCAL_DEF( FT_Error ) | 110 FT_LOCAL_DEF( FT_Error ) |
256 tt_face_load_hhea( TT_Face face, | 111 tt_face_load_hhea( TT_Face face, |
257 FT_Stream stream, | 112 FT_Stream stream, |
258 FT_Bool vertical ) | 113 FT_Bool vertical ) |
259 { | 114 { |
260 FT_Error error; | 115 FT_Error error; |
261 TT_HoriHeader* header; | 116 TT_HoriHeader* header; |
262 | 117 |
263 const FT_Frame_Field metrics_header_fields[] = | 118 static const FT_Frame_Field metrics_header_fields[] = |
264 { | 119 { |
265 #undef FT_STRUCTURE | 120 #undef FT_STRUCTURE |
266 #define FT_STRUCTURE TT_HoriHeader | 121 #define FT_STRUCTURE TT_HoriHeader |
267 | 122 |
268 FT_FRAME_START( 36 ), | 123 FT_FRAME_START( 36 ), |
269 FT_FRAME_ULONG ( Version ), | 124 FT_FRAME_ULONG ( Version ), |
270 FT_FRAME_SHORT ( Ascender ), | 125 FT_FRAME_SHORT ( Ascender ), |
271 FT_FRAME_SHORT ( Descender ), | 126 FT_FRAME_SHORT ( Descender ), |
272 FT_FRAME_SHORT ( Line_Gap ), | 127 FT_FRAME_SHORT ( Line_Gap ), |
273 FT_FRAME_USHORT( advance_Width_Max ), | 128 FT_FRAME_USHORT( advance_Width_Max ), |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 /* header :: A pointer to either the horizontal or vertical metrics */ | 191 /* header :: A pointer to either the horizontal or vertical metrics */ |
337 /* structure. */ | 192 /* structure. */ |
338 /* */ | 193 /* */ |
339 /* idx :: The glyph index. */ | 194 /* idx :: The glyph index. */ |
340 /* */ | 195 /* */ |
341 /* <Output> */ | 196 /* <Output> */ |
342 /* bearing :: The bearing, either left side or top side. */ | 197 /* bearing :: The bearing, either left side or top side. */ |
343 /* */ | 198 /* */ |
344 /* advance :: The advance width resp. advance height. */ | 199 /* advance :: The advance width resp. advance height. */ |
345 /* */ | 200 /* */ |
346 #ifndef FT_CONFIG_OPTION_OLD_INTERNALS | |
347 | |
348 FT_LOCAL_DEF( FT_Error ) | 201 FT_LOCAL_DEF( FT_Error ) |
349 tt_face_get_metrics( TT_Face face, | 202 tt_face_get_metrics( TT_Face face, |
350 FT_Bool vertical, | 203 FT_Bool vertical, |
351 FT_UInt gindex, | 204 FT_UInt gindex, |
352 FT_Short *abearing, | 205 FT_Short *abearing, |
353 FT_UShort *aadvance ) | 206 FT_UShort *aadvance ) |
354 { | 207 { |
355 FT_Error error; | 208 FT_Error error; |
356 FT_Stream stream = face->root.stream; | 209 FT_Stream stream = face->root.stream; |
357 TT_HoriHeader* header; | 210 TT_HoriHeader* header; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 } | 265 } |
413 } | 266 } |
414 } | 267 } |
415 else | 268 else |
416 { | 269 { |
417 NoData: | 270 NoData: |
418 *abearing = 0; | 271 *abearing = 0; |
419 *aadvance = 0; | 272 *aadvance = 0; |
420 } | 273 } |
421 | 274 |
422 return SFNT_Err_Ok; | 275 return FT_Err_Ok; |
423 } | 276 } |
424 | 277 |
425 #else /* !FT_CONFIG_OPTION_OLD_INTERNALS */ | |
426 | |
427 FT_LOCAL_DEF( FT_Error ) | |
428 tt_face_get_metrics( TT_Face face, | |
429 FT_Bool vertical, | |
430 FT_UInt gindex, | |
431 FT_Short* abearing, | |
432 FT_UShort* aadvance ) | |
433 { | |
434 void* v = &face->vertical; | |
435 void* h = &face->horizontal; | |
436 TT_HoriHeader* header = vertical ? (TT_HoriHeader*)v | |
437 : (TT_HoriHeader*)h; | |
438 TT_LongMetrics longs_m; | |
439 FT_UShort k = header->number_Of_HMetrics; | |
440 | |
441 | |
442 if ( k == 0 || | |
443 !header->long_metrics || | |
444 gindex >= (FT_UInt)face->max_profile.numGlyphs ) | |
445 { | |
446 *abearing = *aadvance = 0; | |
447 return SFNT_Err_Ok; | |
448 } | |
449 | |
450 if ( gindex < (FT_UInt)k ) | |
451 { | |
452 longs_m = (TT_LongMetrics)header->long_metrics + gindex; | |
453 *abearing = longs_m->bearing; | |
454 *aadvance = longs_m->advance; | |
455 } | |
456 else | |
457 { | |
458 *abearing = ((TT_ShortMetrics*)header->short_metrics)[gindex - k]; | |
459 *aadvance = ((TT_LongMetrics)header->long_metrics)[k - 1].advance; | |
460 } | |
461 | |
462 return SFNT_Err_Ok; | |
463 } | |
464 | |
465 #endif /* !FT_CONFIG_OPTION_OLD_INTERNALS */ | |
466 | |
467 | 278 |
468 /* END */ | 279 /* END */ |
OLD | NEW |