Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(199)

Side by Side Diff: src/truetype/ttinterp.c

Issue 23555005: Update freetype to the latest version of Android external/freetype (Closed) Base URL: https://chromium.googlesource.com/chromium/src/third_party/freetype.git@master
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/truetype/ttinterp.h ('k') | src/truetype/ttobjs.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /***************************************************************************/ 1 /***************************************************************************/
2 /* */ 2 /* */
3 /* ttinterp.c */ 3 /* ttinterp.c */
4 /* */ 4 /* */
5 /* TrueType bytecode interpreter (body). */ 5 /* TrueType bytecode interpreter (body). */
6 /* */ 6 /* */
7 /* Copyright 1996-2011 */ 7 /* Copyright 1996-2012 */
8 /* by David Turner, Robert Wilhelm, and Werner Lemberg. */ 8 /* by 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 690 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 /* <Note> */ 708 /* <Note> */
709 /* Only the glyph loader and debugger should call this function. */ 709 /* Only the glyph loader and debugger should call this function. */
710 /* */ 710 /* */
711 FT_LOCAL_DEF( FT_Error ) 711 FT_LOCAL_DEF( FT_Error )
712 TT_Run_Context( TT_ExecContext exec, 712 TT_Run_Context( TT_ExecContext exec,
713 FT_Bool debug ) 713 FT_Bool debug )
714 { 714 {
715 FT_Error error; 715 FT_Error error;
716 716
717 717
718 if ( ( error = TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 ) ) 718 if ( ( error = TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 ) )
719 != TT_Err_Ok ) 719 != TT_Err_Ok )
720 return error; 720 return error;
721 721
722 exec->zp0 = exec->pts; 722 exec->zp0 = exec->pts;
723 exec->zp1 = exec->pts; 723 exec->zp1 = exec->pts;
724 exec->zp2 = exec->pts; 724 exec->zp2 = exec->pts;
725 725
726 exec->GS.gep0 = 1; 726 exec->GS.gep0 = 1;
727 exec->GS.gep1 = 1; 727 exec->GS.gep1 = 1;
728 exec->GS.gep2 = 1; 728 exec->GS.gep2 = 1;
(...skipping 1064 matching lines...) Expand 10 before | Expand all | Expand 10 after
1793 range = &CUR.codeRangeTable[aRange - 1]; 1793 range = &CUR.codeRangeTable[aRange - 1];
1794 1794
1795 if ( range->base == NULL ) /* invalid coderange */ 1795 if ( range->base == NULL ) /* invalid coderange */
1796 { 1796 {
1797 CUR.error = TT_Err_Invalid_CodeRange; 1797 CUR.error = TT_Err_Invalid_CodeRange;
1798 return FAILURE; 1798 return FAILURE;
1799 } 1799 }
1800 1800
1801 /* NOTE: Because the last instruction of a program may be a CALL */ 1801 /* NOTE: Because the last instruction of a program may be a CALL */
1802 /* which will return to the first byte *after* the code */ 1802 /* which will return to the first byte *after* the code */
1803 /* range, we test for AIP <= Size, instead of AIP < Size. */ 1803 /* range, we test for aIP <= Size, instead of aIP < Size. */
1804 1804
1805 if ( aIP > range->size ) 1805 if ( aIP > range->size )
1806 { 1806 {
1807 CUR.error = TT_Err_Code_Overflow; 1807 CUR.error = TT_Err_Code_Overflow;
1808 return FAILURE; 1808 return FAILURE;
1809 } 1809 }
1810 1810
1811 CUR.code = range->base; 1811 CUR.code = range->base;
1812 CUR.codeSize = range->size; 1812 CUR.codeSize = range->size;
1813 CUR.IP = aIP; 1813 CUR.IP = aIP;
(...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after
2750 } 2750 }
2751 2751
2752 W = TT_VecLen( Vx, Vy ); 2752 W = TT_VecLen( Vx, Vy );
2753 2753
2754 Vx = FT_MulDiv( Vx, 0x4000L, W ); 2754 Vx = FT_MulDiv( Vx, 0x4000L, W );
2755 Vy = FT_MulDiv( Vy, 0x4000L, W ); 2755 Vy = FT_MulDiv( Vy, 0x4000L, W );
2756 2756
2757 W = Vx * Vx + Vy * Vy; 2757 W = Vx * Vx + Vy * Vy;
2758 2758
2759 /* Now, we want that Sqrt( W ) = 0x4000 */ 2759 /* Now, we want that Sqrt( W ) = 0x4000 */
2760 /* Or 0x10000000 <= W < 0x10004000 */ 2760 /* Or 0x10000000 <= W < 0x10004000 */
2761 2761
2762 if ( Vx < 0 ) 2762 if ( Vx < 0 )
2763 { 2763 {
2764 Vx = -Vx; 2764 Vx = -Vx;
2765 S1 = TRUE; 2765 S1 = TRUE;
2766 } 2766 }
2767 else 2767 else
2768 S1 = FALSE; 2768 S1 = FALSE;
2769 2769
2770 if ( Vy < 0 ) 2770 if ( Vy < 0 )
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
3192 { \ 3192 { \
3193 if ( CUR.pedantic_hinting ) \ 3193 if ( CUR.pedantic_hinting ) \
3194 CUR.error = TT_Err_Invalid_Reference; \ 3194 CUR.error = TT_Err_Invalid_Reference; \
3195 args[0] = 0; \ 3195 args[0] = 0; \
3196 } \ 3196 } \
3197 else \ 3197 else \
3198 args[0] = CUR.stack[CUR.args - L]; \ 3198 args[0] = CUR.stack[CUR.args - L]; \
3199 } 3199 }
3200 3200
3201 3201
3202 #define DO_JROT \ 3202 #define DO_JROT \
3203 if ( args[1] != 0 ) \ 3203 if ( args[1] != 0 ) \
3204 { \ 3204 { \
3205 if ( args[0] == 0 && CUR.args == 0 ) \ 3205 if ( args[0] == 0 && CUR.args == 0 ) \
3206 CUR.error = TT_Err_Bad_Argument; \ 3206 CUR.error = TT_Err_Bad_Argument; \
3207 CUR.IP += args[0]; \ 3207 CUR.IP += args[0]; \
3208 if ( CUR.IP < 0 ) \ 3208 if ( CUR.IP < 0 || \
3209 CUR.error = TT_Err_Bad_Argument; \ 3209 ( CUR.callTop > 0 && \
3210 CUR.step_ins = FALSE; \ 3210 CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \
3211 CUR.error = TT_Err_Bad_Argument; \
3212 CUR.step_ins = FALSE; \
3211 } 3213 }
3212 3214
3213 3215
3214 #define DO_JMPR \ 3216 #define DO_JMPR \
3215 if ( args[0] == 0 && CUR.args == 0 ) \ 3217 if ( args[0] == 0 && CUR.args == 0 ) \
3216 CUR.error = TT_Err_Bad_Argument; \ 3218 CUR.error = TT_Err_Bad_Argument; \
3217 CUR.IP += args[0]; \ 3219 CUR.IP += args[0]; \
3218 if ( CUR.IP < 0 ) \ 3220 if ( CUR.IP < 0 || \
3219 CUR.error = TT_Err_Bad_Argument; \ 3221 ( CUR.callTop > 0 && \
3222 CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \
3223 CUR.error = TT_Err_Bad_Argument; \
3220 CUR.step_ins = FALSE; 3224 CUR.step_ins = FALSE;
3221 3225
3222 3226
3223 #define DO_JROF \ 3227 #define DO_JROF \
3224 if ( args[1] == 0 ) \ 3228 if ( args[1] == 0 ) \
3225 { \ 3229 { \
3226 if ( args[0] == 0 && CUR.args == 0 ) \ 3230 if ( args[0] == 0 && CUR.args == 0 ) \
3227 CUR.error = TT_Err_Bad_Argument; \ 3231 CUR.error = TT_Err_Bad_Argument; \
3228 CUR.IP += args[0]; \ 3232 CUR.IP += args[0]; \
3229 if ( CUR.IP < 0 ) \ 3233 if ( CUR.IP < 0 || \
3230 CUR.error = TT_Err_Bad_Argument; \ 3234 ( CUR.callTop > 0 && \
3231 CUR.step_ins = FALSE; \ 3235 CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \
3236 CUR.error = TT_Err_Bad_Argument; \
3237 CUR.step_ins = FALSE; \
3232 } 3238 }
3233 3239
3234 3240
3235 #define DO_LT \ 3241 #define DO_LT \
3236 args[0] = ( args[0] < args[1] ); 3242 args[0] = ( args[0] < args[1] );
3237 3243
3238 3244
3239 #define DO_LTEQ \ 3245 #define DO_LTEQ \
3240 args[0] = ( args[0] <= args[1] ); 3246 args[0] = ( args[0] <= args[1] );
3241 3247
(...skipping 1222 matching lines...) Expand 10 before | Expand all | Expand 10 after
4464 { 4470 {
4465 CUR.IP += CUR.length; 4471 CUR.IP += CUR.length;
4466 4472
4467 if ( CUR.IP < CUR.codeSize ) 4473 if ( CUR.IP < CUR.codeSize )
4468 { 4474 {
4469 CUR.opcode = CUR.code[CUR.IP]; 4475 CUR.opcode = CUR.code[CUR.IP];
4470 4476
4471 CUR.length = opcode_length[CUR.opcode]; 4477 CUR.length = opcode_length[CUR.opcode];
4472 if ( CUR.length < 0 ) 4478 if ( CUR.length < 0 )
4473 { 4479 {
4474 if ( CUR.IP + 1 > CUR.codeSize ) 4480 if ( CUR.IP + 1 >= CUR.codeSize )
4475 goto Fail_Overflow; 4481 goto Fail_Overflow;
4476 CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1]; 4482 CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1];
4477 } 4483 }
4478 4484
4479 if ( CUR.IP + CUR.length <= CUR.codeSize ) 4485 if ( CUR.IP + CUR.length <= CUR.codeSize )
4480 return SUCCESS; 4486 return SUCCESS;
4481 } 4487 }
4482 4488
4483 Fail_Overflow: 4489 Fail_Overflow:
4484 CUR.error = TT_Err_Code_Overflow; 4490 CUR.error = TT_Err_Code_Overflow;
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
4633 while ( SKIP_Code() == SUCCESS ) 4639 while ( SKIP_Code() == SUCCESS )
4634 { 4640 {
4635 switch ( CUR.opcode ) 4641 switch ( CUR.opcode )
4636 { 4642 {
4637 case 0x89: /* IDEF */ 4643 case 0x89: /* IDEF */
4638 case 0x2C: /* FDEF */ 4644 case 0x2C: /* FDEF */
4639 CUR.error = TT_Err_Nested_DEFS; 4645 CUR.error = TT_Err_Nested_DEFS;
4640 return; 4646 return;
4641 4647
4642 case 0x2D: /* ENDF */ 4648 case 0x2D: /* ENDF */
4649 rec->end = CUR.IP;
4643 return; 4650 return;
4644 } 4651 }
4645 } 4652 }
4646 } 4653 }
4647 4654
4648 4655
4649 /*************************************************************************/ 4656 /*************************************************************************/
4650 /* */ 4657 /* */
4651 /* ENDF[]: END Function definition */ 4658 /* ENDF[]: END Function definition */
4652 /* Opcode range: 0x2D */ 4659 /* Opcode range: 0x2D */
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
4750 CUR.error = TT_Err_Stack_Overflow; 4757 CUR.error = TT_Err_Stack_Overflow;
4751 return; 4758 return;
4752 } 4759 }
4753 4760
4754 pCrec = CUR.callStack + CUR.callTop; 4761 pCrec = CUR.callStack + CUR.callTop;
4755 4762
4756 pCrec->Caller_Range = CUR.curRange; 4763 pCrec->Caller_Range = CUR.curRange;
4757 pCrec->Caller_IP = CUR.IP + 1; 4764 pCrec->Caller_IP = CUR.IP + 1;
4758 pCrec->Cur_Count = 1; 4765 pCrec->Cur_Count = 1;
4759 pCrec->Cur_Restart = def->start; 4766 pCrec->Cur_Restart = def->start;
4767 pCrec->Cur_End = def->end;
4760 4768
4761 CUR.callTop++; 4769 CUR.callTop++;
4762 4770
4763 INS_Goto_CodeRange( def->range, 4771 INS_Goto_CodeRange( def->range,
4764 def->start ); 4772 def->start );
4765 4773
4766 CUR.step_ins = FALSE; 4774 CUR.step_ins = FALSE;
4767 return; 4775 return;
4768 4776
4769 Fail: 4777 Fail:
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
4828 } 4836 }
4829 4837
4830 if ( args[0] > 0 ) 4838 if ( args[0] > 0 )
4831 { 4839 {
4832 pCrec = CUR.callStack + CUR.callTop; 4840 pCrec = CUR.callStack + CUR.callTop;
4833 4841
4834 pCrec->Caller_Range = CUR.curRange; 4842 pCrec->Caller_Range = CUR.curRange;
4835 pCrec->Caller_IP = CUR.IP + 1; 4843 pCrec->Caller_IP = CUR.IP + 1;
4836 pCrec->Cur_Count = (FT_Int)args[0]; 4844 pCrec->Cur_Count = (FT_Int)args[0];
4837 pCrec->Cur_Restart = def->start; 4845 pCrec->Cur_Restart = def->start;
4846 pCrec->Cur_End = def->end;
4838 4847
4839 CUR.callTop++; 4848 CUR.callTop++;
4840 4849
4841 INS_Goto_CodeRange( def->range, def->start ); 4850 INS_Goto_CodeRange( def->range, def->start );
4842 4851
4843 CUR.step_ins = FALSE; 4852 CUR.step_ins = FALSE;
4844 } 4853 }
4845 return; 4854 return;
4846 4855
4847 Fail: 4856 Fail:
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
5043 /* */ 5052 /* */
5044 /*************************************************************************/ 5053 /*************************************************************************/
5045 5054
5046 5055
5047 /*************************************************************************/ 5056 /*************************************************************************/
5048 /* */ 5057 /* */
5049 /* GC[a]: Get Coordinate projected onto */ 5058 /* GC[a]: Get Coordinate projected onto */
5050 /* Opcode range: 0x46-0x47 */ 5059 /* Opcode range: 0x46-0x47 */
5051 /* Stack: uint32 --> f26.6 */ 5060 /* Stack: uint32 --> f26.6 */
5052 /* */ 5061 /* */
5053 /* BULLSHIT: Measures from the original glyph must be taken along the */ 5062 /* XXX: UNDOCUMENTED: Measures from the original glyph must be taken */
5054 /* dual projection vector! */ 5063 /* along the dual projection vector! */
5055 /* */ 5064 /* */
5056 static void 5065 static void
5057 Ins_GC( INS_ARG ) 5066 Ins_GC( INS_ARG )
5058 { 5067 {
5059 FT_ULong L; 5068 FT_ULong L;
5060 FT_F26Dot6 R; 5069 FT_F26Dot6 R;
5061 5070
5062 5071
5063 L = (FT_ULong)args[0]; 5072 L = (FT_ULong)args[0];
5064 5073
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
5116 CUR.zp2.org[L] = CUR.zp2.cur[L]; 5125 CUR.zp2.org[L] = CUR.zp2.cur[L];
5117 } 5126 }
5118 5127
5119 5128
5120 /*************************************************************************/ 5129 /*************************************************************************/
5121 /* */ 5130 /* */
5122 /* MD[a]: Measure Distance */ 5131 /* MD[a]: Measure Distance */
5123 /* Opcode range: 0x49-0x4A */ 5132 /* Opcode range: 0x49-0x4A */
5124 /* Stack: uint32 uint32 --> f26.6 */ 5133 /* Stack: uint32 uint32 --> f26.6 */
5125 /* */ 5134 /* */
5126 /* BULLSHIT: Measure taken in the original glyph must be along the dual */ 5135 /* XXX: UNDOCUMENTED: Measure taken in the original glyph must be along */
5127 /* projection vector. */ 5136 /* the dual projection vector. */
5128 /* */ 5137 /* */
5129 /* Second BULLSHIT: Flag attributes are inverted! */ 5138 /* XXX: UNDOCUMENTED: Flag attributes are inverted! */
5130 /* 0 => measure distance in original outline */ 5139 /* 0 => measure distance in original outline */
5131 /* 1 => measure distance in grid-fitted outline */ 5140 /* 1 => measure distance in grid-fitted outline */
5132 /* */ 5141 /* */
5133 /* Third one: `zp0 - zp1', and not `zp2 - zp1! */ 5142 /* XXX: UNDOCUMENTED: `zp0 - zp1', and not `zp2 - zp1! */
5134 /* */ 5143 /* */
5135 static void 5144 static void
5136 Ins_MD( INS_ARG ) 5145 Ins_MD( INS_ARG )
5137 { 5146 {
5138 FT_UShort K, L; 5147 FT_UShort K, L;
5139 FT_F26Dot6 D; 5148 FT_F26Dot6 D;
5140 5149
5141 5150
5142 K = (FT_UShort)args[1]; 5151 K = (FT_UShort)args[1];
5143 L = (FT_UShort)args[0]; 5152 L = (FT_UShort)args[0];
5144 5153
5145 if ( BOUNDS( L, CUR.zp0.n_points ) || 5154 if ( BOUNDS( L, CUR.zp0.n_points ) ||
5146 BOUNDS( K, CUR.zp1.n_points ) ) 5155 BOUNDS( K, CUR.zp1.n_points ) )
5147 { 5156 {
5148 if ( CUR.pedantic_hinting ) 5157 if ( CUR.pedantic_hinting )
5149 CUR.error = TT_Err_Invalid_Reference; 5158 CUR.error = TT_Err_Invalid_Reference;
5150 D = 0; 5159 D = 0;
5151 } 5160 }
5152 else 5161 else
5153 { 5162 {
5154 if ( CUR.opcode & 1 ) 5163 if ( CUR.opcode & 1 )
5155 D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K ); 5164 D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K );
5156 else 5165 else
5157 { 5166 {
5158 FT_Vector* vec1 = CUR.zp0.orus + L; 5167 /* XXX: UNDOCUMENTED: twilight zone special case */
5159 FT_Vector* vec2 = CUR.zp1.orus + K; 5168
5169 if ( CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 )
5170 {
5171 FT_Vector* vec1 = CUR.zp0.org + L;
5172 FT_Vector* vec2 = CUR.zp1.org + K;
5160 5173
5161 5174
5162 if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
5163 {
5164 /* this should be faster */
5165 D = CUR_Func_dualproj( vec1, vec2 ); 5175 D = CUR_Func_dualproj( vec1, vec2 );
5166 D = TT_MULFIX( D, CUR.metrics.x_scale );
5167 } 5176 }
5168 else 5177 else
5169 { 5178 {
5170 FT_Vector vec; 5179 FT_Vector* vec1 = CUR.zp0.orus + L;
5180 FT_Vector* vec2 = CUR.zp1.orus + K;
5171 5181
5172 5182
5173 vec.x = TT_MULFIX( vec1->x - vec2->x, CUR.metrics.x_scale ); 5183 if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
5174 vec.y = TT_MULFIX( vec1->y - vec2->y, CUR.metrics.y_scale ); 5184 {
5185 /* this should be faster */
5186 D = CUR_Func_dualproj( vec1, vec2 );
5187 D = TT_MULFIX( D, CUR.metrics.x_scale );
5188 }
5189 else
5190 {
5191 FT_Vector vec;
5175 5192
5176 D = CUR_fast_dualproj( &vec ); 5193
5194 vec.x = TT_MULFIX( vec1->x - vec2->x, CUR.metrics.x_scale );
5195 vec.y = TT_MULFIX( vec1->y - vec2->y, CUR.metrics.y_scale );
5196
5197 D = CUR_fast_dualproj( &vec );
5198 }
5177 } 5199 }
5178 } 5200 }
5179 } 5201 }
5180 5202
5181 args[0] = D; 5203 args[0] = D;
5182 } 5204 }
5183 5205
5184 5206
5185 /*************************************************************************/ 5207 /*************************************************************************/
5186 /* */ 5208 /* */
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after
5741 CUR.new_top = CUR.args; 5763 CUR.new_top = CUR.args;
5742 } 5764 }
5743 5765
5744 5766
5745 /*************************************************************************/ 5767 /*************************************************************************/
5746 /* */ 5768 /* */
5747 /* SHC[a]: SHift Contour */ 5769 /* SHC[a]: SHift Contour */
5748 /* Opcode range: 0x34-35 */ 5770 /* Opcode range: 0x34-35 */
5749 /* Stack: uint32 --> */ 5771 /* Stack: uint32 --> */
5750 /* */ 5772 /* */
5773 /* UNDOCUMENTED: According to Greg Hitchcock, there is one (virtual) */
5774 /* contour in the twilight zone, namely contour number */
5775 /* zero. */
5776 /* */
5751 static void 5777 static void
5752 Ins_SHC( INS_ARG ) 5778 Ins_SHC( INS_ARG )
5753 { 5779 {
5754 TT_GlyphZoneRec zp; 5780 TT_GlyphZoneRec zp;
5755 FT_UShort refp; 5781 FT_UShort refp;
5756 FT_F26Dot6 dx, 5782 FT_F26Dot6 dx, dy;
5757 dy;
5758 5783
5759 FT_Short contour; 5784 FT_Short contour, bounds;
5760 FT_UShort first_point, last_point, i; 5785 FT_UShort start, limit, i;
5761 5786
5762 5787
5763 contour = (FT_UShort)args[0]; 5788 contour = (FT_UShort)args[0];
5789 bounds = ( CUR.GS.gep2 == 0 ) ? 1 : CUR.zp2.n_contours;
5764 5790
5765 if ( BOUNDS( contour, CUR.pts.n_contours ) ) 5791 if ( BOUNDS( contour, bounds ) )
5766 { 5792 {
5767 if ( CUR.pedantic_hinting ) 5793 if ( CUR.pedantic_hinting )
5768 CUR.error = TT_Err_Invalid_Reference; 5794 CUR.error = TT_Err_Invalid_Reference;
5769 return; 5795 return;
5770 } 5796 }
5771 5797
5772 if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) 5798 if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
5773 return; 5799 return;
5774 5800
5775 if ( contour == 0 ) 5801 if ( contour == 0 )
5776 first_point = 0; 5802 start = 0;
5777 else 5803 else
5778 first_point = (FT_UShort)( CUR.pts.contours[contour - 1] + 1 - 5804 start = (FT_UShort)( CUR.zp2.contours[contour - 1] + 1 -
5779 CUR.pts.first_point ); 5805 CUR.zp2.first_point );
5780 5806
5781 last_point = (FT_UShort)( CUR.pts.contours[contour] - 5807 /* we use the number of points if in the twilight zone */
5782 CUR.pts.first_point ); 5808 if ( CUR.GS.gep2 == 0 )
5809 limit = CUR.zp2.n_points;
5810 else
5811 limit = (FT_UShort)( CUR.zp2.contours[contour] -
5812 CUR.zp2.first_point + 1 );
5783 5813
5784 /* XXX: this is probably wrong... at least it prevents memory */ 5814 for ( i = start; i < limit; i++ )
5785 /* corruption when zp2 is the twilight zone */
5786 if ( BOUNDS( last_point, CUR.zp2.n_points ) )
5787 {
5788 if ( CUR.zp2.n_points > 0 )
5789 last_point = (FT_UShort)(CUR.zp2.n_points - 1);
5790 else
5791 last_point = 0;
5792 }
5793
5794 for ( i = first_point; i <= last_point; i++ )
5795 { 5815 {
5796 if ( zp.cur != CUR.zp2.cur || refp != i ) 5816 if ( zp.cur != CUR.zp2.cur || refp != i )
5797 MOVE_Zp2_Point( i, dx, dy, TRUE ); 5817 MOVE_Zp2_Point( i, dx, dy, TRUE );
5798 } 5818 }
5799 } 5819 }
5800 5820
5801 5821
5802 /*************************************************************************/ 5822 /*************************************************************************/
5803 /* */ 5823 /* */
5804 /* SHZ[a]: SHift Zone */ 5824 /* SHZ[a]: SHift Zone */
5805 /* Opcode range: 0x36-37 */ 5825 /* Opcode range: 0x36-37 */
5806 /* Stack: uint32 --> */ 5826 /* Stack: uint32 --> */
5807 /* */ 5827 /* */
5808 static void 5828 static void
5809 Ins_SHZ( INS_ARG ) 5829 Ins_SHZ( INS_ARG )
5810 { 5830 {
5811 TT_GlyphZoneRec zp; 5831 TT_GlyphZoneRec zp;
5812 FT_UShort refp; 5832 FT_UShort refp;
5813 FT_F26Dot6 dx, 5833 FT_F26Dot6 dx,
5814 dy; 5834 dy;
5815 5835
5816 FT_UShort last_point, i; 5836 FT_UShort limit, i;
5817 5837
5818 5838
5819 if ( BOUNDS( args[0], 2 ) ) 5839 if ( BOUNDS( args[0], 2 ) )
5820 { 5840 {
5821 if ( CUR.pedantic_hinting ) 5841 if ( CUR.pedantic_hinting )
5822 CUR.error = TT_Err_Invalid_Reference; 5842 CUR.error = TT_Err_Invalid_Reference;
5823 return; 5843 return;
5824 } 5844 }
5825 5845
5826 if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) 5846 if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
5827 return; 5847 return;
5828 5848
5829 /* XXX: UNDOCUMENTED! SHZ doesn't move the phantom points. */ 5849 /* XXX: UNDOCUMENTED! SHZ doesn't move the phantom points. */
5830 /* Twilight zone has no contours, so use `n_points'. */ 5850 /* Twilight zone has no real contours, so use `n_points'. */
5831 /* Normal zone's `n_points' includes phantoms, so must */ 5851 /* Normal zone's `n_points' includes phantoms, so must */
5832 /* use end of last contour. */ 5852 /* use end of last contour. */
5833 if ( CUR.GS.gep2 == 0 && CUR.zp2.n_points > 0 ) 5853 if ( CUR.GS.gep2 == 0 )
5834 last_point = (FT_UShort)( CUR.zp2.n_points - 1 ); 5854 limit = (FT_UShort)CUR.zp2.n_points;
5835 else if ( CUR.GS.gep2 == 1 && CUR.zp2.n_contours > 0 ) 5855 else if ( CUR.GS.gep2 == 1 && CUR.zp2.n_contours > 0 )
5836 { 5856 limit = (FT_UShort)( CUR.zp2.contours[CUR.zp2.n_contours - 1] + 1 );
5837 last_point = (FT_UShort)( CUR.zp2.contours[CUR.zp2.n_contours - 1] );
5838
5839 if ( BOUNDS( last_point, CUR.zp2.n_points ) )
5840 {
5841 if ( CUR.pedantic_hinting )
5842 CUR.error = TT_Err_Invalid_Reference;
5843 return;
5844 }
5845 }
5846 else 5857 else
5847 last_point = 0; 5858 limit = 0;
5848 5859
5849 /* XXX: UNDOCUMENTED! SHZ doesn't touch the points */ 5860 /* XXX: UNDOCUMENTED! SHZ doesn't touch the points */
5850 for ( i = 0; i <= last_point; i++ ) 5861 for ( i = 0; i < limit; i++ )
5851 { 5862 {
5852 if ( zp.cur != CUR.zp2.cur || refp != i ) 5863 if ( zp.cur != CUR.zp2.cur || refp != i )
5853 MOVE_Zp2_Point( i, dx, dy, FALSE ); 5864 MOVE_Zp2_Point( i, dx, dy, FALSE );
5854 } 5865 }
5855 } 5866 }
5856 5867
5857 5868
5858 /*************************************************************************/ 5869 /*************************************************************************/
5859 /* */ 5870 /* */
5860 /* SHPIX[]: SHift points by a PIXel amount */ 5871 /* SHPIX[]: SHift points by a PIXel amount */
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
6246 /* UNDOCUMENTED! The MS rasterizer does that with */ 6257 /* UNDOCUMENTED! The MS rasterizer does that with */
6247 /* twilight points (confirmed by Greg Hitchcock) */ 6258 /* twilight points (confirmed by Greg Hitchcock) */
6248 if ( CUR.GS.gep1 == 0 ) 6259 if ( CUR.GS.gep1 == 0 )
6249 { 6260 {
6250 CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x + 6261 CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x +
6251 TT_MulFix14( (FT_UInt32)cvt_dist, 6262 TT_MulFix14( (FT_UInt32)cvt_dist,
6252 CUR.GS.freeVector.x ); 6263 CUR.GS.freeVector.x );
6253 CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y + 6264 CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y +
6254 TT_MulFix14( (FT_UInt32)cvt_dist, 6265 TT_MulFix14( (FT_UInt32)cvt_dist,
6255 CUR.GS.freeVector.y ); 6266 CUR.GS.freeVector.y );
6256 CUR.zp1.cur[point] = CUR.zp0.cur[point]; 6267 CUR.zp1.cur[point] = CUR.zp1.org[point];
6257 } 6268 }
6258 6269
6259 org_dist = CUR_Func_dualproj( &CUR.zp1.org[point], 6270 org_dist = CUR_Func_dualproj( &CUR.zp1.org[point],
6260 &CUR.zp0.org[CUR.GS.rp0] ); 6271 &CUR.zp0.org[CUR.GS.rp0] );
6261 cur_dist = CUR_Func_project ( &CUR.zp1.cur[point], 6272 cur_dist = CUR_Func_project ( &CUR.zp1.cur[point],
6262 &CUR.zp0.cur[CUR.GS.rp0] ); 6273 &CUR.zp0.cur[CUR.GS.rp0] );
6263 6274
6264 /* auto-flip test */ 6275 /* auto-flip test */
6265 6276
6266 if ( CUR.GS.auto_flip ) 6277 if ( CUR.GS.auto_flip )
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
6555 BOUNDS( CUR.GS.rp2, CUR.zp1.n_points ) ) 6566 BOUNDS( CUR.GS.rp2, CUR.zp1.n_points ) )
6556 { 6567 {
6557 old_range = 0; 6568 old_range = 0;
6558 cur_range = 0; 6569 cur_range = 0;
6559 } 6570 }
6560 else 6571 else
6561 { 6572 {
6562 if ( twilight ) 6573 if ( twilight )
6563 old_range = CUR_Func_dualproj( &CUR.zp1.org[CUR.GS.rp2], 6574 old_range = CUR_Func_dualproj( &CUR.zp1.org[CUR.GS.rp2],
6564 orus_base ); 6575 orus_base );
6565 else 6576 else if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
6566 old_range = CUR_Func_dualproj( &CUR.zp1.orus[CUR.GS.rp2], 6577 old_range = CUR_Func_dualproj( &CUR.zp1.orus[CUR.GS.rp2],
6567 orus_base ); 6578 orus_base );
6579 else
6580 {
6581 FT_Vector vec;
6582
6583
6584 vec.x = TT_MULFIX( CUR.zp1.orus[CUR.GS.rp2].x - orus_base->x,
6585 CUR.metrics.x_scale );
6586 vec.y = TT_MULFIX( CUR.zp1.orus[CUR.GS.rp2].y - orus_base->y,
6587 CUR.metrics.y_scale );
6588
6589 old_range = CUR_fast_dualproj( &vec );
6590 }
6568 6591
6569 cur_range = CUR_Func_project ( &CUR.zp1.cur[CUR.GS.rp2], cur_base ); 6592 cur_range = CUR_Func_project ( &CUR.zp1.cur[CUR.GS.rp2], cur_base );
6570 } 6593 }
6571 6594
6572 for ( ; CUR.GS.loop > 0; --CUR.GS.loop ) 6595 for ( ; CUR.GS.loop > 0; --CUR.GS.loop )
6573 { 6596 {
6574 FT_UInt point = (FT_UInt)CUR.stack[--CUR.args]; 6597 FT_UInt point = (FT_UInt)CUR.stack[--CUR.args];
6575 FT_F26Dot6 org_dist, cur_dist, new_dist; 6598 FT_F26Dot6 org_dist, cur_dist, new_dist;
6576 6599
6577 6600
6578 /* check point bounds */ 6601 /* check point bounds */
6579 if ( BOUNDS( point, CUR.zp2.n_points ) ) 6602 if ( BOUNDS( point, CUR.zp2.n_points ) )
6580 { 6603 {
6581 if ( CUR.pedantic_hinting ) 6604 if ( CUR.pedantic_hinting )
6582 { 6605 {
6583 CUR.error = TT_Err_Invalid_Reference; 6606 CUR.error = TT_Err_Invalid_Reference;
6584 return; 6607 return;
6585 } 6608 }
6586 continue; 6609 continue;
6587 } 6610 }
6588 6611
6589 if ( twilight ) 6612 if ( twilight )
6590 org_dist = CUR_Func_dualproj( &CUR.zp2.org[point], orus_base ); 6613 org_dist = CUR_Func_dualproj( &CUR.zp2.org[point], orus_base );
6614 else if ( CUR.metrics.x_scale == CUR.metrics.y_scale )
6615 org_dist = CUR_Func_dualproj( &CUR.zp2.orus[point], orus_base );
6591 else 6616 else
6592 org_dist = CUR_Func_dualproj( &CUR.zp2.orus[point], orus_base ); 6617 {
6618 FT_Vector vec;
6619
6620
6621 vec.x = TT_MULFIX( CUR.zp2.orus[point].x - orus_base->x,
6622 CUR.metrics.x_scale );
6623 vec.y = TT_MULFIX( CUR.zp2.orus[point].y - orus_base->y,
6624 CUR.metrics.y_scale );
6625
6626 org_dist = CUR_fast_dualproj( &vec );
6627 }
6593 6628
6594 cur_dist = CUR_Func_project ( &CUR.zp2.cur[point], cur_base ); 6629 cur_dist = CUR_Func_project ( &CUR.zp2.cur[point], cur_base );
6595 6630
6596 if ( org_dist ) 6631 if ( org_dist )
6597 new_dist = ( old_range != 0 ) 6632 new_dist = ( old_range != 0 )
6598 ? TT_MULDIV( org_dist, cur_range, old_range ) 6633 ? TT_MULDIV( org_dist, cur_range, old_range )
6599 : cur_dist; 6634 : cur_dist;
6600 else 6635 else
6601 new_dist = 0; 6636 new_dist = 0;
6602 6637
(...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after
7129 CUR.error = TT_Err_Stack_Overflow; 7164 CUR.error = TT_Err_Stack_Overflow;
7130 return; 7165 return;
7131 } 7166 }
7132 7167
7133 call = CUR.callStack + CUR.callTop++; 7168 call = CUR.callStack + CUR.callTop++;
7134 7169
7135 call->Caller_Range = CUR.curRange; 7170 call->Caller_Range = CUR.curRange;
7136 call->Caller_IP = CUR.IP + 1; 7171 call->Caller_IP = CUR.IP + 1;
7137 call->Cur_Count = 1; 7172 call->Cur_Count = 1;
7138 call->Cur_Restart = def->start; 7173 call->Cur_Restart = def->start;
7174 call->Cur_End = def->end;
7139 7175
7140 INS_Goto_CodeRange( def->range, def->start ); 7176 INS_Goto_CodeRange( def->range, def->start );
7141 7177
7142 CUR.step_ins = FALSE; 7178 CUR.step_ins = FALSE;
7143 return; 7179 return;
7144 } 7180 }
7145 } 7181 }
7146 7182
7147 CUR.error = TT_Err_Invalid_Opcode; 7183 CUR.error = TT_Err_Invalid_Opcode;
7148 } 7184 }
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
7501 do 7537 do
7502 { 7538 {
7503 CUR.opcode = CUR.code[CUR.IP]; 7539 CUR.opcode = CUR.code[CUR.IP];
7504 7540
7505 FT_TRACE7(( " " )); 7541 FT_TRACE7(( " " ));
7506 FT_TRACE7(( opcode_name[CUR.opcode] )); 7542 FT_TRACE7(( opcode_name[CUR.opcode] ));
7507 FT_TRACE7(( "\n" )); 7543 FT_TRACE7(( "\n" ));
7508 7544
7509 if ( ( CUR.length = opcode_length[CUR.opcode] ) < 0 ) 7545 if ( ( CUR.length = opcode_length[CUR.opcode] ) < 0 )
7510 { 7546 {
7511 if ( CUR.IP + 1 > CUR.codeSize ) 7547 if ( CUR.IP + 1 >= CUR.codeSize )
7512 goto LErrorCodeOverflow_; 7548 goto LErrorCodeOverflow_;
7513 7549
7514 CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1]; 7550 CUR.length = 2 - CUR.length * CUR.code[CUR.IP + 1];
7515 } 7551 }
7516 7552
7517 if ( CUR.IP + CUR.length > CUR.codeSize ) 7553 if ( CUR.IP + CUR.length > CUR.codeSize )
7518 goto LErrorCodeOverflow_; 7554 goto LErrorCodeOverflow_;
7519 7555
7520 /* First, let's check for empty stack and overflow */ 7556 /* First, let's check for empty stack and overflow */
7521 CUR.args = CUR.top - ( Pop_Push_Count[CUR.opcode] >> 4 ); 7557 CUR.args = CUR.top - ( Pop_Push_Count[CUR.opcode] >> 4 );
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after
8137 CUR.error = TT_Err_Invalid_Reference; 8173 CUR.error = TT_Err_Invalid_Reference;
8138 goto LErrorLabel_; 8174 goto LErrorLabel_;
8139 } 8175 }
8140 8176
8141 callrec = &CUR.callStack[CUR.callTop]; 8177 callrec = &CUR.callStack[CUR.callTop];
8142 8178
8143 callrec->Caller_Range = CUR.curRange; 8179 callrec->Caller_Range = CUR.curRange;
8144 callrec->Caller_IP = CUR.IP + 1; 8180 callrec->Caller_IP = CUR.IP + 1;
8145 callrec->Cur_Count = 1; 8181 callrec->Cur_Count = 1;
8146 callrec->Cur_Restart = def->start; 8182 callrec->Cur_Restart = def->start;
8183 callrec->Cur_End = def->end;
8147 8184
8148 if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE ) 8185 if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE )
8149 goto LErrorLabel_; 8186 goto LErrorLabel_;
8150 8187
8151 goto LSuiteLabel_; 8188 goto LSuiteLabel_;
8152 } 8189 }
8153 } 8190 }
8154 } 8191 }
8155 8192
8156 CUR.error = TT_Err_Invalid_Opcode; 8193 CUR.error = TT_Err_Invalid_Opcode;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
8210 #ifdef TT_CONFIG_OPTION_STATIC_RASTER 8247 #ifdef TT_CONFIG_OPTION_STATIC_RASTER
8211 *exc = cur; 8248 *exc = cur;
8212 #endif 8249 #endif
8213 8250
8214 /* If any errors have occurred, function tables may be broken. */ 8251 /* If any errors have occurred, function tables may be broken. */
8215 /* Force a re-execution of `prep' and `fpgm' tables if no */ 8252 /* Force a re-execution of `prep' and `fpgm' tables if no */
8216 /* bytecode debugger is run. */ 8253 /* bytecode debugger is run. */
8217 if ( CUR.error && !CUR.instruction_trap ) 8254 if ( CUR.error && !CUR.instruction_trap )
8218 { 8255 {
8219 FT_TRACE1(( " The interpreter returned error 0x%x\n", CUR.error )); 8256 FT_TRACE1(( " The interpreter returned error 0x%x\n", CUR.error ));
8220 exc->size->cvt_ready = FALSE; 8257 exc->size->cvt_ready = FALSE;
8221 } 8258 }
8222 8259
8223 return CUR.error; 8260 return CUR.error;
8224 } 8261 }
8225 8262
8226 8263
8227 #endif /* TT_USE_BYTECODE_INTERPRETER */ 8264 #endif /* TT_USE_BYTECODE_INTERPRETER */
8228 8265
8229 8266
8230 /* END */ 8267 /* END */
OLDNEW
« no previous file with comments | « src/truetype/ttinterp.h ('k') | src/truetype/ttobjs.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698