| 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 |