OLD | NEW |
1 /***************************************************************************/ | 1 /***************************************************************************/ |
2 /* */ | 2 /* */ |
3 /* ttgload.c */ | 3 /* ttgload.c */ |
4 /* */ | 4 /* */ |
5 /* TrueType Glyph Loader (body). */ | 5 /* TrueType Glyph Loader (body). */ |
6 /* */ | 6 /* */ |
7 /* Copyright 1996-2012 */ | 7 /* Copyright 1996-2013 */ |
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 |
18 | 18 |
19 #include <ft2build.h> | 19 #include <ft2build.h> |
20 #include FT_INTERNAL_DEBUG_H | 20 #include FT_INTERNAL_DEBUG_H |
21 #include FT_INTERNAL_CALC_H | 21 #include FT_INTERNAL_CALC_H |
22 #include FT_INTERNAL_STREAM_H | 22 #include FT_INTERNAL_STREAM_H |
23 #include FT_INTERNAL_SFNT_H | 23 #include FT_INTERNAL_SFNT_H |
24 #include FT_TRUETYPE_TAGS_H | 24 #include FT_TRUETYPE_TAGS_H |
25 #include FT_OUTLINE_H | 25 #include FT_OUTLINE_H |
| 26 #include FT_TRUETYPE_DRIVER_H |
26 | 27 |
27 #include "ttgload.h" | 28 #include "ttgload.h" |
28 #include "ttpload.h" | 29 #include "ttpload.h" |
29 | 30 |
30 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT | 31 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
31 #include "ttgxvar.h" | 32 #include "ttgxvar.h" |
32 #endif | 33 #endif |
33 | 34 |
34 #include "tterrors.h" | 35 #include "tterrors.h" |
| 36 #include "ttsubpix.h" |
35 | 37 |
36 | 38 |
37 /*************************************************************************/ | 39 /*************************************************************************/ |
38 /* */ | 40 /* */ |
39 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ | 41 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
40 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ | 42 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ |
41 /* messages during execution. */ | 43 /* messages during execution. */ |
42 /* */ | 44 /* */ |
43 #undef FT_COMPONENT | 45 #undef FT_COMPONENT |
44 #define FT_COMPONENT trace_ttgload | 46 #define FT_COMPONENT trace_ttgload |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 | 126 |
125 FT_TRACE5(( " advance height (font units): %d\n", *ah )); | 127 FT_TRACE5(( " advance height (font units): %d\n", *ah )); |
126 FT_TRACE5(( " top side bearing (font units): %d\n", *tsb )); | 128 FT_TRACE5(( " top side bearing (font units): %d\n", *tsb )); |
127 } | 129 } |
128 | 130 |
129 | 131 |
130 static void | 132 static void |
131 tt_get_metrics( TT_Loader loader, | 133 tt_get_metrics( TT_Loader loader, |
132 FT_UInt glyph_index ) | 134 FT_UInt glyph_index ) |
133 { | 135 { |
134 TT_Face face = (TT_Face)loader->face; | 136 TT_Face face = (TT_Face)loader->face; |
| 137 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 138 TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); |
| 139 #endif |
135 | 140 |
136 FT_Short left_bearing = 0, top_bearing = 0; | 141 FT_Short left_bearing = 0, top_bearing = 0; |
137 FT_UShort advance_width = 0, advance_height = 0; | 142 FT_UShort advance_width = 0, advance_height = 0; |
138 | 143 |
139 | 144 |
140 TT_Get_HMetrics( face, glyph_index, | 145 TT_Get_HMetrics( face, glyph_index, |
141 &left_bearing, | 146 &left_bearing, |
142 &advance_width ); | 147 &advance_width ); |
143 TT_Get_VMetrics( face, glyph_index, | 148 TT_Get_VMetrics( face, glyph_index, |
144 &top_bearing, | 149 &top_bearing, |
145 &advance_height ); | 150 &advance_height ); |
146 | 151 |
147 loader->left_bearing = left_bearing; | 152 loader->left_bearing = left_bearing; |
148 loader->advance = advance_width; | 153 loader->advance = advance_width; |
149 loader->top_bearing = top_bearing; | 154 loader->top_bearing = top_bearing; |
150 loader->vadvance = advance_height; | 155 loader->vadvance = advance_height; |
151 | 156 |
| 157 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 158 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) |
| 159 { |
| 160 if ( loader->exec ) |
| 161 loader->exec->sph_tweak_flags = 0; |
| 162 |
| 163 /* this may not be the right place for this, but it works */ |
| 164 if ( loader->exec && loader->exec->ignore_x_mode ) |
| 165 sph_set_tweaks( loader, glyph_index ); |
| 166 } |
| 167 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 168 |
152 if ( !loader->linear_def ) | 169 if ( !loader->linear_def ) |
153 { | 170 { |
154 loader->linear_def = 1; | 171 loader->linear_def = 1; |
155 loader->linear = advance_width; | 172 loader->linear = advance_width; |
156 } | 173 } |
157 } | 174 } |
158 | 175 |
159 | 176 |
160 #ifdef FT_CONFIG_OPTION_INCREMENTAL | 177 #ifdef FT_CONFIG_OPTION_INCREMENTAL |
161 | 178 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 if ( delta_x ) | 262 if ( delta_x ) |
246 for ( k = 0; k < n; k++ ) | 263 for ( k = 0; k < n; k++ ) |
247 coords[k].x += delta_x; | 264 coords[k].x += delta_x; |
248 | 265 |
249 if ( delta_y ) | 266 if ( delta_y ) |
250 for ( k = 0; k < n; k++ ) | 267 for ( k = 0; k < n; k++ ) |
251 coords[k].y += delta_y; | 268 coords[k].y += delta_y; |
252 } | 269 } |
253 | 270 |
254 | 271 |
255 #undef IS_HINTED | |
256 #define IS_HINTED( flags ) ( ( flags & FT_LOAD_NO_HINTING ) == 0 ) | |
257 | |
258 | |
259 /*************************************************************************/ | 272 /*************************************************************************/ |
260 /* */ | 273 /* */ |
261 /* The following functions are used by default with TrueType fonts. */ | 274 /* The following functions are used by default with TrueType fonts. */ |
262 /* However, they can be replaced by alternatives if we need to support */ | 275 /* However, they can be replaced by alternatives if we need to support */ |
263 /* TrueType-compressed formats (like MicroType) in the future. */ | 276 /* TrueType-compressed formats (like MicroType) in the future. */ |
264 /* */ | 277 /* */ |
265 /*************************************************************************/ | 278 /*************************************************************************/ |
266 | 279 |
267 FT_CALLBACK_DEF( FT_Error ) | 280 FT_CALLBACK_DEF( FT_Error ) |
268 TT_Access_Glyph_Frame( TT_Loader loader, | 281 TT_Access_Glyph_Frame( TT_Loader loader, |
(...skipping 10 matching lines...) Expand all Loading... |
279 | 292 |
280 FT_TRACE4(( "Glyph %ld\n", glyph_index )); | 293 FT_TRACE4(( "Glyph %ld\n", glyph_index )); |
281 | 294 |
282 /* the following line sets the `error' variable through macros! */ | 295 /* the following line sets the `error' variable through macros! */ |
283 if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( byte_count ) ) | 296 if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( byte_count ) ) |
284 return error; | 297 return error; |
285 | 298 |
286 loader->cursor = stream->cursor; | 299 loader->cursor = stream->cursor; |
287 loader->limit = stream->limit; | 300 loader->limit = stream->limit; |
288 | 301 |
289 return TT_Err_Ok; | 302 return FT_Err_Ok; |
290 } | 303 } |
291 | 304 |
292 | 305 |
293 FT_CALLBACK_DEF( void ) | 306 FT_CALLBACK_DEF( void ) |
294 TT_Forget_Glyph_Frame( TT_Loader loader ) | 307 TT_Forget_Glyph_Frame( TT_Loader loader ) |
295 { | 308 { |
296 FT_Stream stream = loader->stream; | 309 FT_Stream stream = loader->stream; |
297 | 310 |
298 | 311 |
299 FT_FRAME_EXIT(); | 312 FT_FRAME_EXIT(); |
300 } | 313 } |
301 | 314 |
302 | 315 |
303 FT_CALLBACK_DEF( FT_Error ) | 316 FT_CALLBACK_DEF( FT_Error ) |
304 TT_Load_Glyph_Header( TT_Loader loader ) | 317 TT_Load_Glyph_Header( TT_Loader loader ) |
305 { | 318 { |
306 FT_Byte* p = loader->cursor; | 319 FT_Byte* p = loader->cursor; |
307 FT_Byte* limit = loader->limit; | 320 FT_Byte* limit = loader->limit; |
308 | 321 |
309 | 322 |
310 if ( p + 10 > limit ) | 323 if ( p + 10 > limit ) |
311 return TT_Err_Invalid_Outline; | 324 return FT_THROW( Invalid_Outline ); |
312 | 325 |
313 loader->n_contours = FT_NEXT_SHORT( p ); | 326 loader->n_contours = FT_NEXT_SHORT( p ); |
314 | 327 |
315 loader->bbox.xMin = FT_NEXT_SHORT( p ); | 328 loader->bbox.xMin = FT_NEXT_SHORT( p ); |
316 loader->bbox.yMin = FT_NEXT_SHORT( p ); | 329 loader->bbox.yMin = FT_NEXT_SHORT( p ); |
317 loader->bbox.xMax = FT_NEXT_SHORT( p ); | 330 loader->bbox.xMax = FT_NEXT_SHORT( p ); |
318 loader->bbox.yMax = FT_NEXT_SHORT( p ); | 331 loader->bbox.yMax = FT_NEXT_SHORT( p ); |
319 | 332 |
320 FT_TRACE5(( " # of contours: %d\n", loader->n_contours )); | 333 FT_TRACE5(( " # of contours: %d\n", loader->n_contours )); |
321 FT_TRACE5(( " xMin: %4d xMax: %4d\n", loader->bbox.xMin, | 334 FT_TRACE5(( " xMin: %4d xMax: %4d\n", loader->bbox.xMin, |
322 loader->bbox.xMax )); | 335 loader->bbox.xMax )); |
323 FT_TRACE5(( " yMin: %4d yMax: %4d\n", loader->bbox.yMin, | 336 FT_TRACE5(( " yMin: %4d yMax: %4d\n", loader->bbox.yMin, |
324 loader->bbox.yMax )); | 337 loader->bbox.yMax )); |
325 loader->cursor = p; | 338 loader->cursor = p; |
326 | 339 |
327 return TT_Err_Ok; | 340 return FT_Err_Ok; |
328 } | 341 } |
329 | 342 |
330 | 343 |
331 FT_CALLBACK_DEF( FT_Error ) | 344 FT_CALLBACK_DEF( FT_Error ) |
332 TT_Load_Simple_Glyph( TT_Loader load ) | 345 TT_Load_Simple_Glyph( TT_Loader load ) |
333 { | 346 { |
334 FT_Error error; | 347 FT_Error error; |
335 FT_Byte* p = load->cursor; | 348 FT_Byte* p = load->cursor; |
336 FT_Byte* limit = load->limit; | 349 FT_Byte* limit = load->limit; |
337 FT_GlyphLoader gloader = load->gloader; | 350 FT_GlyphLoader gloader = load->gloader; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 goto Invalid_Outline; | 415 goto Invalid_Outline; |
403 | 416 |
404 n_ins = FT_NEXT_USHORT( p ); | 417 n_ins = FT_NEXT_USHORT( p ); |
405 | 418 |
406 FT_TRACE5(( " Instructions size: %u\n", n_ins )); | 419 FT_TRACE5(( " Instructions size: %u\n", n_ins )); |
407 | 420 |
408 if ( n_ins > face->max_profile.maxSizeOfInstructions ) | 421 if ( n_ins > face->max_profile.maxSizeOfInstructions ) |
409 { | 422 { |
410 FT_TRACE0(( "TT_Load_Simple_Glyph: too many instructions (%d)\n", | 423 FT_TRACE0(( "TT_Load_Simple_Glyph: too many instructions (%d)\n", |
411 n_ins )); | 424 n_ins )); |
412 error = TT_Err_Too_Many_Hints; | 425 error = FT_THROW( Too_Many_Hints ); |
413 goto Fail; | 426 goto Fail; |
414 } | 427 } |
415 | 428 |
416 if ( ( limit - p ) < n_ins ) | 429 if ( ( limit - p ) < n_ins ) |
417 { | 430 { |
418 FT_TRACE0(( "TT_Load_Simple_Glyph: instruction count mismatch\n" )); | 431 FT_TRACE0(( "TT_Load_Simple_Glyph: instruction count mismatch\n" )); |
419 error = TT_Err_Too_Many_Hints; | 432 error = FT_THROW( Too_Many_Hints ); |
420 goto Fail; | 433 goto Fail; |
421 } | 434 } |
422 | 435 |
423 #ifdef TT_USE_BYTECODE_INTERPRETER | 436 #ifdef TT_USE_BYTECODE_INTERPRETER |
424 | 437 |
425 if ( IS_HINTED( load->load_flags ) ) | 438 if ( IS_HINTED( load->load_flags ) ) |
426 { | 439 { |
427 load->glyph->control_len = n_ins; | 440 load->glyph->control_len = n_ins; |
428 load->glyph->control_data = load->exec->glyphIns; | 441 load->glyph->control_data = load->exec->glyphIns; |
429 | 442 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
539 | 552 |
540 outline->n_points = (FT_UShort)n_points; | 553 outline->n_points = (FT_UShort)n_points; |
541 outline->n_contours = (FT_Short) n_contours; | 554 outline->n_contours = (FT_Short) n_contours; |
542 | 555 |
543 load->cursor = p; | 556 load->cursor = p; |
544 | 557 |
545 Fail: | 558 Fail: |
546 return error; | 559 return error; |
547 | 560 |
548 Invalid_Outline: | 561 Invalid_Outline: |
549 error = TT_Err_Invalid_Outline; | 562 error = FT_THROW( Invalid_Outline ); |
550 goto Fail; | 563 goto Fail; |
551 } | 564 } |
552 | 565 |
553 | 566 |
554 FT_CALLBACK_DEF( FT_Error ) | 567 FT_CALLBACK_DEF( FT_Error ) |
555 TT_Load_Composite_Glyph( TT_Loader loader ) | 568 TT_Load_Composite_Glyph( TT_Loader loader ) |
556 { | 569 { |
557 FT_Error error; | 570 FT_Error error; |
558 FT_Byte* p = loader->cursor; | 571 FT_Byte* p = loader->cursor; |
559 FT_Byte* limit = loader->limit; | 572 FT_Byte* limit = loader->limit; |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
660 } | 673 } |
661 | 674 |
662 #endif | 675 #endif |
663 | 676 |
664 loader->cursor = p; | 677 loader->cursor = p; |
665 | 678 |
666 Fail: | 679 Fail: |
667 return error; | 680 return error; |
668 | 681 |
669 Invalid_Composite: | 682 Invalid_Composite: |
670 error = TT_Err_Invalid_Composite; | 683 error = FT_THROW( Invalid_Composite ); |
671 goto Fail; | 684 goto Fail; |
672 } | 685 } |
673 | 686 |
674 | 687 |
675 FT_LOCAL_DEF( void ) | 688 FT_LOCAL_DEF( void ) |
676 TT_Init_Glyph_Loading( TT_Face face ) | 689 TT_Init_Glyph_Loading( TT_Face face ) |
677 { | 690 { |
678 face->access_glyph_frame = TT_Access_Glyph_Frame; | 691 face->access_glyph_frame = TT_Access_Glyph_Frame; |
679 face->read_glyph_header = TT_Load_Glyph_Header; | 692 face->read_glyph_header = TT_Load_Glyph_Header; |
680 face->read_simple_glyph = TT_Load_Simple_Glyph; | 693 face->read_simple_glyph = TT_Load_Simple_Glyph; |
(...skipping 26 matching lines...) Expand all Loading... |
707 /* TT_Hint_Glyph */ | 720 /* TT_Hint_Glyph */ |
708 /* */ | 721 /* */ |
709 /* <Description> */ | 722 /* <Description> */ |
710 /* Hint the glyph using the zone prepared by the caller. Note that */ | 723 /* Hint the glyph using the zone prepared by the caller. Note that */ |
711 /* the zone is supposed to include four phantom points. */ | 724 /* the zone is supposed to include four phantom points. */ |
712 /* */ | 725 /* */ |
713 static FT_Error | 726 static FT_Error |
714 TT_Hint_Glyph( TT_Loader loader, | 727 TT_Hint_Glyph( TT_Loader loader, |
715 FT_Bool is_composite ) | 728 FT_Bool is_composite ) |
716 { | 729 { |
| 730 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 731 TT_Face face = (TT_Face)loader->face; |
| 732 TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); |
| 733 #endif |
| 734 |
717 TT_GlyphZone zone = &loader->zone; | 735 TT_GlyphZone zone = &loader->zone; |
718 FT_Pos origin; | 736 FT_Pos origin; |
719 | 737 |
720 #ifdef TT_USE_BYTECODE_INTERPRETER | 738 #ifdef TT_USE_BYTECODE_INTERPRETER |
721 FT_UInt n_ins; | 739 FT_UInt n_ins; |
722 #else | 740 #else |
723 FT_UNUSED( is_composite ); | 741 FT_UNUSED( is_composite ); |
724 #endif | 742 #endif |
725 | 743 |
726 | 744 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
806 | 824 |
807 /* save glyph phantom points */ | 825 /* save glyph phantom points */ |
808 if ( !loader->preserve_pps ) | 826 if ( !loader->preserve_pps ) |
809 { | 827 { |
810 loader->pp1 = zone->cur[zone->n_points - 4]; | 828 loader->pp1 = zone->cur[zone->n_points - 4]; |
811 loader->pp2 = zone->cur[zone->n_points - 3]; | 829 loader->pp2 = zone->cur[zone->n_points - 3]; |
812 loader->pp3 = zone->cur[zone->n_points - 2]; | 830 loader->pp3 = zone->cur[zone->n_points - 2]; |
813 loader->pp4 = zone->cur[zone->n_points - 1]; | 831 loader->pp4 = zone->cur[zone->n_points - 1]; |
814 } | 832 } |
815 | 833 |
816 return TT_Err_Ok; | 834 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 835 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) |
| 836 { |
| 837 if ( loader->exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN ) |
| 838 FT_Outline_EmboldenXY( &loader->gloader->current.outline, -24, 0 ); |
| 839 |
| 840 else if ( loader->exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN ) |
| 841 FT_Outline_EmboldenXY( &loader->gloader->current.outline, 24, 0 ); |
| 842 } |
| 843 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 844 |
| 845 return FT_Err_Ok; |
817 } | 846 } |
818 | 847 |
819 | 848 |
820 /*************************************************************************/ | 849 /*************************************************************************/ |
821 /* */ | 850 /* */ |
822 /* <Function> */ | 851 /* <Function> */ |
823 /* TT_Process_Simple_Glyph */ | 852 /* TT_Process_Simple_Glyph */ |
824 /* */ | 853 /* */ |
825 /* <Description> */ | 854 /* <Description> */ |
826 /* Once a simple glyph has been loaded, it needs to be processed. */ | 855 /* Once a simple glyph has been loaded, it needs to be processed. */ |
827 /* Usually, this means scaling and hinting through bytecode */ | 856 /* Usually, this means scaling and hinting through bytecode */ |
828 /* interpretation. */ | 857 /* interpretation. */ |
829 /* */ | 858 /* */ |
830 static FT_Error | 859 static FT_Error |
831 TT_Process_Simple_Glyph( TT_Loader loader ) | 860 TT_Process_Simple_Glyph( TT_Loader loader ) |
832 { | 861 { |
833 FT_GlyphLoader gloader = loader->gloader; | 862 FT_GlyphLoader gloader = loader->gloader; |
834 FT_Error error = TT_Err_Ok; | 863 FT_Error error = FT_Err_Ok; |
835 FT_Outline* outline; | 864 FT_Outline* outline; |
836 FT_Int n_points; | 865 FT_Int n_points; |
837 | 866 |
838 | 867 |
839 outline = &gloader->current.outline; | 868 outline = &gloader->current.outline; |
840 n_points = outline->n_points; | 869 n_points = outline->n_points; |
841 | 870 |
842 /* set phantom points */ | 871 /* set phantom points */ |
843 | 872 |
844 outline->points[n_points ] = loader->pp1; | 873 outline->points[n_points ] = loader->pp1; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
882 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ | 911 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ |
883 | 912 |
884 if ( IS_HINTED( loader->load_flags ) ) | 913 if ( IS_HINTED( loader->load_flags ) ) |
885 { | 914 { |
886 tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 ); | 915 tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 ); |
887 | 916 |
888 FT_ARRAY_COPY( loader->zone.orus, loader->zone.cur, | 917 FT_ARRAY_COPY( loader->zone.orus, loader->zone.cur, |
889 loader->zone.n_points + 4 ); | 918 loader->zone.n_points + 4 ); |
890 } | 919 } |
891 | 920 |
892 /* scale the glyph */ | |
893 if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) | |
894 { | 921 { |
895 FT_Vector* vec = outline->points; | 922 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
896 FT_Vector* limit = outline->points + n_points; | 923 TT_Face face = (TT_Face)loader->face; |
897 FT_Fixed x_scale = ((TT_Size)loader->size)->metrics.x_scale; | 924 TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); |
898 FT_Fixed y_scale = ((TT_Size)loader->size)->metrics.y_scale; | 925 |
| 926 FT_String* family = face->root.family_name; |
| 927 FT_Int ppem = loader->size->metrics.x_ppem; |
| 928 FT_String* style = face->root.style_name; |
| 929 FT_Int x_scale_factor = 1000; |
| 930 #endif |
| 931 |
| 932 FT_Vector* vec = outline->points; |
| 933 FT_Vector* limit = outline->points + n_points; |
| 934 |
| 935 FT_Fixed x_scale = 0; /* pacify compiler */ |
| 936 FT_Fixed y_scale = 0; |
| 937 |
| 938 FT_Bool do_scale = FALSE; |
899 | 939 |
900 | 940 |
901 for ( ; vec < limit; vec++ ) | 941 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 942 |
| 943 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) |
902 { | 944 { |
903 vec->x = FT_MulFix( vec->x, x_scale ); | 945 /* scale, but only if enabled and only if TT hinting is being used */ |
904 vec->y = FT_MulFix( vec->y, y_scale ); | 946 if ( IS_HINTED( loader->load_flags ) ) |
| 947 x_scale_factor = sph_test_tweak_x_scaling( face, |
| 948 family, |
| 949 ppem, |
| 950 style, |
| 951 loader->glyph_index ); |
| 952 /* scale the glyph */ |
| 953 if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 || |
| 954 x_scale_factor != 1000 ) |
| 955 { |
| 956 x_scale = FT_MulDiv( ((TT_Size)loader->size)->metrics.x_scale, |
| 957 x_scale_factor, 1000 ); |
| 958 y_scale = ((TT_Size)loader->size)->metrics.y_scale; |
| 959 |
| 960 /* compensate for any scaling by de/emboldening; */ |
| 961 /* the amount was determined via experimentation */ |
| 962 if ( x_scale_factor != 1000 && ppem > 11 ) |
| 963 FT_Outline_EmboldenXY( outline, |
| 964 FT_MulFix( 1280 * ppem, |
| 965 1000 - x_scale_factor ), |
| 966 0 ); |
| 967 do_scale = TRUE; |
| 968 } |
| 969 } |
| 970 else |
| 971 |
| 972 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 973 |
| 974 { |
| 975 /* scale the glyph */ |
| 976 if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) |
| 977 { |
| 978 x_scale = ((TT_Size)loader->size)->metrics.x_scale; |
| 979 y_scale = ((TT_Size)loader->size)->metrics.y_scale; |
| 980 |
| 981 do_scale = TRUE; |
| 982 } |
905 } | 983 } |
906 | 984 |
907 loader->pp1 = outline->points[n_points - 4]; | 985 if ( do_scale ) |
908 loader->pp2 = outline->points[n_points - 3]; | 986 { |
909 loader->pp3 = outline->points[n_points - 2]; | 987 for ( ; vec < limit; vec++ ) |
910 loader->pp4 = outline->points[n_points - 1]; | 988 { |
| 989 vec->x = FT_MulFix( vec->x, x_scale ); |
| 990 vec->y = FT_MulFix( vec->y, y_scale ); |
| 991 } |
| 992 |
| 993 loader->pp1 = outline->points[n_points - 4]; |
| 994 loader->pp2 = outline->points[n_points - 3]; |
| 995 loader->pp3 = outline->points[n_points - 2]; |
| 996 loader->pp4 = outline->points[n_points - 1]; |
| 997 } |
911 } | 998 } |
912 | 999 |
913 if ( IS_HINTED( loader->load_flags ) ) | 1000 if ( IS_HINTED( loader->load_flags ) ) |
914 { | 1001 { |
915 loader->zone.n_points += 4; | 1002 loader->zone.n_points += 4; |
916 | 1003 |
917 error = TT_Hint_Glyph( loader, 0 ); | 1004 error = TT_Hint_Glyph( loader, 0 ); |
918 } | 1005 } |
919 | 1006 |
920 return error; | 1007 return error; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
967 | 1054 |
968 | 1055 |
969 /* match l-th point of the newly loaded component to the k-th point */ | 1056 /* match l-th point of the newly loaded component to the k-th point */ |
970 /* of the previously loaded components. */ | 1057 /* of the previously loaded components. */ |
971 | 1058 |
972 /* change to the point numbers used by our outline */ | 1059 /* change to the point numbers used by our outline */ |
973 k += start_point; | 1060 k += start_point; |
974 l += num_base_points; | 1061 l += num_base_points; |
975 if ( k >= num_base_points || | 1062 if ( k >= num_base_points || |
976 l >= num_points ) | 1063 l >= num_points ) |
977 return TT_Err_Invalid_Composite; | 1064 return FT_THROW( Invalid_Composite ); |
978 | 1065 |
979 p1 = gloader->base.outline.points + k; | 1066 p1 = gloader->base.outline.points + k; |
980 p2 = gloader->base.outline.points + l; | 1067 p2 = gloader->base.outline.points + l; |
981 | 1068 |
982 x = p1->x - p2->x; | 1069 x = p1->x - p2->x; |
983 y = p1->y - p2->y; | 1070 y = p1->y - p2->y; |
984 } | 1071 } |
985 else | 1072 else |
986 { | 1073 { |
987 x = subglyph->arg1; | 1074 x = subglyph->arg1; |
988 y = subglyph->arg2; | 1075 y = subglyph->arg2; |
989 | 1076 |
990 if ( !x && !y ) | 1077 if ( !x && !y ) |
991 return TT_Err_Ok; | 1078 return FT_Err_Ok; |
992 | 1079 |
993 /* Use a default value dependent on */ | 1080 /* Use a default value dependent on */ |
994 /* TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED. This is useful for old TT */ | 1081 /* TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED. This is useful for old TT */ |
995 /* fonts which don't set the xxx_COMPONENT_OFFSET bit. */ | 1082 /* fonts which don't set the xxx_COMPONENT_OFFSET bit. */ |
996 | 1083 |
997 if ( have_scale && | 1084 if ( have_scale && |
998 #ifdef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED | 1085 #ifdef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED |
999 !( subglyph->flags & UNSCALED_COMPONENT_OFFSET ) ) | 1086 !( subglyph->flags & UNSCALED_COMPONENT_OFFSET ) ) |
1000 #else | 1087 #else |
1001 ( subglyph->flags & SCALED_COMPONENT_OFFSET ) ) | 1088 ( subglyph->flags & SCALED_COMPONENT_OFFSET ) ) |
(...skipping 24 matching lines...) Expand all Loading... |
1026 n *= 2; | 1113 n *= 2; |
1027 x = FT_MulFix( x, m ); | 1114 x = FT_MulFix( x, m ); |
1028 y = FT_MulFix( y, n ); | 1115 y = FT_MulFix( y, n ); |
1029 | 1116 |
1030 #else /* 0 */ | 1117 #else /* 0 */ |
1031 | 1118 |
1032 /*************************************************************************/ | 1119 /*************************************************************************/ |
1033 /* */ | 1120 /* */ |
1034 /* This algorithm is a guess and works much better than the above. */ | 1121 /* This algorithm is a guess and works much better than the above. */ |
1035 /* */ | 1122 /* */ |
1036 FT_Fixed mac_xscale = FT_SqrtFixed( | 1123 FT_Fixed mac_xscale = FT_Hypot( subglyph->transform.xx, |
1037 (FT_Int32)FT_MulFix( subglyph->transform.xx, | 1124 subglyph->transform.xy ); |
1038 subglyph->transform.xx ) + | 1125 FT_Fixed mac_yscale = FT_Hypot( subglyph->transform.yy, |
1039 (FT_Int32)FT_MulFix( subglyph->transform.xy, | 1126 subglyph->transform.yx ); |
1040 subglyph->transform.xy ) )
; | |
1041 FT_Fixed mac_yscale = FT_SqrtFixed( | |
1042 (FT_Int32)FT_MulFix( subglyph->transform.yy, | |
1043 subglyph->transform.yy ) + | |
1044 (FT_Int32)FT_MulFix( subglyph->transform.yx, | |
1045 subglyph->transform.yx ) )
; | |
1046 | 1127 |
1047 | 1128 |
1048 x = FT_MulFix( x, mac_xscale ); | 1129 x = FT_MulFix( x, mac_xscale ); |
1049 y = FT_MulFix( y, mac_yscale ); | 1130 y = FT_MulFix( y, mac_yscale ); |
1050 | 1131 |
1051 #endif /* 0 */ | 1132 #endif /* 0 */ |
1052 | 1133 |
1053 } | 1134 } |
1054 | 1135 |
1055 if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) ) | 1136 if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) ) |
(...skipping 11 matching lines...) Expand all Loading... |
1067 y = FT_PIX_ROUND( y ); | 1148 y = FT_PIX_ROUND( y ); |
1068 } | 1149 } |
1069 } | 1150 } |
1070 } | 1151 } |
1071 | 1152 |
1072 if ( x || y ) | 1153 if ( x || y ) |
1073 translate_array( num_points - num_base_points, | 1154 translate_array( num_points - num_base_points, |
1074 base_vec + num_base_points, | 1155 base_vec + num_base_points, |
1075 x, y ); | 1156 x, y ); |
1076 | 1157 |
1077 return TT_Err_Ok; | 1158 return FT_Err_Ok; |
1078 } | 1159 } |
1079 | 1160 |
1080 | 1161 |
1081 /*************************************************************************/ | 1162 /*************************************************************************/ |
1082 /* */ | 1163 /* */ |
1083 /* <Function> */ | 1164 /* <Function> */ |
1084 /* TT_Process_Composite_Glyph */ | 1165 /* TT_Process_Composite_Glyph */ |
1085 /* */ | 1166 /* */ |
1086 /* <Description> */ | 1167 /* <Description> */ |
1087 /* This is slightly different from TT_Process_Simple_Glyph, in that */ | 1168 /* This is slightly different from TT_Process_Simple_Glyph, in that */ |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1136 /* check it */ | 1217 /* check it */ |
1137 max_ins = ((TT_Face)loader->face)->max_profile.maxSizeOfInstructions; | 1218 max_ins = ((TT_Face)loader->face)->max_profile.maxSizeOfInstructions; |
1138 if ( n_ins > max_ins ) | 1219 if ( n_ins > max_ins ) |
1139 { | 1220 { |
1140 /* acroread ignores this field, so we only do a rough safety check */ | 1221 /* acroread ignores this field, so we only do a rough safety check */ |
1141 if ( (FT_Int)n_ins > loader->byte_len ) | 1222 if ( (FT_Int)n_ins > loader->byte_len ) |
1142 { | 1223 { |
1143 FT_TRACE1(( "TT_Process_Composite_Glyph: " | 1224 FT_TRACE1(( "TT_Process_Composite_Glyph: " |
1144 "too many instructions (%d) for glyph with length %d\n", | 1225 "too many instructions (%d) for glyph with length %d\n", |
1145 n_ins, loader->byte_len )); | 1226 n_ins, loader->byte_len )); |
1146 return TT_Err_Too_Many_Hints; | 1227 return FT_THROW( Too_Many_Hints ); |
1147 } | 1228 } |
1148 | 1229 |
1149 tmp = loader->exec->glyphSize; | 1230 tmp = loader->exec->glyphSize; |
1150 error = Update_Max( loader->exec->memory, | 1231 error = Update_Max( loader->exec->memory, |
1151 &tmp, | 1232 &tmp, |
1152 sizeof ( FT_Byte ), | 1233 sizeof ( FT_Byte ), |
1153 (void*)&loader->exec->glyphIns, | 1234 (void*)&loader->exec->glyphIns, |
1154 n_ins ); | 1235 n_ins ); |
1155 loader->exec->glyphSize = (FT_UShort)tmp; | 1236 loader->exec->glyphSize = (FT_UShort)tmp; |
1156 if ( error ) | 1237 if ( error ) |
1157 return error; | 1238 return error; |
1158 } | 1239 } |
1159 else if ( n_ins == 0 ) | 1240 else if ( n_ins == 0 ) |
1160 return TT_Err_Ok; | 1241 return FT_Err_Ok; |
1161 | 1242 |
1162 if ( FT_STREAM_READ( loader->exec->glyphIns, n_ins ) ) | 1243 if ( FT_STREAM_READ( loader->exec->glyphIns, n_ins ) ) |
1163 return error; | 1244 return error; |
1164 | 1245 |
1165 loader->glyph->control_data = loader->exec->glyphIns; | 1246 loader->glyph->control_data = loader->exec->glyphIns; |
1166 loader->glyph->control_len = n_ins; | 1247 loader->glyph->control_len = n_ins; |
1167 } | 1248 } |
1168 | 1249 |
1169 #endif | 1250 #endif |
1170 | 1251 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1206 /* <Description> */ | 1287 /* <Description> */ |
1207 /* Loads a given truetype glyph. Handles composites and uses a */ | 1288 /* Loads a given truetype glyph. Handles composites and uses a */ |
1208 /* TT_Loader object. */ | 1289 /* TT_Loader object. */ |
1209 /* */ | 1290 /* */ |
1210 static FT_Error | 1291 static FT_Error |
1211 load_truetype_glyph( TT_Loader loader, | 1292 load_truetype_glyph( TT_Loader loader, |
1212 FT_UInt glyph_index, | 1293 FT_UInt glyph_index, |
1213 FT_UInt recurse_count, | 1294 FT_UInt recurse_count, |
1214 FT_Bool header_only ) | 1295 FT_Bool header_only ) |
1215 { | 1296 { |
1216 FT_Error error = TT_Err_Ok; | 1297 FT_Error error = FT_Err_Ok; |
1217 FT_Fixed x_scale, y_scale; | 1298 FT_Fixed x_scale, y_scale; |
1218 FT_ULong offset; | 1299 FT_ULong offset; |
1219 TT_Face face = (TT_Face)loader->face; | 1300 TT_Face face = (TT_Face)loader->face; |
1220 FT_GlyphLoader gloader = loader->gloader; | 1301 FT_GlyphLoader gloader = loader->gloader; |
1221 FT_Bool opened_frame = 0; | 1302 FT_Bool opened_frame = 0; |
1222 | 1303 |
1223 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT | 1304 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
1224 FT_Vector* deltas = NULL; | 1305 FT_Vector* deltas = NULL; |
1225 #endif | 1306 #endif |
1226 | 1307 |
1227 #ifdef FT_CONFIG_OPTION_INCREMENTAL | 1308 #ifdef FT_CONFIG_OPTION_INCREMENTAL |
1228 FT_StreamRec inc_stream; | 1309 FT_StreamRec inc_stream; |
1229 FT_Data glyph_data; | 1310 FT_Data glyph_data; |
1230 FT_Bool glyph_data_loaded = 0; | 1311 FT_Bool glyph_data_loaded = 0; |
1231 #endif | 1312 #endif |
1232 | 1313 |
1233 | 1314 |
1234 /* some fonts have an incorrect value of `maxComponentDepth', */ | 1315 /* some fonts have an incorrect value of `maxComponentDepth', */ |
1235 /* thus we allow depth 1 to catch the majority of them */ | 1316 /* thus we allow depth 1 to catch the majority of them */ |
1236 if ( recurse_count > 1 && | 1317 if ( recurse_count > 1 && |
1237 recurse_count > face->max_profile.maxComponentDepth ) | 1318 recurse_count > face->max_profile.maxComponentDepth ) |
1238 { | 1319 { |
1239 error = TT_Err_Invalid_Composite; | 1320 error = FT_THROW( Invalid_Composite ); |
1240 goto Exit; | 1321 goto Exit; |
1241 } | 1322 } |
1242 | 1323 |
1243 /* check glyph index */ | 1324 /* check glyph index */ |
1244 if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) | 1325 if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) |
1245 { | 1326 { |
1246 error = TT_Err_Invalid_Glyph_Index; | 1327 error = FT_THROW( Invalid_Glyph_Index ); |
1247 goto Exit; | 1328 goto Exit; |
1248 } | 1329 } |
1249 | 1330 |
1250 loader->glyph_index = glyph_index; | 1331 loader->glyph_index = glyph_index; |
1251 | 1332 |
1252 if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) | 1333 if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) |
1253 { | 1334 { |
1254 x_scale = ((TT_Size)loader->size)->metrics.x_scale; | 1335 x_scale = ((TT_Size)loader->size)->metrics.x_scale; |
1255 y_scale = ((TT_Size)loader->size)->metrics.y_scale; | 1336 y_scale = ((TT_Size)loader->size)->metrics.y_scale; |
1256 } | 1337 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1300 { | 1381 { |
1301 #ifdef FT_CONFIG_OPTION_INCREMENTAL | 1382 #ifdef FT_CONFIG_OPTION_INCREMENTAL |
1302 /* for the incremental interface, `glyf_offset' is always zero */ | 1383 /* for the incremental interface, `glyf_offset' is always zero */ |
1303 if ( !loader->glyf_offset && | 1384 if ( !loader->glyf_offset && |
1304 !face->root.internal->incremental_interface ) | 1385 !face->root.internal->incremental_interface ) |
1305 #else | 1386 #else |
1306 if ( !loader->glyf_offset ) | 1387 if ( !loader->glyf_offset ) |
1307 #endif /* FT_CONFIG_OPTION_INCREMENTAL */ | 1388 #endif /* FT_CONFIG_OPTION_INCREMENTAL */ |
1308 { | 1389 { |
1309 FT_TRACE2(( "no `glyf' table but non-zero `loca' entry\n" )); | 1390 FT_TRACE2(( "no `glyf' table but non-zero `loca' entry\n" )); |
1310 error = TT_Err_Invalid_Table; | 1391 error = FT_THROW( Invalid_Table ); |
1311 goto Exit; | 1392 goto Exit; |
1312 } | 1393 } |
1313 | 1394 |
1314 error = face->access_glyph_frame( loader, glyph_index, | 1395 error = face->access_glyph_frame( loader, glyph_index, |
1315 loader->glyf_offset + offset, | 1396 loader->glyf_offset + offset, |
1316 loader->byte_len ); | 1397 loader->byte_len ); |
1317 if ( error ) | 1398 if ( error ) |
1318 goto Exit; | 1399 goto Exit; |
1319 | 1400 |
1320 opened_frame = 1; | 1401 opened_frame = 1; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1367 #endif | 1448 #endif |
1368 | 1449 |
1369 if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) | 1450 if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) |
1370 { | 1451 { |
1371 loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale ); | 1452 loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale ); |
1372 loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); | 1453 loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); |
1373 loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale ); | 1454 loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale ); |
1374 loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale ); | 1455 loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale ); |
1375 } | 1456 } |
1376 | 1457 |
1377 error = TT_Err_Ok; | 1458 error = FT_Err_Ok; |
1378 goto Exit; | 1459 goto Exit; |
1379 } | 1460 } |
1380 | 1461 |
1381 /* must initialize points before (possibly) overriding */ | 1462 /* must initialize points before (possibly) overriding */ |
1382 /* glyph metrics from the incremental interface */ | 1463 /* glyph metrics from the incremental interface */ |
1383 TT_LOADER_SET_PP( loader ); | 1464 TT_LOADER_SET_PP( loader ); |
1384 | 1465 |
1385 #ifdef FT_CONFIG_OPTION_INCREMENTAL | 1466 #ifdef FT_CONFIG_OPTION_INCREMENTAL |
1386 tt_get_metrics_incr_overrides( loader, glyph_index ); | 1467 tt_get_metrics_incr_overrides( loader, glyph_index ); |
1387 #endif | 1468 #endif |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1581 #endif | 1662 #endif |
1582 | 1663 |
1583 num_points > start_point ) | 1664 num_points > start_point ) |
1584 TT_Process_Composite_Glyph( loader, start_point, start_contour ); | 1665 TT_Process_Composite_Glyph( loader, start_point, start_contour ); |
1585 | 1666 |
1586 } | 1667 } |
1587 } | 1668 } |
1588 else | 1669 else |
1589 { | 1670 { |
1590 /* invalid composite count (negative but not -1) */ | 1671 /* invalid composite count (negative but not -1) */ |
1591 error = TT_Err_Invalid_Outline; | 1672 error = FT_THROW( Invalid_Outline ); |
1592 goto Exit; | 1673 goto Exit; |
1593 } | 1674 } |
1594 | 1675 |
1595 /***********************************************************************/ | 1676 /***********************************************************************/ |
1596 /***********************************************************************/ | 1677 /***********************************************************************/ |
1597 /***********************************************************************/ | 1678 /***********************************************************************/ |
1598 | 1679 |
1599 Exit: | 1680 Exit: |
1600 | 1681 |
1601 if ( opened_frame ) | 1682 if ( opened_frame ) |
1602 face->forget_glyph_frame( loader ); | 1683 face->forget_glyph_frame( loader ); |
1603 | 1684 |
1604 #ifdef FT_CONFIG_OPTION_INCREMENTAL | 1685 #ifdef FT_CONFIG_OPTION_INCREMENTAL |
1605 | 1686 |
1606 if ( glyph_data_loaded ) | 1687 if ( glyph_data_loaded ) |
1607 face->root.internal->incremental_interface->funcs->free_glyph_data( | 1688 face->root.internal->incremental_interface->funcs->free_glyph_data( |
1608 face->root.internal->incremental_interface->object, | 1689 face->root.internal->incremental_interface->object, |
1609 &glyph_data ); | 1690 &glyph_data ); |
1610 | 1691 |
1611 #endif | 1692 #endif |
1612 | 1693 |
1613 return error; | 1694 return error; |
1614 } | 1695 } |
1615 | 1696 |
1616 | 1697 |
1617 static FT_Error | 1698 static FT_Error |
1618 compute_glyph_metrics( TT_Loader loader, | 1699 compute_glyph_metrics( TT_Loader loader, |
1619 FT_UInt glyph_index ) | 1700 FT_UInt glyph_index ) |
1620 { | 1701 { |
| 1702 TT_Face face = (TT_Face)loader->face; |
| 1703 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 1704 TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); |
| 1705 #endif |
| 1706 |
1621 FT_BBox bbox; | 1707 FT_BBox bbox; |
1622 TT_Face face = (TT_Face)loader->face; | |
1623 FT_Fixed y_scale; | 1708 FT_Fixed y_scale; |
1624 TT_GlyphSlot glyph = loader->glyph; | 1709 TT_GlyphSlot glyph = loader->glyph; |
1625 TT_Size size = (TT_Size)loader->size; | 1710 TT_Size size = (TT_Size)loader->size; |
1626 | 1711 |
1627 | 1712 |
1628 y_scale = 0x10000L; | 1713 y_scale = 0x10000L; |
1629 if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) | 1714 if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) |
1630 y_scale = size->root.metrics.y_scale; | 1715 y_scale = size->root.metrics.y_scale; |
1631 | 1716 |
1632 if ( glyph->format != FT_GLYPH_FORMAT_COMPOSITE ) | 1717 if ( glyph->format != FT_GLYPH_FORMAT_COMPOSITE ) |
1633 FT_Outline_Get_CBox( &glyph->outline, &bbox ); | 1718 FT_Outline_Get_CBox( &glyph->outline, &bbox ); |
1634 else | 1719 else |
1635 bbox = loader->bbox; | 1720 bbox = loader->bbox; |
(...skipping 10 matching lines...) Expand all Loading... |
1646 if ( !face->postscript.isFixedPitch && | 1731 if ( !face->postscript.isFixedPitch && |
1647 IS_HINTED( loader->load_flags ) ) | 1732 IS_HINTED( loader->load_flags ) ) |
1648 { | 1733 { |
1649 FT_Byte* widthp; | 1734 FT_Byte* widthp; |
1650 | 1735 |
1651 | 1736 |
1652 widthp = tt_face_get_device_metrics( face, | 1737 widthp = tt_face_get_device_metrics( face, |
1653 size->root.metrics.x_ppem, | 1738 size->root.metrics.x_ppem, |
1654 glyph_index ); | 1739 glyph_index ); |
1655 | 1740 |
1656 if ( widthp ) | 1741 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
1657 glyph->metrics.horiAdvance = *widthp << 6; | 1742 |
| 1743 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) |
| 1744 { |
| 1745 FT_Bool ignore_x_mode; |
| 1746 |
| 1747 |
| 1748 ignore_x_mode = FT_BOOL( FT_LOAD_TARGET_MODE( loader->load_flags ) != |
| 1749 FT_RENDER_MODE_MONO ); |
| 1750 |
| 1751 if ( widthp && |
| 1752 ( ( ignore_x_mode && loader->exec->compatible_widths ) || |
| 1753 !ignore_x_mode || |
| 1754 SPH_OPTION_BITMAP_WIDTHS ) ) |
| 1755 glyph->metrics.horiAdvance = *widthp << 6; |
| 1756 } |
| 1757 else |
| 1758 |
| 1759 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 1760 |
| 1761 { |
| 1762 if ( widthp ) |
| 1763 glyph->metrics.horiAdvance = *widthp << 6; |
| 1764 } |
1658 } | 1765 } |
1659 | 1766 |
1660 /* set glyph dimensions */ | 1767 /* set glyph dimensions */ |
1661 glyph->metrics.width = bbox.xMax - bbox.xMin; | 1768 glyph->metrics.width = bbox.xMax - bbox.xMin; |
1662 glyph->metrics.height = bbox.yMax - bbox.yMin; | 1769 glyph->metrics.height = bbox.yMax - bbox.yMin; |
1663 | 1770 |
1664 /* Now take care of vertical metrics. In the case where there is */ | 1771 /* Now take care of vertical metrics. In the case where there is */ |
1665 /* no vertical information within the font (relatively common), */ | 1772 /* no vertical information within the font (relatively common), */ |
1666 /* create some metrics manually */ | 1773 /* create some metrics manually */ |
1667 { | 1774 { |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1826 | 1933 |
1827 static FT_Error | 1934 static FT_Error |
1828 tt_loader_init( TT_Loader loader, | 1935 tt_loader_init( TT_Loader loader, |
1829 TT_Size size, | 1936 TT_Size size, |
1830 TT_GlyphSlot glyph, | 1937 TT_GlyphSlot glyph, |
1831 FT_Int32 load_flags, | 1938 FT_Int32 load_flags, |
1832 FT_Bool glyf_table_only ) | 1939 FT_Bool glyf_table_only ) |
1833 { | 1940 { |
1834 TT_Face face; | 1941 TT_Face face; |
1835 FT_Stream stream; | 1942 FT_Stream stream; |
| 1943 #ifdef TT_USE_BYTECODE_INTERPRETER |
1836 FT_Bool pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC ); | 1944 FT_Bool pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC ); |
| 1945 #endif |
1837 | 1946 |
1838 | 1947 |
1839 face = (TT_Face)glyph->face; | 1948 face = (TT_Face)glyph->face; |
1840 stream = face->root.stream; | 1949 stream = face->root.stream; |
1841 | 1950 |
1842 FT_MEM_ZERO( loader, sizeof ( TT_LoaderRec ) ); | 1951 FT_MEM_ZERO( loader, sizeof ( TT_LoaderRec ) ); |
1843 | 1952 |
1844 #ifdef TT_USE_BYTECODE_INTERPRETER | 1953 #ifdef TT_USE_BYTECODE_INTERPRETER |
1845 | 1954 |
1846 /* load execution context */ | 1955 /* load execution context */ |
1847 if ( IS_HINTED( load_flags ) && !glyf_table_only ) | 1956 if ( IS_HINTED( load_flags ) && !glyf_table_only ) |
1848 { | 1957 { |
1849 TT_ExecContext exec; | 1958 TT_ExecContext exec; |
1850 FT_Bool grayscale; | 1959 FT_Bool grayscale; |
1851 | 1960 |
| 1961 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
| 1962 TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); |
| 1963 |
| 1964 FT_Bool subpixel_hinting = FALSE; |
| 1965 FT_Bool grayscale_hinting = TRUE; |
| 1966 |
| 1967 #if 0 |
| 1968 /* not used yet */ |
| 1969 FT_Bool compatible_widths; |
| 1970 FT_Bool symmetrical_smoothing; |
| 1971 FT_Bool bgr; |
| 1972 FT_Bool subpixel_positioned; |
| 1973 #endif |
| 1974 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 1975 |
| 1976 FT_Bool reexecute = FALSE; |
| 1977 |
1852 | 1978 |
1853 if ( !size->cvt_ready ) | 1979 if ( !size->cvt_ready ) |
1854 { | 1980 { |
1855 FT_Error error = tt_size_ready_bytecode( size, pedantic ); | 1981 FT_Error error = tt_size_ready_bytecode( size, pedantic ); |
1856 | 1982 |
1857 | 1983 |
1858 if ( error ) | 1984 if ( error ) |
1859 return error; | 1985 return error; |
1860 } | 1986 } |
1861 | 1987 |
1862 /* query new execution context */ | 1988 /* query new execution context */ |
1863 exec = size->debug ? size->context | 1989 exec = size->debug ? size->context |
1864 : ( (TT_Driver)FT_FACE_DRIVER( face ) )->context; | 1990 : ( (TT_Driver)FT_FACE_DRIVER( face ) )->context; |
1865 if ( !exec ) | 1991 if ( !exec ) |
1866 return TT_Err_Could_Not_Find_Context; | 1992 return FT_THROW( Could_Not_Find_Context ); |
1867 | 1993 |
1868 grayscale = | 1994 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
1869 FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != FT_RENDER_MODE_MONO ); | 1995 |
| 1996 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) |
| 1997 { |
| 1998 subpixel_hinting = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags ) |
| 1999 != FT_RENDER_MODE_MONO ) && |
| 2000 SPH_OPTION_SET_SUBPIXEL ); |
| 2001 |
| 2002 if ( subpixel_hinting ) |
| 2003 grayscale = grayscale_hinting = FALSE; |
| 2004 else if ( SPH_OPTION_SET_GRAYSCALE ) |
| 2005 { |
| 2006 grayscale = grayscale_hinting = TRUE; |
| 2007 subpixel_hinting = FALSE; |
| 2008 } |
| 2009 else |
| 2010 grayscale = grayscale_hinting = FALSE; |
| 2011 |
| 2012 if ( FT_IS_TRICKY( glyph->face ) ) |
| 2013 subpixel_hinting = grayscale_hinting = FALSE; |
| 2014 |
| 2015 exec->ignore_x_mode = subpixel_hinting || grayscale_hinting; |
| 2016 exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION; |
| 2017 if ( exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 ) |
| 2018 exec->rasterizer_version = TT_INTERPRETER_VERSION_35; |
| 2019 |
| 2020 #if 1 |
| 2021 exec->compatible_widths = SPH_OPTION_SET_COMPATIBLE_WIDTHS; |
| 2022 exec->symmetrical_smoothing = FALSE; |
| 2023 exec->bgr = FALSE; |
| 2024 exec->subpixel_positioned = TRUE; |
| 2025 #else /* 0 */ |
| 2026 exec->compatible_widths = |
| 2027 FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != |
| 2028 TT_LOAD_COMPATIBLE_WIDTHS ); |
| 2029 exec->symmetrical_smoothing = |
| 2030 FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != |
| 2031 TT_LOAD_SYMMETRICAL_SMOOTHING ); |
| 2032 exec->bgr = |
| 2033 FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != |
| 2034 TT_LOAD_BGR ); |
| 2035 exec->subpixel_positioned = |
| 2036 FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != |
| 2037 TT_LOAD_SUBPIXEL_POSITIONED ); |
| 2038 #endif /* 0 */ |
| 2039 |
| 2040 } |
| 2041 else |
| 2042 |
| 2043 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 2044 |
| 2045 { |
| 2046 grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != |
| 2047 FT_RENDER_MODE_MONO ); |
| 2048 } |
1870 | 2049 |
1871 TT_Load_Context( exec, face, size ); | 2050 TT_Load_Context( exec, face, size ); |
1872 | 2051 |
1873 /* a change from mono to grayscale rendering (and vice versa) */ | 2052 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING |
1874 /* requires a re-execution of the CVT program */ | 2053 |
1875 if ( grayscale != exec->grayscale ) | 2054 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) |
| 2055 { |
| 2056 /* a change from mono to subpixel rendering (and vice versa) */ |
| 2057 /* requires a re-execution of the CVT program */ |
| 2058 if ( subpixel_hinting != exec->subpixel_hinting ) |
| 2059 { |
| 2060 FT_TRACE4(( "tt_loader_init: subpixel hinting change," |
| 2061 " re-executing `prep' table\n" )); |
| 2062 |
| 2063 exec->subpixel_hinting = subpixel_hinting; |
| 2064 reexecute = TRUE; |
| 2065 } |
| 2066 |
| 2067 /* a change from mono to grayscale rendering (and vice versa) */ |
| 2068 /* requires a re-execution of the CVT program */ |
| 2069 if ( grayscale != exec->grayscale_hinting ) |
| 2070 { |
| 2071 FT_TRACE4(( "tt_loader_init: grayscale hinting change," |
| 2072 " re-executing `prep' table\n" )); |
| 2073 |
| 2074 exec->grayscale_hinting = grayscale_hinting; |
| 2075 reexecute = TRUE; |
| 2076 } |
| 2077 } |
| 2078 else |
| 2079 |
| 2080 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ |
| 2081 |
| 2082 { |
| 2083 /* a change from mono to grayscale rendering (and vice versa) */ |
| 2084 /* requires a re-execution of the CVT program */ |
| 2085 if ( grayscale != exec->grayscale ) |
| 2086 { |
| 2087 FT_TRACE4(( "tt_loader_init: grayscale change," |
| 2088 " re-executing `prep' table\n" )); |
| 2089 |
| 2090 exec->grayscale = grayscale; |
| 2091 reexecute = TRUE; |
| 2092 } |
| 2093 } |
| 2094 |
| 2095 if ( reexecute ) |
1876 { | 2096 { |
1877 FT_UInt i; | 2097 FT_UInt i; |
1878 | 2098 |
1879 | 2099 |
1880 FT_TRACE4(( "tt_loader_init: grayscale change," | |
1881 " re-executing `prep' table\n" )); | |
1882 | |
1883 exec->grayscale = grayscale; | |
1884 | |
1885 for ( i = 0; i < size->cvt_size; i++ ) | 2100 for ( i = 0; i < size->cvt_size; i++ ) |
1886 size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); | 2101 size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); |
1887 tt_size_run_prep( size, pedantic ); | 2102 tt_size_run_prep( size, pedantic ); |
1888 } | 2103 } |
1889 | 2104 |
1890 /* see whether the cvt program has disabled hinting */ | 2105 /* see whether the cvt program has disabled hinting */ |
1891 if ( exec->GS.instruct_control & 1 ) | 2106 if ( exec->GS.instruct_control & 1 ) |
1892 load_flags |= FT_LOAD_NO_HINTING; | 2107 load_flags |= FT_LOAD_NO_HINTING; |
1893 | 2108 |
1894 /* load default graphics state -- if needed */ | 2109 /* load default graphics state -- if needed */ |
(...skipping 16 matching lines...) Expand all Loading... |
1911 if ( face->root.internal->incremental_interface ) | 2126 if ( face->root.internal->incremental_interface ) |
1912 loader->glyf_offset = 0; | 2127 loader->glyf_offset = 0; |
1913 else | 2128 else |
1914 | 2129 |
1915 #endif | 2130 #endif |
1916 | 2131 |
1917 { | 2132 { |
1918 FT_Error error = face->goto_table( face, TTAG_glyf, stream, 0 ); | 2133 FT_Error error = face->goto_table( face, TTAG_glyf, stream, 0 ); |
1919 | 2134 |
1920 | 2135 |
1921 if ( error == TT_Err_Table_Missing ) | 2136 if ( FT_ERR_EQ( error, Table_Missing ) ) |
1922 loader->glyf_offset = 0; | 2137 loader->glyf_offset = 0; |
1923 else if ( error ) | 2138 else if ( error ) |
1924 { | 2139 { |
1925 FT_ERROR(( "tt_loader_init: could not access glyph table\n" )); | 2140 FT_ERROR(( "tt_loader_init: could not access glyph table\n" )); |
1926 return error; | 2141 return error; |
1927 } | 2142 } |
1928 else | 2143 else |
1929 loader->glyf_offset = FT_STREAM_POS(); | 2144 loader->glyf_offset = FT_STREAM_POS(); |
1930 } | 2145 } |
1931 | 2146 |
1932 /* get face's glyph loader */ | 2147 /* get face's glyph loader */ |
1933 if ( !glyf_table_only ) | 2148 if ( !glyf_table_only ) |
1934 { | 2149 { |
1935 FT_GlyphLoader gloader = glyph->internal->loader; | 2150 FT_GlyphLoader gloader = glyph->internal->loader; |
1936 | 2151 |
1937 | 2152 |
1938 FT_GlyphLoader_Rewind( gloader ); | 2153 FT_GlyphLoader_Rewind( gloader ); |
1939 loader->gloader = gloader; | 2154 loader->gloader = gloader; |
1940 } | 2155 } |
1941 | 2156 |
1942 loader->load_flags = load_flags; | 2157 loader->load_flags = load_flags; |
1943 | 2158 |
1944 loader->face = (FT_Face)face; | 2159 loader->face = (FT_Face)face; |
1945 loader->size = (FT_Size)size; | 2160 loader->size = (FT_Size)size; |
1946 loader->glyph = (FT_GlyphSlot)glyph; | 2161 loader->glyph = (FT_GlyphSlot)glyph; |
1947 loader->stream = stream; | 2162 loader->stream = stream; |
1948 | 2163 |
1949 return TT_Err_Ok; | 2164 return FT_Err_Ok; |
1950 } | 2165 } |
1951 | 2166 |
1952 | 2167 |
1953 /*************************************************************************/ | 2168 /*************************************************************************/ |
1954 /* */ | 2169 /* */ |
1955 /* <Function> */ | 2170 /* <Function> */ |
1956 /* TT_Load_Glyph */ | 2171 /* TT_Load_Glyph */ |
1957 /* */ | 2172 /* */ |
1958 /* <Description> */ | 2173 /* <Description> */ |
1959 /* A function used to load a single glyph within a given glyph slot, */ | 2174 /* A function used to load a single glyph within a given glyph slot, */ |
(...skipping 16 matching lines...) Expand all Loading... |
1976 /* */ | 2191 /* */ |
1977 /* <Return> */ | 2192 /* <Return> */ |
1978 /* FreeType error code. 0 means success. */ | 2193 /* FreeType error code. 0 means success. */ |
1979 /* */ | 2194 /* */ |
1980 FT_LOCAL_DEF( FT_Error ) | 2195 FT_LOCAL_DEF( FT_Error ) |
1981 TT_Load_Glyph( TT_Size size, | 2196 TT_Load_Glyph( TT_Size size, |
1982 TT_GlyphSlot glyph, | 2197 TT_GlyphSlot glyph, |
1983 FT_UInt glyph_index, | 2198 FT_UInt glyph_index, |
1984 FT_Int32 load_flags ) | 2199 FT_Int32 load_flags ) |
1985 { | 2200 { |
1986 TT_Face face; | |
1987 FT_Error error; | 2201 FT_Error error; |
1988 TT_LoaderRec loader; | 2202 TT_LoaderRec loader; |
1989 | 2203 |
1990 | 2204 |
1991 face = (TT_Face)glyph->face; | 2205 error = FT_Err_Ok; |
1992 error = TT_Err_Ok; | |
1993 | 2206 |
1994 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS | 2207 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS |
1995 | 2208 |
1996 /* try to load embedded bitmap if any */ | 2209 /* try to load embedded bitmap if any */ |
1997 /* */ | 2210 /* */ |
1998 /* XXX: The convention should be emphasized in */ | 2211 /* XXX: The convention should be emphasized in */ |
1999 /* the documents because it can be confusing. */ | 2212 /* the documents because it can be confusing. */ |
2000 if ( size->strike_index != 0xFFFFFFFFUL && | 2213 if ( size->strike_index != 0xFFFFFFFFUL && |
2001 ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) | 2214 ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) |
2002 { | 2215 { |
2003 error = load_sbit_image( size, glyph, glyph_index, load_flags ); | 2216 error = load_sbit_image( size, glyph, glyph_index, load_flags ); |
2004 if ( !error ) | 2217 if ( !error ) |
2005 { | 2218 { |
2006 FT_Face root = &face->root; | 2219 if ( FT_IS_SCALABLE( glyph->face ) ) |
2007 | |
2008 | |
2009 if ( FT_IS_SCALABLE( root ) ) | |
2010 { | 2220 { |
2011 /* for the bbox we need the header only */ | 2221 /* for the bbox we need the header only */ |
2012 (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE ); | 2222 (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE ); |
2013 (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE ); | 2223 (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE ); |
2014 glyph->linearHoriAdvance = loader.linear; | 2224 glyph->linearHoriAdvance = loader.linear; |
2015 glyph->linearVertAdvance = loader.top_bearing + loader.bbox.yMax - | 2225 glyph->linearVertAdvance = loader.top_bearing + loader.bbox.yMax - |
2016 loader.vadvance; | 2226 loader.vadvance; |
| 2227 |
| 2228 /* sanity check: if `horiAdvance' in the sbit metric */ |
| 2229 /* structure isn't set, use `linearHoriAdvance' */ |
| 2230 if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance ) |
| 2231 glyph->metrics.horiAdvance = |
| 2232 FT_MulFix( glyph->linearHoriAdvance, |
| 2233 size->root.metrics.x_scale ); |
2017 } | 2234 } |
2018 | 2235 |
2019 return TT_Err_Ok; | 2236 return FT_Err_Ok; |
2020 } | 2237 } |
2021 } | 2238 } |
2022 | 2239 |
2023 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ | 2240 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ |
2024 | 2241 |
2025 /* if FT_LOAD_NO_SCALE is not set, `ttmetrics' must be valid */ | 2242 /* if FT_LOAD_NO_SCALE is not set, `ttmetrics' must be valid */ |
2026 if ( !( load_flags & FT_LOAD_NO_SCALE ) && !size->ttmetrics.valid ) | 2243 if ( !( load_flags & FT_LOAD_NO_SCALE ) && !size->ttmetrics.valid ) |
2027 return TT_Err_Invalid_Size_Handle; | 2244 return FT_THROW( Invalid_Size_Handle ); |
2028 | 2245 |
2029 if ( load_flags & FT_LOAD_SBITS_ONLY ) | 2246 if ( load_flags & FT_LOAD_SBITS_ONLY ) |
2030 return TT_Err_Invalid_Argument; | 2247 return FT_THROW( Invalid_Argument ); |
2031 | 2248 |
2032 error = tt_loader_init( &loader, size, glyph, load_flags, FALSE ); | 2249 error = tt_loader_init( &loader, size, glyph, load_flags, FALSE ); |
2033 if ( error ) | 2250 if ( error ) |
2034 return error; | 2251 return error; |
2035 | 2252 |
2036 glyph->format = FT_GLYPH_FORMAT_OUTLINE; | 2253 glyph->format = FT_GLYPH_FORMAT_OUTLINE; |
2037 glyph->num_subglyphs = 0; | 2254 glyph->num_subglyphs = 0; |
2038 glyph->outline.flags = 0; | 2255 glyph->outline.flags = 0; |
2039 | 2256 |
2040 /* main loading loop */ | 2257 /* main loading loop */ |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2102 /* */ | 2319 /* */ |
2103 if ( !( load_flags & FT_LOAD_NO_SCALE ) && | 2320 if ( !( load_flags & FT_LOAD_NO_SCALE ) && |
2104 size->root.metrics.y_ppem < 24 ) | 2321 size->root.metrics.y_ppem < 24 ) |
2105 glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION; | 2322 glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION; |
2106 | 2323 |
2107 return error; | 2324 return error; |
2108 } | 2325 } |
2109 | 2326 |
2110 | 2327 |
2111 /* END */ | 2328 /* END */ |
OLD | NEW |