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

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

Issue 815103002: Update freetype to 2.5.4. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Adjust GYP and GN Created 6 years 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
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-2013 */ 7 /* Copyright 1996-2014 */
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
18 18
19 /* Greg Hitchcock from Microsoft has helped a lot in resolving unclear */ 19 /* Greg Hitchcock from Microsoft has helped a lot in resolving unclear */
20 /* issues; many thanks! */ 20 /* issues; many thanks! */
21 21
22 22
23 #include "../../include/ft2build.h" 23 #include <ft2build.h>
24 #include "../../include/freetype/internal/ftdebug.h" 24 #include FT_INTERNAL_DEBUG_H
25 #include "../../include/freetype/internal/ftcalc.h" 25 #include FT_INTERNAL_CALC_H
26 #include "../../include/freetype/fttrigon.h" 26 #include FT_TRIGONOMETRY_H
27 #include "../../include/freetype/ftsystem.h" 27 #include FT_SYSTEM_H
28 #include "../../include/freetype/ftttdrv.h" 28 #include FT_TRUETYPE_DRIVER_H
29 29
30 #include "ttinterp.h" 30 #include "ttinterp.h"
31 #include "tterrors.h" 31 #include "tterrors.h"
32 #include "ttsubpix.h" 32 #include "ttsubpix.h"
33 33
34 34
35 #ifdef TT_USE_BYTECODE_INTERPRETER 35 #ifdef TT_USE_BYTECODE_INTERPRETER
36 36
37 37
38 /*************************************************************************/ 38 /*************************************************************************/
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 165
166 #define CUR_Func_move( z, p, d ) \ 166 #define CUR_Func_move( z, p, d ) \
167 CUR.func_move( EXEC_ARG_ z, p, d ) 167 CUR.func_move( EXEC_ARG_ z, p, d )
168 168
169 #define CUR_Func_move_orig( z, p, d ) \ 169 #define CUR_Func_move_orig( z, p, d ) \
170 CUR.func_move_orig( EXEC_ARG_ z, p, d ) 170 CUR.func_move_orig( EXEC_ARG_ z, p, d )
171 171
172 #define CUR_Func_round( d, c ) \ 172 #define CUR_Func_round( d, c ) \
173 CUR.func_round( EXEC_ARG_ d, c ) 173 CUR.func_round( EXEC_ARG_ d, c )
174 174
175 #define CUR_Func_cur_ppem() \
176 CUR.func_cur_ppem( EXEC_ARG )
177
175 #define CUR_Func_read_cvt( index ) \ 178 #define CUR_Func_read_cvt( index ) \
176 CUR.func_read_cvt( EXEC_ARG_ index ) 179 CUR.func_read_cvt( EXEC_ARG_ index )
177 180
178 #define CUR_Func_write_cvt( index, val ) \ 181 #define CUR_Func_write_cvt( index, val ) \
179 CUR.func_write_cvt( EXEC_ARG_ index, val ) 182 CUR.func_write_cvt( EXEC_ARG_ index, val )
180 183
181 #define CUR_Func_move_cvt( index, val ) \ 184 #define CUR_Func_move_cvt( index, val ) \
182 CUR.func_move_cvt( EXEC_ARG_ index, val ) 185 CUR.func_move_cvt( EXEC_ARG_ index, val )
183 186
184 #define CURRENT_Ratio() \ 187 #define CURRENT_Ratio() \
185 Current_Ratio( EXEC_ARG ) 188 Current_Ratio( EXEC_ARG )
186 189
187 #define CURRENT_Ppem() \
188 Current_Ppem( EXEC_ARG )
189
190 #define CUR_Ppem() \
191 Cur_PPEM( EXEC_ARG )
192
193 #define INS_SxVTL( a, b, c, d ) \ 190 #define INS_SxVTL( a, b, c, d ) \
194 Ins_SxVTL( EXEC_ARG_ a, b, c, d ) 191 Ins_SxVTL( EXEC_ARG_ a, b, c, d )
195 192
196 #define COMPUTE_Funcs() \ 193 #define COMPUTE_Funcs() \
197 Compute_Funcs( EXEC_ARG ) 194 Compute_Funcs( EXEC_ARG )
198 195
199 #define COMPUTE_Round( a ) \ 196 #define COMPUTE_Round( a ) \
200 Compute_Round( EXEC_ARG_ a ) 197 Compute_Round( EXEC_ARG_ a )
201 198
202 #define COMPUTE_Point_Displacement( a, b, c, d ) \ 199 #define COMPUTE_Point_Displacement( a, b, c, d ) \
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 /* `exec', and `IP'). */ 272 /* `exec', and `IP'). */
276 /* */ 273 /* */
277 /* <Input> */ 274 /* <Input> */
278 /* range :: The new execution code range. */ 275 /* range :: The new execution code range. */
279 /* */ 276 /* */
280 /* IP :: The new IP in the new code range. */ 277 /* IP :: The new IP in the new code range. */
281 /* */ 278 /* */
282 /* <InOut> */ 279 /* <InOut> */
283 /* exec :: The target execution context. */ 280 /* exec :: The target execution context. */
284 /* */ 281 /* */
285 /* <Return> */ 282 FT_LOCAL_DEF( void )
286 /* FreeType error code. 0 means success. */
287 /* */
288 FT_LOCAL_DEF( FT_Error )
289 TT_Goto_CodeRange( TT_ExecContext exec, 283 TT_Goto_CodeRange( TT_ExecContext exec,
290 FT_Int range, 284 FT_Int range,
291 FT_Long IP ) 285 FT_Long IP )
292 { 286 {
293 TT_CodeRange* coderange; 287 TT_CodeRange* coderange;
294 288
295 289
296 FT_ASSERT( range >= 1 && range <= 3 ); 290 FT_ASSERT( range >= 1 && range <= 3 );
297 291
298 coderange = &exec->codeRangeTable[range - 1]; 292 coderange = &exec->codeRangeTable[range - 1];
299 293
300 FT_ASSERT( coderange->base != NULL ); 294 FT_ASSERT( coderange->base != NULL );
301 295
302 /* NOTE: Because the last instruction of a program may be a CALL */ 296 /* NOTE: Because the last instruction of a program may be a CALL */
303 /* which will return to the first byte *after* the code */ 297 /* which will return to the first byte *after* the code */
304 /* range, we test for IP <= Size instead of IP < Size. */ 298 /* range, we test for IP <= Size instead of IP < Size. */
305 /* */ 299 /* */
306 FT_ASSERT( (FT_ULong)IP <= coderange->size ); 300 FT_ASSERT( (FT_ULong)IP <= coderange->size );
307 301
308 exec->code = coderange->base; 302 exec->code = coderange->base;
309 exec->codeSize = coderange->size; 303 exec->codeSize = coderange->size;
310 exec->IP = IP; 304 exec->IP = IP;
311 exec->curRange = range; 305 exec->curRange = range;
312
313 return FT_Err_Ok;
314 } 306 }
315 307
316 308
317 /*************************************************************************/ 309 /*************************************************************************/
318 /* */ 310 /* */
319 /* <Function> */ 311 /* <Function> */
320 /* TT_Set_CodeRange */ 312 /* TT_Set_CodeRange */
321 /* */ 313 /* */
322 /* <Description> */ 314 /* <Description> */
323 /* Sets a code range. */ 315 /* Sets a code range. */
324 /* */ 316 /* */
325 /* <Input> */ 317 /* <Input> */
326 /* range :: The code range index. */ 318 /* range :: The code range index. */
327 /* */ 319 /* */
328 /* base :: The new code base. */ 320 /* base :: The new code base. */
329 /* */ 321 /* */
330 /* length :: The range size in bytes. */ 322 /* length :: The range size in bytes. */
331 /* */ 323 /* */
332 /* <InOut> */ 324 /* <InOut> */
333 /* exec :: The target execution context. */ 325 /* exec :: The target execution context. */
334 /* */ 326 /* */
335 /* <Return> */ 327 FT_LOCAL_DEF( void )
336 /* FreeType error code. 0 means success. */
337 /* */
338 FT_LOCAL_DEF( FT_Error )
339 TT_Set_CodeRange( TT_ExecContext exec, 328 TT_Set_CodeRange( TT_ExecContext exec,
340 FT_Int range, 329 FT_Int range,
341 void* base, 330 void* base,
342 FT_Long length ) 331 FT_Long length )
343 { 332 {
344 FT_ASSERT( range >= 1 && range <= 3 ); 333 FT_ASSERT( range >= 1 && range <= 3 );
345 334
346 exec->codeRangeTable[range - 1].base = (FT_Byte*)base; 335 exec->codeRangeTable[range - 1].base = (FT_Byte*)base;
347 exec->codeRangeTable[range - 1].size = length; 336 exec->codeRangeTable[range - 1].size = length;
348
349 return FT_Err_Ok;
350 } 337 }
351 338
352 339
353 /*************************************************************************/ 340 /*************************************************************************/
354 /* */ 341 /* */
355 /* <Function> */ 342 /* <Function> */
356 /* TT_Clear_CodeRange */ 343 /* TT_Clear_CodeRange */
357 /* */ 344 /* */
358 /* <Description> */ 345 /* <Description> */
359 /* Clears a code range. */ 346 /* Clears a code range. */
360 /* */ 347 /* */
361 /* <Input> */ 348 /* <Input> */
362 /* range :: The code range index. */ 349 /* range :: The code range index. */
363 /* */ 350 /* */
364 /* <InOut> */ 351 /* <InOut> */
365 /* exec :: The target execution context. */ 352 /* exec :: The target execution context. */
366 /* */ 353 /* */
367 /* <Return> */ 354 FT_LOCAL_DEF( void )
368 /* FreeType error code. 0 means success. */
369 /* */
370 /* <Note> */
371 /* Does not set the Error variable. */
372 /* */
373 FT_LOCAL_DEF( FT_Error )
374 TT_Clear_CodeRange( TT_ExecContext exec, 355 TT_Clear_CodeRange( TT_ExecContext exec,
375 FT_Int range ) 356 FT_Int range )
376 { 357 {
377 FT_ASSERT( range >= 1 && range <= 3 ); 358 FT_ASSERT( range >= 1 && range <= 3 );
378 359
379 exec->codeRangeTable[range - 1].base = NULL; 360 exec->codeRangeTable[range - 1].base = NULL;
380 exec->codeRangeTable[range - 1].size = 0; 361 exec->codeRangeTable[range - 1].size = 0;
381
382 return FT_Err_Ok;
383 } 362 }
384 363
385 364
386 /*************************************************************************/ 365 /*************************************************************************/
387 /* */ 366 /* */
388 /* EXECUTION CONTEXT ROUTINES */ 367 /* EXECUTION CONTEXT ROUTINES */
389 /* */ 368 /* */
390 /*************************************************************************/ 369 /*************************************************************************/
391 370
392 371
393 /*************************************************************************/ 372 /*************************************************************************/
394 /* */ 373 /* */
395 /* <Function> */ 374 /* <Function> */
396 /* TT_Done_Context */ 375 /* TT_Done_Context */
397 /* */ 376 /* */
398 /* <Description> */ 377 /* <Description> */
399 /* Destroys a given context. */ 378 /* Destroys a given context. */
400 /* */ 379 /* */
401 /* <Input> */ 380 /* <Input> */
402 /* exec :: A handle to the target execution context. */ 381 /* exec :: A handle to the target execution context. */
403 /* */ 382 /* */
404 /* memory :: A handle to the parent memory object. */ 383 /* memory :: A handle to the parent memory object. */
405 /* */ 384 /* */
406 /* <Return> */
407 /* FreeType error code. 0 means success. */
408 /* */
409 /* <Note> */ 385 /* <Note> */
410 /* Only the glyph loader and debugger should call this function. */ 386 /* Only the glyph loader and debugger should call this function. */
411 /* */ 387 /* */
412 FT_LOCAL_DEF( FT_Error ) 388 FT_LOCAL_DEF( void )
413 TT_Done_Context( TT_ExecContext exec ) 389 TT_Done_Context( TT_ExecContext exec )
414 { 390 {
415 FT_Memory memory = exec->memory; 391 FT_Memory memory = exec->memory;
416 392
417 393
418 /* points zone */ 394 /* points zone */
419 exec->maxPoints = 0; 395 exec->maxPoints = 0;
420 exec->maxContours = 0; 396 exec->maxContours = 0;
421 397
422 /* free stack */ 398 /* free stack */
423 FT_FREE( exec->stack ); 399 FT_FREE( exec->stack );
424 exec->stackSize = 0; 400 exec->stackSize = 0;
425 401
426 /* free call stack */ 402 /* free call stack */
427 FT_FREE( exec->callStack ); 403 FT_FREE( exec->callStack );
428 exec->callSize = 0; 404 exec->callSize = 0;
429 exec->callTop = 0; 405 exec->callTop = 0;
430 406
431 /* free glyph code range */ 407 /* free glyph code range */
432 FT_FREE( exec->glyphIns ); 408 FT_FREE( exec->glyphIns );
433 exec->glyphSize = 0; 409 exec->glyphSize = 0;
434 410
435 exec->size = NULL; 411 exec->size = NULL;
436 exec->face = NULL; 412 exec->face = NULL;
437 413
438 FT_FREE( exec ); 414 FT_FREE( exec );
439
440 return FT_Err_Ok;
441 } 415 }
442 416
443 417
444 /*************************************************************************/ 418 /*************************************************************************/
445 /* */ 419 /* */
446 /* <Function> */ 420 /* <Function> */
447 /* Init_Context */ 421 /* Init_Context */
448 /* */ 422 /* */
449 /* <Description> */ 423 /* <Description> */
450 /* Initializes a context object. */ 424 /* Initializes a context object. */
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 /* */ 631 /* */
658 /* <Description> */ 632 /* <Description> */
659 /* Saves the code ranges in a `size' object. */ 633 /* Saves the code ranges in a `size' object. */
660 /* */ 634 /* */
661 /* <Input> */ 635 /* <Input> */
662 /* exec :: A handle to the source execution context. */ 636 /* exec :: A handle to the source execution context. */
663 /* */ 637 /* */
664 /* <InOut> */ 638 /* <InOut> */
665 /* size :: A handle to the target size object. */ 639 /* size :: A handle to the target size object. */
666 /* */ 640 /* */
667 /* <Return> */
668 /* FreeType error code. 0 means success. */
669 /* */
670 /* <Note> */ 641 /* <Note> */
671 /* Only the glyph loader and debugger should call this function. */ 642 /* Only the glyph loader and debugger should call this function. */
672 /* */ 643 /* */
673 FT_LOCAL_DEF( FT_Error ) 644 FT_LOCAL_DEF( void )
674 TT_Save_Context( TT_ExecContext exec, 645 TT_Save_Context( TT_ExecContext exec,
675 TT_Size size ) 646 TT_Size size )
676 { 647 {
677 FT_Int i; 648 FT_Int i;
678 649
679 650
680 /* XXX: Will probably disappear soon with all the code range */ 651 /* XXX: Will probably disappear soon with all the code range */
681 /* management, which is now rather obsolete. */ 652 /* management, which is now rather obsolete. */
682 /* */ 653 /* */
683 size->num_function_defs = exec->numFDefs; 654 size->num_function_defs = exec->numFDefs;
684 size->num_instruction_defs = exec->numIDefs; 655 size->num_instruction_defs = exec->numIDefs;
685 656
686 size->max_func = exec->maxFunc; 657 size->max_func = exec->maxFunc;
687 size->max_ins = exec->maxIns; 658 size->max_ins = exec->maxIns;
688 659
689 for ( i = 0; i < TT_MAX_CODE_RANGES; i++ ) 660 for ( i = 0; i < TT_MAX_CODE_RANGES; i++ )
690 size->codeRangeTable[i] = exec->codeRangeTable[i]; 661 size->codeRangeTable[i] = exec->codeRangeTable[i];
691
692 return FT_Err_Ok;
693 } 662 }
694 663
695 664
696 /*************************************************************************/ 665 /*************************************************************************/
697 /* */ 666 /* */
698 /* <Function> */ 667 /* <Function> */
699 /* TT_Run_Context */ 668 /* TT_Run_Context */
700 /* */ 669 /* */
701 /* <Description> */ 670 /* <Description> */
702 /* Executes one or more instructions in the execution context. */ 671 /* Executes one or more instructions in the execution context. */
(...skipping 11 matching lines...) Expand all
714 /* <Return> */ 683 /* <Return> */
715 /* TrueType error code. 0 means success. */ 684 /* TrueType error code. 0 means success. */
716 /* */ 685 /* */
717 /* <Note> */ 686 /* <Note> */
718 /* Only the glyph loader and debugger should call this function. */ 687 /* Only the glyph loader and debugger should call this function. */
719 /* */ 688 /* */
720 FT_LOCAL_DEF( FT_Error ) 689 FT_LOCAL_DEF( FT_Error )
721 TT_Run_Context( TT_ExecContext exec, 690 TT_Run_Context( TT_ExecContext exec,
722 FT_Bool debug ) 691 FT_Bool debug )
723 { 692 {
724 FT_Error error; 693 TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 );
725
726
727 if ( ( error = TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 ) )
728 != FT_Err_Ok )
729 return error;
730 694
731 exec->zp0 = exec->pts; 695 exec->zp0 = exec->pts;
732 exec->zp1 = exec->pts; 696 exec->zp1 = exec->pts;
733 exec->zp2 = exec->pts; 697 exec->zp2 = exec->pts;
734 698
735 exec->GS.gep0 = 1; 699 exec->GS.gep0 = 1;
736 exec->GS.gep1 = 1; 700 exec->GS.gep1 = 1;
737 exec->GS.gep2 = 1; 701 exec->GS.gep2 = 1;
738 702
739 exec->GS.projVector.x = 0x4000; 703 exec->GS.projVector.x = 0x4000;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 TRUE, 68, 0, 0, 9, 3, 753 TRUE, 68, 0, 0, 9, 3,
790 0, FALSE, 0, 1, 1, 1 754 0, FALSE, 0, 1, 1, 1
791 }; 755 };
792 756
793 757
794 /* documentation is in ttinterp.h */ 758 /* documentation is in ttinterp.h */
795 759
796 FT_EXPORT_DEF( TT_ExecContext ) 760 FT_EXPORT_DEF( TT_ExecContext )
797 TT_New_Context( TT_Driver driver ) 761 TT_New_Context( TT_Driver driver )
798 { 762 {
799 TT_ExecContext exec; 763 FT_Memory memory;
800 FT_Memory memory;
801 764
802 765
766 if ( !driver )
767 goto Fail;
768
803 memory = driver->root.root.memory; 769 memory = driver->root.root.memory;
804 exec = driver->context;
805 770
806 if ( !driver->context ) 771 if ( !driver->context )
807 { 772 {
808 FT_Error error; 773 FT_Error error;
774 TT_ExecContext exec;
809 775
810 776
811 /* allocate object */ 777 /* allocate object */
812 if ( FT_NEW( exec ) ) 778 if ( FT_NEW( exec ) )
813 goto Fail; 779 goto Fail;
814 780
815 /* initialize it; in case of error this deallocates `exec' too */ 781 /* initialize it; in case of error this deallocates `exec' too */
816 error = Init_Context( exec, memory ); 782 error = Init_Context( exec, memory );
817 if ( error ) 783 if ( error )
818 goto Fail; 784 goto Fail;
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after
1430 2, 3, 4, 5, 6, 7, 8, 9, 3, 5, 7, 9, 11,13,15,17, 1396 2, 3, 4, 5, 6, 7, 8, 9, 3, 5, 7, 9, 11,13,15,17,
1431 1397
1432 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1398 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1433 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1399 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1434 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1400 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1435 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 1401 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
1436 }; 1402 };
1437 1403
1438 #undef PACK 1404 #undef PACK
1439 1405
1440 #if 1
1441 1406
1407 #ifndef FT_CONFIG_OPTION_NO_ASSEMBLER
1408
1409 #if defined( __arm__ ) && \
1410 ( defined( __thumb2__ ) || !defined( __thumb__ ) )
1411
1412 #define TT_MulFix14 TT_MulFix14_arm
1413
1414 static FT_Int32
1415 TT_MulFix14_arm( FT_Int32 a,
1416 FT_Int b )
1417 {
1418 FT_Int32 t, t2;
1419
1420
1421 #if defined( __CC_ARM ) || defined( __ARMCC__ )
1422
1423 __asm
1424 {
1425 smull t2, t, b, a /* (lo=t2,hi=t) = a*b */
1426 mov a, t, asr #31 /* a = (hi >> 31) */
1427 add a, a, #0x2000 /* a += 0x2000 */
1428 adds t2, t2, a /* t2 += a */
1429 adc t, t, #0 /* t += carry */
1430 mov a, t2, lsr #14 /* a = t2 >> 14 */
1431 orr a, a, t, lsl #18 /* a |= t << 18 */
1432 }
1433
1434 #elif defined( __GNUC__ )
1435
1436 __asm__ __volatile__ (
1437 "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */
1438 "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */
1439 #if defined( __clang__ ) && defined( __thumb2__ )
1440 "add.w %0, %0, #0x2000\n\t" /* %0 += 0x2000 */
1441 #else
1442 "add %0, %0, #0x2000\n\t" /* %0 += 0x2000 */
1443 #endif
1444 "adds %1, %1, %0\n\t" /* %1 += %0 */
1445 "adc %2, %2, #0\n\t" /* %2 += carry */
1446 "mov %0, %1, lsr #14\n\t" /* %0 = %1 >> 16 */
1447 "orr %0, %0, %2, lsl #18\n\t" /* %0 |= %2 << 16 */
1448 : "=r"(a), "=&r"(t2), "=&r"(t)
1449 : "r"(a), "r"(b)
1450 : "cc" );
1451
1452 #endif
1453
1454 return a;
1455 }
1456
1457 #endif /* __arm__ && ( __thumb2__ || !__thumb__ ) */
1458
1459 #endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */
1460
1461
1462 #if defined( __GNUC__ ) && \
1463 ( defined( __i386__ ) || defined( __x86_64__ ) )
1464
1465 #define TT_MulFix14 TT_MulFix14_long_long
1466
1467 /* Temporarily disable the warning that C90 doesn't support `long long'. */
1468 #if ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 406
1469 #pragma GCC diagnostic push
1470 #endif
1471 #pragma GCC diagnostic ignored "-Wlong-long"
1472
1473 /* This is declared `noinline' because inlining the function results */
1474 /* in slower code. The `pure' attribute indicates that the result */
1475 /* only depends on the parameters. */
1476 static __attribute__(( noinline ))
1477 __attribute__(( pure )) FT_Int32
1478 TT_MulFix14_long_long( FT_Int32 a,
1479 FT_Int b )
1480 {
1481
1482 long long ret = (long long)a * b;
1483
1484 /* The following line assumes that right shifting of signed values */
1485 /* will actually preserve the sign bit. The exact behaviour is */
1486 /* undefined, but this is true on x86 and x86_64. */
1487 long long tmp = ret >> 63;
1488
1489
1490 ret += 0x2000 + tmp;
1491
1492 return (FT_Int32)( ret >> 14 );
1493 }
1494
1495 #if ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 406
1496 #pragma GCC diagnostic pop
1497 #endif
1498
1499 #endif /* __GNUC__ && ( __i386__ || __x86_64__ ) */
1500
1501
1502 #ifndef TT_MulFix14
1503
1504 /* Compute (a*b)/2^14 with maximum accuracy and rounding. */
1505 /* This is optimized to be faster than calling FT_MulFix() */
1506 /* for platforms where sizeof(int) == 2. */
1442 static FT_Int32 1507 static FT_Int32
1443 TT_MulFix14( FT_Int32 a, 1508 TT_MulFix14( FT_Int32 a,
1444 FT_Int b ) 1509 FT_Int b )
1445 { 1510 {
1446 FT_Int32 sign; 1511 FT_Int32 sign;
1447 FT_UInt32 ah, al, mid, lo, hi; 1512 FT_UInt32 ah, al, mid, lo, hi;
1448 1513
1449 1514
1450 sign = a ^ b; 1515 sign = a ^ b;
1451 1516
(...skipping 11 matching lines...) Expand all
1463 mid = ( mid << 16 ) + ( 1 << 13 ); /* rounding */ 1528 mid = ( mid << 16 ) + ( 1 << 13 ); /* rounding */
1464 lo += mid; 1529 lo += mid;
1465 if ( lo < mid ) 1530 if ( lo < mid )
1466 hi += 1; 1531 hi += 1;
1467 1532
1468 mid = ( lo >> 14 ) | ( hi << 18 ); 1533 mid = ( lo >> 14 ) | ( hi << 18 );
1469 1534
1470 return sign >= 0 ? (FT_Int32)mid : -(FT_Int32)mid; 1535 return sign >= 0 ? (FT_Int32)mid : -(FT_Int32)mid;
1471 } 1536 }
1472 1537
1473 #else 1538 #endif /* !TT_MulFix14 */
1474
1475 /* compute (a*b)/2^14 with maximum accuracy and rounding */
1476 static FT_Int32
1477 TT_MulFix14( FT_Int32 a,
1478 FT_Int b )
1479 {
1480 FT_Int32 m, s, hi;
1481 FT_UInt32 l, lo;
1482 1539
1483 1540
1484 /* compute ax*bx as 64-bit value */ 1541 #if defined( __GNUC__ ) && \
1485 l = (FT_UInt32)( ( a & 0xFFFFU ) * b ); 1542 ( defined( __i386__ ) || \
1486 m = ( a >> 16 ) * b; 1543 defined( __x86_64__ ) || \
1544 defined( __arm__ ) )
1487 1545
1488 lo = l + ( (FT_UInt32)m << 16 ); 1546 #define TT_DotFix14 TT_DotFix14_long_long
1489 hi = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo < l );
1490 1547
1491 /* divide the result by 2^14 with rounding */ 1548 #if ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 406
1492 s = hi >> 31; 1549 #pragma GCC diagnostic push
1493 l = lo + (FT_UInt32)s; 1550 #endif
1494 hi += s + ( l < lo ); 1551 #pragma GCC diagnostic ignored "-Wlong-long"
1495 lo = l;
1496 1552
1497 l = lo + 0x2000U; 1553 static __attribute__(( pure )) FT_Int32
1498 hi += l < lo; 1554 TT_DotFix14_long_long( FT_Int32 ax,
1555 FT_Int32 ay,
1556 FT_Int bx,
1557 FT_Int by )
1558 {
1559 /* Temporarily disable the warning that C90 doesn't support */
1560 /* `long long'. */
1499 1561
1500 return (FT_Int32)( ( (FT_UInt32)hi << 18 ) | ( l >> 14 ) ); 1562 long long temp1 = (long long)ax * bx;
1563 long long temp2 = (long long)ay * by;
1564
1565
1566 temp1 += temp2;
1567 temp2 = temp1 >> 63;
1568 temp1 += 0x2000 + temp2;
1569
1570 return (FT_Int32)( temp1 >> 14 );
1571
1501 } 1572 }
1573
1574 #if ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 406
1575 #pragma GCC diagnostic pop
1502 #endif 1576 #endif
1503 1577
1578 #endif /* __GNUC__ && (__arm__ || __i386__ || __x86_64__) */
1579
1580
1581 #ifndef TT_DotFix14
1504 1582
1505 /* compute (ax*bx+ay*by)/2^14 with maximum accuracy and rounding */ 1583 /* compute (ax*bx+ay*by)/2^14 with maximum accuracy and rounding */
1506 static FT_Int32 1584 static FT_Int32
1507 TT_DotFix14( FT_Int32 ax, 1585 TT_DotFix14( FT_Int32 ax,
1508 FT_Int32 ay, 1586 FT_Int32 ay,
1509 FT_Int bx, 1587 FT_Int bx,
1510 FT_Int by ) 1588 FT_Int by )
1511 { 1589 {
1512 FT_Int32 m, s, hi1, hi2, hi; 1590 FT_Int32 m, s, hi1, hi2, hi;
1513 FT_UInt32 l, lo1, lo2, lo; 1591 FT_UInt32 l, lo1, lo2, lo;
(...skipping 22 matching lines...) Expand all
1536 l = lo + (FT_UInt32)s; 1614 l = lo + (FT_UInt32)s;
1537 hi += s + ( l < lo ); 1615 hi += s + ( l < lo );
1538 lo = l; 1616 lo = l;
1539 1617
1540 l = lo + 0x2000U; 1618 l = lo + 0x2000U;
1541 hi += ( l < lo ); 1619 hi += ( l < lo );
1542 1620
1543 return (FT_Int32)( ( (FT_UInt32)hi << 18 ) | ( l >> 14 ) ); 1621 return (FT_Int32)( ( (FT_UInt32)hi << 18 ) | ( l >> 14 ) );
1544 } 1622 }
1545 1623
1624 #endif /* TT_DotFix14 */
1625
1546 1626
1547 /*************************************************************************/ 1627 /*************************************************************************/
1548 /* */ 1628 /* */
1549 /* <Function> */ 1629 /* <Function> */
1550 /* Current_Ratio */ 1630 /* Current_Ratio */
1551 /* */ 1631 /* */
1552 /* <Description> */ 1632 /* <Description> */
1553 /* Returns the current aspect ratio scaling factor depending on the */ 1633 /* Returns the current aspect ratio scaling factor depending on the */
1554 /* projection vector's state and device resolutions. */ 1634 /* projection vector's state and device resolutions. */
1555 /* */ 1635 /* */
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1588 y = TT_MulFix14( CUR.tt_metrics.y_ratio, 1668 y = TT_MulFix14( CUR.tt_metrics.y_ratio,
1589 CUR.GS.projVector.y ); 1669 CUR.GS.projVector.y );
1590 CUR.tt_metrics.ratio = FT_Hypot( x, y ); 1670 CUR.tt_metrics.ratio = FT_Hypot( x, y );
1591 } 1671 }
1592 } 1672 }
1593 } 1673 }
1594 return CUR.tt_metrics.ratio; 1674 return CUR.tt_metrics.ratio;
1595 } 1675 }
1596 1676
1597 1677
1598 static FT_Long 1678 FT_CALLBACK_DEF( FT_Long )
1599 Current_Ppem( EXEC_OP ) 1679 Current_Ppem( EXEC_OP )
1600 { 1680 {
1681 return CUR.tt_metrics.ppem;
1682 }
1683
1684
1685 FT_CALLBACK_DEF( FT_Long )
1686 Current_Ppem_Stretched( EXEC_OP )
1687 {
1601 return FT_MulFix( CUR.tt_metrics.ppem, CURRENT_Ratio() ); 1688 return FT_MulFix( CUR.tt_metrics.ppem, CURRENT_Ratio() );
1602 } 1689 }
1603 1690
1604 1691
1605 /*************************************************************************/ 1692 /*************************************************************************/
1606 /* */ 1693 /* */
1607 /* Functions related to the control value table (CVT). */ 1694 /* Functions related to the control value table (CVT). */
1608 /* */ 1695 /* */
1609 /*************************************************************************/ 1696 /*************************************************************************/
1610 1697
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
1929 FT_F26Dot6 compensation ) 2016 FT_F26Dot6 compensation )
1930 { 2017 {
1931 FT_F26Dot6 val; 2018 FT_F26Dot6 val;
1932 2019
1933 FT_UNUSED_EXEC; 2020 FT_UNUSED_EXEC;
1934 2021
1935 2022
1936 if ( distance >= 0 ) 2023 if ( distance >= 0 )
1937 { 2024 {
1938 val = distance + compensation; 2025 val = distance + compensation;
1939 if ( distance && val < 0 ) 2026 if ( val < 0 )
1940 val = 0; 2027 val = 0;
1941 } 2028 }
1942 else 2029 else
1943 { 2030 {
1944 val = distance - compensation; 2031 val = distance - compensation;
1945 if ( val > 0 ) 2032 if ( val > 0 )
1946 val = 0; 2033 val = 0;
1947 } 2034 }
1948 return val; 2035 return val;
1949 } 2036 }
(...skipping 19 matching lines...) Expand all
1969 Round_To_Grid( EXEC_OP_ FT_F26Dot6 distance, 2056 Round_To_Grid( EXEC_OP_ FT_F26Dot6 distance,
1970 FT_F26Dot6 compensation ) 2057 FT_F26Dot6 compensation )
1971 { 2058 {
1972 FT_F26Dot6 val; 2059 FT_F26Dot6 val;
1973 2060
1974 FT_UNUSED_EXEC; 2061 FT_UNUSED_EXEC;
1975 2062
1976 2063
1977 if ( distance >= 0 ) 2064 if ( distance >= 0 )
1978 { 2065 {
1979 val = distance + compensation + 32; 2066 val = FT_PIX_ROUND( distance + compensation );
1980 if ( distance && val > 0 ) 2067 if ( val < 0 )
1981 val &= ~63;
1982 else
1983 val = 0; 2068 val = 0;
1984 } 2069 }
1985 else 2070 else
1986 { 2071 {
1987 val = -FT_PIX_ROUND( compensation - distance ); 2072 val = -FT_PIX_ROUND( compensation - distance );
1988 if ( val > 0 ) 2073 if ( val > 0 )
1989 val = 0; 2074 val = 0;
1990 } 2075 }
1991 2076
1992 return val; 2077 return val;
(...skipping 21 matching lines...) Expand all
2014 FT_F26Dot6 compensation ) 2099 FT_F26Dot6 compensation )
2015 { 2100 {
2016 FT_F26Dot6 val; 2101 FT_F26Dot6 val;
2017 2102
2018 FT_UNUSED_EXEC; 2103 FT_UNUSED_EXEC;
2019 2104
2020 2105
2021 if ( distance >= 0 ) 2106 if ( distance >= 0 )
2022 { 2107 {
2023 val = FT_PIX_FLOOR( distance + compensation ) + 32; 2108 val = FT_PIX_FLOOR( distance + compensation ) + 32;
2024 if ( distance && val < 0 ) 2109 if ( val < 0 )
2025 val = 0; 2110 val = 32;
2026 } 2111 }
2027 else 2112 else
2028 { 2113 {
2029 val = -( FT_PIX_FLOOR( compensation - distance ) + 32 ); 2114 val = -( FT_PIX_FLOOR( compensation - distance ) + 32 );
2030 if ( val > 0 ) 2115 if ( val > 0 )
2031 val = 0; 2116 val = -32;
2032 } 2117 }
2033 2118
2034 return val; 2119 return val;
2035 } 2120 }
2036 2121
2037 2122
2038 /*************************************************************************/ 2123 /*************************************************************************/
2039 /* */ 2124 /* */
2040 /* <Function> */ 2125 /* <Function> */
2041 /* Round_Down_To_Grid */ 2126 /* Round_Down_To_Grid */
(...skipping 13 matching lines...) Expand all
2055 Round_Down_To_Grid( EXEC_OP_ FT_F26Dot6 distance, 2140 Round_Down_To_Grid( EXEC_OP_ FT_F26Dot6 distance,
2056 FT_F26Dot6 compensation ) 2141 FT_F26Dot6 compensation )
2057 { 2142 {
2058 FT_F26Dot6 val; 2143 FT_F26Dot6 val;
2059 2144
2060 FT_UNUSED_EXEC; 2145 FT_UNUSED_EXEC;
2061 2146
2062 2147
2063 if ( distance >= 0 ) 2148 if ( distance >= 0 )
2064 { 2149 {
2065 val = distance + compensation; 2150 val = FT_PIX_FLOOR( distance + compensation );
2066 if ( distance && val > 0 ) 2151 if ( val < 0 )
2067 val &= ~63;
2068 else
2069 val = 0; 2152 val = 0;
2070 } 2153 }
2071 else 2154 else
2072 { 2155 {
2073 val = -( ( compensation - distance ) & -64 ); 2156 val = -FT_PIX_FLOOR( compensation - distance );
2074 if ( val > 0 ) 2157 if ( val > 0 )
2075 val = 0; 2158 val = 0;
2076 } 2159 }
2077 2160
2078 return val; 2161 return val;
2079 } 2162 }
2080 2163
2081 2164
2082 /*************************************************************************/ 2165 /*************************************************************************/
2083 /* */ 2166 /* */
(...skipping 15 matching lines...) Expand all
2099 Round_Up_To_Grid( EXEC_OP_ FT_F26Dot6 distance, 2182 Round_Up_To_Grid( EXEC_OP_ FT_F26Dot6 distance,
2100 FT_F26Dot6 compensation ) 2183 FT_F26Dot6 compensation )
2101 { 2184 {
2102 FT_F26Dot6 val; 2185 FT_F26Dot6 val;
2103 2186
2104 FT_UNUSED_EXEC; 2187 FT_UNUSED_EXEC;
2105 2188
2106 2189
2107 if ( distance >= 0 ) 2190 if ( distance >= 0 )
2108 { 2191 {
2109 val = distance + compensation + 63; 2192 val = FT_PIX_CEIL( distance + compensation );
2110 if ( distance && val > 0 ) 2193 if ( val < 0 )
2111 val &= ~63;
2112 else
2113 val = 0; 2194 val = 0;
2114 } 2195 }
2115 else 2196 else
2116 { 2197 {
2117 val = -FT_PIX_CEIL( compensation - distance ); 2198 val = -FT_PIX_CEIL( compensation - distance );
2118 if ( val > 0 ) 2199 if ( val > 0 )
2119 val = 0; 2200 val = 0;
2120 } 2201 }
2121 2202
2122 return val; 2203 return val;
(...skipping 20 matching lines...) Expand all
2143 Round_To_Double_Grid( EXEC_OP_ FT_F26Dot6 distance, 2224 Round_To_Double_Grid( EXEC_OP_ FT_F26Dot6 distance,
2144 FT_F26Dot6 compensation ) 2225 FT_F26Dot6 compensation )
2145 { 2226 {
2146 FT_F26Dot6 val; 2227 FT_F26Dot6 val;
2147 2228
2148 FT_UNUSED_EXEC; 2229 FT_UNUSED_EXEC;
2149 2230
2150 2231
2151 if ( distance >= 0 ) 2232 if ( distance >= 0 )
2152 { 2233 {
2153 val = distance + compensation + 16; 2234 val = FT_PAD_ROUND( distance + compensation, 32 );
2154 if ( distance && val > 0 ) 2235 if ( val < 0 )
2155 val &= ~31;
2156 else
2157 val = 0; 2236 val = 0;
2158 } 2237 }
2159 else 2238 else
2160 { 2239 {
2161 val = -FT_PAD_ROUND( compensation - distance, 32 ); 2240 val = -FT_PAD_ROUND( compensation - distance, 32 );
2162 if ( val > 0 ) 2241 if ( val > 0 )
2163 val = 0; 2242 val = 0;
2164 } 2243 }
2165 2244
2166 return val; 2245 return val;
(...skipping 26 matching lines...) Expand all
2193 Round_Super( EXEC_OP_ FT_F26Dot6 distance, 2272 Round_Super( EXEC_OP_ FT_F26Dot6 distance,
2194 FT_F26Dot6 compensation ) 2273 FT_F26Dot6 compensation )
2195 { 2274 {
2196 FT_F26Dot6 val; 2275 FT_F26Dot6 val;
2197 2276
2198 2277
2199 if ( distance >= 0 ) 2278 if ( distance >= 0 )
2200 { 2279 {
2201 val = ( distance - CUR.phase + CUR.threshold + compensation ) & 2280 val = ( distance - CUR.phase + CUR.threshold + compensation ) &
2202 -CUR.period; 2281 -CUR.period;
2203 if ( distance && val < 0 )
2204 val = 0;
2205 val += CUR.phase; 2282 val += CUR.phase;
2283 if ( val < 0 )
2284 val = CUR.phase;
2206 } 2285 }
2207 else 2286 else
2208 { 2287 {
2209 val = -( ( CUR.threshold - CUR.phase - distance + compensation ) & 2288 val = -( ( CUR.threshold - CUR.phase - distance + compensation ) &
2210 -CUR.period ); 2289 -CUR.period );
2290 val -= CUR.phase;
2211 if ( val > 0 ) 2291 if ( val > 0 )
2212 val = 0; 2292 val = -CUR.phase;
2213 val -= CUR.phase;
2214 } 2293 }
2215 2294
2216 return val; 2295 return val;
2217 } 2296 }
2218 2297
2219 2298
2220 /*************************************************************************/ 2299 /*************************************************************************/
2221 /* */ 2300 /* */
2222 /* <Function> */ 2301 /* <Function> */
2223 /* Round_Super_45 */ 2302 /* Round_Super_45 */
(...skipping 17 matching lines...) Expand all
2241 Round_Super_45( EXEC_OP_ FT_F26Dot6 distance, 2320 Round_Super_45( EXEC_OP_ FT_F26Dot6 distance,
2242 FT_F26Dot6 compensation ) 2321 FT_F26Dot6 compensation )
2243 { 2322 {
2244 FT_F26Dot6 val; 2323 FT_F26Dot6 val;
2245 2324
2246 2325
2247 if ( distance >= 0 ) 2326 if ( distance >= 0 )
2248 { 2327 {
2249 val = ( ( distance - CUR.phase + CUR.threshold + compensation ) / 2328 val = ( ( distance - CUR.phase + CUR.threshold + compensation ) /
2250 CUR.period ) * CUR.period; 2329 CUR.period ) * CUR.period;
2251 if ( distance && val < 0 )
2252 val = 0;
2253 val += CUR.phase; 2330 val += CUR.phase;
2331 if ( val < 0 )
2332 val = CUR.phase;
2254 } 2333 }
2255 else 2334 else
2256 { 2335 {
2257 val = -( ( ( CUR.threshold - CUR.phase - distance + compensation ) / 2336 val = -( ( ( CUR.threshold - CUR.phase - distance + compensation ) /
2258 CUR.period ) * CUR.period ); 2337 CUR.period ) * CUR.period );
2338 val -= CUR.phase;
2259 if ( val > 0 ) 2339 if ( val > 0 )
2260 val = 0; 2340 val = -CUR.phase;
2261 val -= CUR.phase;
2262 } 2341 }
2263 2342
2264 return val; 2343 return val;
2265 } 2344 }
2266 2345
2267 2346
2268 /*************************************************************************/ 2347 /*************************************************************************/
2269 /* */ 2348 /* */
2270 /* <Function> */ 2349 /* <Function> */
2271 /* Compute_Round */ 2350 /* Compute_Round */
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after
2959 3038
2960 3039
2961 #define DO_FLIPON \ 3040 #define DO_FLIPON \
2962 CUR.GS.auto_flip = TRUE; 3041 CUR.GS.auto_flip = TRUE;
2963 3042
2964 3043
2965 #define DO_FLIPOFF \ 3044 #define DO_FLIPOFF \
2966 CUR.GS.auto_flip = FALSE; 3045 CUR.GS.auto_flip = FALSE;
2967 3046
2968 3047
2969 #define DO_SDB \ 3048 #define DO_SDB \
2970 CUR.GS.delta_base = (FT_Short)args[0]; 3049 CUR.GS.delta_base = (FT_UShort)args[0];
2971 3050
2972 3051
2973 #define DO_SDS \ 3052 #define DO_SDS \
2974 CUR.GS.delta_shift = (FT_Short)args[0]; 3053 if ( (FT_ULong)args[0] > 6UL ) \
3054 CUR.error = FT_THROW( Bad_Argument ); \
3055 else \
3056 CUR.GS.delta_shift = (FT_UShort)args[0];
2975 3057
2976 3058
2977 #define DO_MD /* nothing */ 3059 #define DO_MD /* nothing */
2978 3060
2979 3061
2980 #define DO_MPPEM \ 3062 #define DO_MPPEM \
2981 args[0] = CURRENT_Ppem(); 3063 args[0] = CUR_Func_cur_ppem();
2982 3064
2983 3065
2984 /* Note: The pointSize should be irrelevant in a given font program; */ 3066 /* Note: The pointSize should be irrelevant in a given font program; */
2985 /* we thus decide to return only the ppem. */ 3067 /* we thus decide to return only the ppem. */
2986 #if 0 3068 #if 0
2987 3069
2988 #define DO_MPS \ 3070 #define DO_MPS \
2989 args[0] = CUR.metrics.pointSize; 3071 args[0] = CUR.metrics.pointSize;
2990 3072
2991 #else 3073 #else
2992 3074
2993 #define DO_MPS \ 3075 #define DO_MPS \
2994 args[0] = CURRENT_Ppem(); 3076 args[0] = CUR_Func_cur_ppem();
2995 3077
2996 #endif /* 0 */ 3078 #endif /* 0 */
2997 3079
2998 3080
2999 #define DO_DUP \ 3081 #define DO_DUP \
3000 args[1] = args[0]; 3082 args[1] = args[0];
3001 3083
3002 3084
3003 #define DO_CLEAR \ 3085 #define DO_CLEAR \
3004 CUR.new_top = 0; 3086 CUR.new_top = 0;
(...skipping 25 matching lines...) Expand all
3030 { \ 3112 { \
3031 if ( CUR.pedantic_hinting ) \ 3113 if ( CUR.pedantic_hinting ) \
3032 CUR.error = FT_THROW( Invalid_Reference ); \ 3114 CUR.error = FT_THROW( Invalid_Reference ); \
3033 args[0] = 0; \ 3115 args[0] = 0; \
3034 } \ 3116 } \
3035 else \ 3117 else \
3036 args[0] = CUR.stack[CUR.args - L]; \ 3118 args[0] = CUR.stack[CUR.args - L]; \
3037 } 3119 }
3038 3120
3039 3121
3040 #define DO_JROT \ 3122 #define DO_JROT \
3041 if ( args[1] != 0 ) \ 3123 if ( args[1] != 0 ) \
3042 { \ 3124 { \
3043 if ( args[0] == 0 && CUR.args == 0 ) \ 3125 if ( args[0] == 0 && CUR.args == 0 ) \
3044 CUR.error = FT_THROW( Bad_Argument ); \ 3126 CUR.error = FT_THROW( Bad_Argument ); \
3045 CUR.IP += args[0]; \ 3127 CUR.IP += args[0]; \
3046 if ( CUR.IP < 0 || \ 3128 if ( CUR.IP < 0 || \
3047 ( CUR.callTop > 0 && \ 3129 ( CUR.callTop > 0 && \
3048 CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \ 3130 CUR.IP > CUR.callStack[CUR.callTop - 1].Def->end ) ) \
3049 CUR.error = FT_THROW( Bad_Argument ); \ 3131 CUR.error = FT_THROW( Bad_Argument ); \
3050 CUR.step_ins = FALSE; \ 3132 CUR.step_ins = FALSE; \
3051 } 3133 }
3052 3134
3053 3135
3054 #define DO_JMPR \ 3136 #define DO_JMPR \
3055 if ( args[0] == 0 && CUR.args == 0 ) \ 3137 if ( args[0] == 0 && CUR.args == 0 ) \
3056 CUR.error = FT_THROW( Bad_Argument ); \ 3138 CUR.error = FT_THROW( Bad_Argument ); \
3057 CUR.IP += args[0]; \ 3139 CUR.IP += args[0]; \
3058 if ( CUR.IP < 0 || \ 3140 if ( CUR.IP < 0 || \
3059 ( CUR.callTop > 0 && \ 3141 ( CUR.callTop > 0 && \
3060 CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \ 3142 CUR.IP > CUR.callStack[CUR.callTop - 1].Def->end ) ) \
3061 CUR.error = FT_THROW( Bad_Argument ); \ 3143 CUR.error = FT_THROW( Bad_Argument ); \
3062 CUR.step_ins = FALSE; 3144 CUR.step_ins = FALSE;
3063 3145
3064 3146
3065 #define DO_JROF \ 3147 #define DO_JROF \
3066 if ( args[1] == 0 ) \ 3148 if ( args[1] == 0 ) \
3067 { \ 3149 { \
3068 if ( args[0] == 0 && CUR.args == 0 ) \ 3150 if ( args[0] == 0 && CUR.args == 0 ) \
3069 CUR.error = FT_THROW( Bad_Argument ); \ 3151 CUR.error = FT_THROW( Bad_Argument ); \
3070 CUR.IP += args[0]; \ 3152 CUR.IP += args[0]; \
3071 if ( CUR.IP < 0 || \ 3153 if ( CUR.IP < 0 || \
3072 ( CUR.callTop > 0 && \ 3154 ( CUR.callTop > 0 && \
3073 CUR.IP > CUR.callStack[CUR.callTop - 1].Cur_End ) ) \ 3155 CUR.IP > CUR.callStack[CUR.callTop - 1].Def->end ) ) \
3074 CUR.error = FT_THROW( Bad_Argument ); \ 3156 CUR.error = FT_THROW( Bad_Argument ); \
3075 CUR.step_ins = FALSE; \ 3157 CUR.step_ins = FALSE; \
3076 } 3158 }
3077 3159
3078 3160
3079 #define DO_LT \ 3161 #define DO_LT \
3080 args[0] = ( args[0] < args[1] ); 3162 args[0] = ( args[0] < args[1] );
3081 3163
3082 3164
3083 #define DO_LTEQ \ 3165 #define DO_LTEQ \
3084 args[0] = ( args[0] <= args[1] ); 3166 args[0] = ( args[0] <= args[1] );
3085 3167
(...skipping 1695 matching lines...) Expand 10 before | Expand all | Expand 10 after
4781 4863
4782 pRec = &CUR.callStack[CUR.callTop]; 4864 pRec = &CUR.callStack[CUR.callTop];
4783 4865
4784 pRec->Cur_Count--; 4866 pRec->Cur_Count--;
4785 4867
4786 CUR.step_ins = FALSE; 4868 CUR.step_ins = FALSE;
4787 4869
4788 if ( pRec->Cur_Count > 0 ) 4870 if ( pRec->Cur_Count > 0 )
4789 { 4871 {
4790 CUR.callTop++; 4872 CUR.callTop++;
4791 CUR.IP = pRec->Cur_Restart; 4873 CUR.IP = pRec->Def->start;
4792 } 4874 }
4793 else 4875 else
4794 /* Loop through the current function */ 4876 /* Loop through the current function */
4795 INS_Goto_CodeRange( pRec->Caller_Range, 4877 INS_Goto_CodeRange( pRec->Caller_Range,
4796 pRec->Caller_IP ); 4878 pRec->Caller_IP );
4797 4879
4798 /* Exit the current call frame. */ 4880 /* Exit the current call frame. */
4799 4881
4800 /* NOTE: If the last instruction of a program is a */ 4882 /* NOTE: If the last instruction of a program is a */
4801 /* CALL or LOOPCALL, the return address is */ 4883 /* CALL or LOOPCALL, the return address is */
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
4871 { 4953 {
4872 CUR.error = FT_THROW( Stack_Overflow ); 4954 CUR.error = FT_THROW( Stack_Overflow );
4873 return; 4955 return;
4874 } 4956 }
4875 4957
4876 pCrec = CUR.callStack + CUR.callTop; 4958 pCrec = CUR.callStack + CUR.callTop;
4877 4959
4878 pCrec->Caller_Range = CUR.curRange; 4960 pCrec->Caller_Range = CUR.curRange;
4879 pCrec->Caller_IP = CUR.IP + 1; 4961 pCrec->Caller_IP = CUR.IP + 1;
4880 pCrec->Cur_Count = 1; 4962 pCrec->Cur_Count = 1;
4881 pCrec->Cur_Restart = def->start; 4963 pCrec->Def = def;
4882 pCrec->Cur_End = def->end;
4883 4964
4884 CUR.callTop++; 4965 CUR.callTop++;
4885 4966
4886 INS_Goto_CodeRange( def->range, 4967 INS_Goto_CodeRange( def->range,
4887 def->start ); 4968 def->start );
4888 4969
4889 CUR.step_ins = FALSE; 4970 CUR.step_ins = FALSE;
4890 4971
4891 return; 4972 return;
4892 4973
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
4960 return; 5041 return;
4961 } 5042 }
4962 5043
4963 if ( args[0] > 0 ) 5044 if ( args[0] > 0 )
4964 { 5045 {
4965 pCrec = CUR.callStack + CUR.callTop; 5046 pCrec = CUR.callStack + CUR.callTop;
4966 5047
4967 pCrec->Caller_Range = CUR.curRange; 5048 pCrec->Caller_Range = CUR.curRange;
4968 pCrec->Caller_IP = CUR.IP + 1; 5049 pCrec->Caller_IP = CUR.IP + 1;
4969 pCrec->Cur_Count = (FT_Int)args[0]; 5050 pCrec->Cur_Count = (FT_Int)args[0];
4970 pCrec->Cur_Restart = def->start; 5051 pCrec->Def = def;
4971 pCrec->Cur_End = def->end;
4972 5052
4973 CUR.callTop++; 5053 CUR.callTop++;
4974 5054
4975 INS_Goto_CodeRange( def->range, def->start ); 5055 INS_Goto_CodeRange( def->range, def->start );
4976 5056
4977 CUR.step_ins = FALSE; 5057 CUR.step_ins = FALSE;
4978 } 5058 }
4979 5059
4980 return; 5060 return;
4981 5061
(...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after
5822 else 5902 else
5823 { 5903 {
5824 CUR.zp2.cur[point].y += dy; 5904 CUR.zp2.cur[point].y += dy;
5825 if ( touch ) 5905 if ( touch )
5826 CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; 5906 CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y;
5827 } 5907 }
5828 return; 5908 return;
5829 } 5909 }
5830 #endif 5910 #endif
5831 5911
5832 if (CUR.zp2.cur == NULL) return; /* Security fix: Google Chris6 ufuzz109 .pdf page #1 */
5833 if ( CUR.GS.freeVector.x != 0 ) 5912 if ( CUR.GS.freeVector.x != 0 )
5834 { 5913 {
5835 CUR.zp2.cur[point].x += dx; 5914 CUR.zp2.cur[point].x += dx;
5836 if ( touch ) 5915 if ( touch )
5837 CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; 5916 CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X;
5838 } 5917 }
5839 5918
5840 if ( CUR.GS.freeVector.y != 0 ) 5919 if ( CUR.GS.freeVector.y != 0 )
5841 { 5920 {
5842 CUR.zp2.cur[point].y += dy; 5921 CUR.zp2.cur[point].y += dy;
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
5988 6067
5989 if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) 6068 if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
5990 return; 6069 return;
5991 6070
5992 /* XXX: UNDOCUMENTED! SHZ doesn't move the phantom points. */ 6071 /* XXX: UNDOCUMENTED! SHZ doesn't move the phantom points. */
5993 /* Twilight zone has no real contours, so use `n_points'. */ 6072 /* Twilight zone has no real contours, so use `n_points'. */
5994 /* Normal zone's `n_points' includes phantoms, so must */ 6073 /* Normal zone's `n_points' includes phantoms, so must */
5995 /* use end of last contour. */ 6074 /* use end of last contour. */
5996 if ( CUR.GS.gep2 == 0 ) 6075 if ( CUR.GS.gep2 == 0 )
5997 limit = (FT_UShort)CUR.zp2.n_points; 6076 limit = (FT_UShort)CUR.zp2.n_points;
5998 else if ( CUR.GS.gep2 == 1 && CUR.zp2.n_contours > 0 ) { 6077 else if ( CUR.GS.gep2 == 1 && CUR.zp2.n_contours > 0 )
5999 limit = (FT_UShort)( CUR.zp2.contours[CUR.zp2.n_contours - 1] + 1 ); 6078 limit = (FT_UShort)( CUR.zp2.contours[CUR.zp2.n_contours - 1] + 1 );
6000 if (limit >= CUR.zp2.n_points) /* XYQ 2010-10-01: secur ity fix: validate last point index */
6001 limit = CUR.zp2.n_points - 1;
6002 }
6003 else 6079 else
6004 limit = 0; 6080 limit = 0;
6005 6081
6006 /* XXX: UNDOCUMENTED! SHZ doesn't touch the points */ 6082 /* XXX: UNDOCUMENTED! SHZ doesn't touch the points */
6007 for ( i = 0; i < limit; i++ ) 6083 for ( i = 0; i < limit; i++ )
6008 { 6084 {
6009 if ( zp.cur != CUR.zp2.cur || refp != i ) 6085 if ( zp.cur != CUR.zp2.cur || refp != i )
6010 MOVE_Zp2_Point( i, dx, dy, FALSE ); 6086 MOVE_Zp2_Point( i, dx, dy, FALSE );
6011 } 6087 }
6012 } 6088 }
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after
6559 6635
6560 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 6636 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
6561 if ( SUBPIXEL_HINTING && 6637 if ( SUBPIXEL_HINTING &&
6562 CUR.ignore_x_mode && 6638 CUR.ignore_x_mode &&
6563 CUR.GS.freeVector.x != 0 && 6639 CUR.GS.freeVector.x != 0 &&
6564 !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) 6640 !( CUR.sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
6565 control_value_cutin = minimum_distance = 0; 6641 control_value_cutin = minimum_distance = 0;
6566 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 6642 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
6567 6643
6568 /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */ 6644 /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */
6569 » /* Security fix: Google 07_oobread4.pdf page #1, cvtEntry > CUR.cvtSize + 1 will cause array index oob. */ 6645
6570 if ( BOUNDS( point, CUR.zp1.n_points ) || 6646 if ( BOUNDS( point, CUR.zp1.n_points ) ||
6571 BOUNDS( cvtEntry, CUR.cvtSize + 1 ) || 6647 BOUNDSL( cvtEntry, CUR.cvtSize + 1 ) ||
6572 BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) 6648 BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
6573 { 6649 {
6574 if ( CUR.pedantic_hinting ) 6650 if ( CUR.pedantic_hinting )
6575 CUR.error = FT_THROW( Invalid_Reference ); 6651 CUR.error = FT_THROW( Invalid_Reference );
6576 goto Fail; 6652 goto Fail;
6577 } 6653 }
6578 6654
6579 if ( !cvtEntry ) 6655 if ( !cvtEntry )
6580 cvt_dist = 0; 6656 cvt_dist = 0;
6581 else 6657 else
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after
7054 7130
7055 7131
7056 vec.x = FT_MulFix( CUR.zp2.orus[point].x - orus_base->x, 7132 vec.x = FT_MulFix( CUR.zp2.orus[point].x - orus_base->x,
7057 CUR.metrics.x_scale ); 7133 CUR.metrics.x_scale );
7058 vec.y = FT_MulFix( CUR.zp2.orus[point].y - orus_base->y, 7134 vec.y = FT_MulFix( CUR.zp2.orus[point].y - orus_base->y,
7059 CUR.metrics.y_scale ); 7135 CUR.metrics.y_scale );
7060 7136
7061 org_dist = CUR_fast_dualproj( &vec ); 7137 org_dist = CUR_fast_dualproj( &vec );
7062 } 7138 }
7063 7139
7064 cur_dist = CUR_Func_project ( &CUR.zp2.cur[point], cur_base ); 7140 cur_dist = CUR_Func_project( &CUR.zp2.cur[point], cur_base );
7065 7141
7066 if ( org_dist ) 7142 if ( org_dist )
7067 { 7143 {
7068 if ( old_range ) 7144 if ( old_range )
7069 new_dist = FT_MulDiv( org_dist, cur_range, old_range ); 7145 new_dist = FT_MulDiv( org_dist, cur_range, old_range );
7070 else 7146 else
7071 { 7147 {
7072 /* This is the same as what MS does for the invalid case: */ 7148 /* This is the same as what MS does for the invalid case: */
7073 /* */ 7149 /* */
7074 /* delta = (Original_Pt - Original_RP1) - */ 7150 /* delta = (Original_Pt - Original_RP1) - */
7075 /* (Current_Pt - Current_RP1) */ 7151 /* (Current_Pt - Current_RP1) ; */
7076 /* */ 7152 /* */
7077 /* In FreeType speak: */ 7153 /* In FreeType speak: */
7078 /* */ 7154 /* */
7079 /* new_dist = cur_dist - */ 7155 /* delta = org_dist - cur_dist . */
7080 /* org_dist - cur_dist; */ 7156 /* */
7157 /* We move `point' by `new_dist - cur_dist' after leaving */
7158 /* this block, thus we have */
7159 /* */
7160 /* new_dist - cur_dist = delta , */
7161 /* new_dist - cur_dist = org_dist - cur_dist , */
7162 /* new_dist = org_dist . */
7081 7163
7082 new_dist = -org_dist; 7164 new_dist = org_dist;
7083 } 7165 }
7084 } 7166 }
7085 else 7167 else
7086 new_dist = 0; 7168 new_dist = 0;
7087 7169
7088 CUR_Func_move( &CUR.zp2, (FT_UShort)point, new_dist - cur_dist ); 7170 CUR_Func_move( &CUR.zp2, (FT_UShort)point, new_dist - cur_dist );
7089 } 7171 }
7090 7172
7091 Fail: 7173 Fail:
7092 CUR.GS.loop = 1; 7174 CUR.GS.loop = 1;
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
7369 7451
7370 /*************************************************************************/ 7452 /*************************************************************************/
7371 /* */ 7453 /* */
7372 /* DELTAPn[]: DELTA exceptions P1, P2, P3 */ 7454 /* DELTAPn[]: DELTA exceptions P1, P2, P3 */
7373 /* Opcode range: 0x5D,0x71,0x72 */ 7455 /* Opcode range: 0x5D,0x71,0x72 */
7374 /* Stack: uint32 (2 * uint32)... --> */ 7456 /* Stack: uint32 (2 * uint32)... --> */
7375 /* */ 7457 /* */
7376 static void 7458 static void
7377 Ins_DELTAP( INS_ARG ) 7459 Ins_DELTAP( INS_ARG )
7378 { 7460 {
7379 FT_ULong k, nump; 7461 FT_ULong nump, k;
7380 FT_UShort A; 7462 FT_UShort A;
7381 FT_ULong C; 7463 FT_ULong C, P;
7382 FT_Long B; 7464 FT_Long B;
7383 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 7465 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
7384 FT_UShort B1, B2; 7466 FT_UShort B1, B2;
7385 7467
7386 7468
7387 if ( SUBPIXEL_HINTING && 7469 if ( SUBPIXEL_HINTING &&
7388 CUR.ignore_x_mode && 7470 CUR.ignore_x_mode &&
7389 CUR.iup_called && 7471 CUR.iup_called &&
7390 ( CUR.sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) ) 7472 ( CUR.sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) )
7391 goto Fail; 7473 goto Fail;
(...skipping 13 matching lines...) Expand all
7405 CUR.error = FT_THROW( Too_Few_Arguments ); 7487 CUR.error = FT_THROW( Too_Few_Arguments );
7406 n = CUR.args; 7488 n = CUR.args;
7407 } 7489 }
7408 7490
7409 CUR.args -= n; 7491 CUR.args -= n;
7410 CUR.new_top = CUR.args; 7492 CUR.new_top = CUR.args;
7411 return; 7493 return;
7412 } 7494 }
7413 #endif 7495 #endif
7414 7496
7497 P = (FT_ULong)CUR_Func_cur_ppem();
7415 nump = (FT_ULong)args[0]; /* some points theoretically may occur more 7498 nump = (FT_ULong)args[0]; /* some points theoretically may occur more
7416 than once, thus UShort isn't enough */ 7499 than once, thus UShort isn't enough */
7417 7500
7418 for ( k = 1; k <= nump; k++ ) 7501 for ( k = 1; k <= nump; k++ )
7419 { 7502 {
7420 if ( CUR.args < 2 ) 7503 if ( CUR.args < 2 )
7421 { 7504 {
7422 if ( CUR.pedantic_hinting ) 7505 if ( CUR.pedantic_hinting )
7423 CUR.error = FT_THROW( Too_Few_Arguments ); 7506 CUR.error = FT_THROW( Too_Few_Arguments );
7424 CUR.args = 0; 7507 CUR.args = 0;
(...skipping 24 matching lines...) Expand all
7449 C += 16; 7532 C += 16;
7450 break; 7533 break;
7451 7534
7452 case 0x72: 7535 case 0x72:
7453 C += 32; 7536 C += 32;
7454 break; 7537 break;
7455 } 7538 }
7456 7539
7457 C += CUR.GS.delta_base; 7540 C += CUR.GS.delta_base;
7458 7541
7459 if ( CURRENT_Ppem() == (FT_Long)C ) 7542 if ( P == C )
7460 { 7543 {
7461 B = ( (FT_ULong)B & 0xF ) - 8; 7544 B = ( (FT_ULong)B & 0xF ) - 8;
7462 if ( B >= 0 ) 7545 if ( B >= 0 )
7463 B++; 7546 B++;
7464 B = B * 64 / ( 1L << CUR.GS.delta_shift ); 7547 B *= 1L << ( 6 - CUR.GS.delta_shift );
7465 7548
7466 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 7549 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
7467 7550
7468 if ( SUBPIXEL_HINTING ) 7551 if ( SUBPIXEL_HINTING )
7469 { 7552 {
7470 /* 7553 /*
7471 * Allow delta move if 7554 * Allow delta move if
7472 * 7555 *
7473 * - not using ignore_x_mode rendering 7556 * - not using ignore_x_mode rendering,
7474 * - glyph is specifically set to allow it 7557 * - glyph is specifically set to allow it, or
7475 * - glyph is composite and freedom vector is not subpixel 7558 * - glyph is composite and freedom vector is not in subpixel
7476 * vector 7559 * direction.
7477 */ 7560 */
7478 if ( !CUR.ignore_x_mode || 7561 if ( !CUR.ignore_x_mode ||
7479 ( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) || 7562 ( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) ||
7480 ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) ) 7563 ( CUR.is_composite && CUR.GS.freeVector.y != 0 ) )
7481 CUR_Func_move( &CUR.zp0, A, B ); 7564 CUR_Func_move( &CUR.zp0, A, B );
7482 7565
7483 /* Otherwise apply subpixel hinting and */ 7566 /* Otherwise, apply subpixel hinting and compatibility mode */
7484 /* compatibility mode rules */ 7567 /* rules, always skipping deltas in subpixel direction. */
7485 else if ( CUR.ignore_x_mode ) 7568 else if ( CUR.ignore_x_mode && CUR.GS.freeVector.y != 0 )
7486 { 7569 {
7487 if ( CUR.GS.freeVector.y != 0 ) 7570 /* save the y value of the point now; compare after move */
7488 B1 = CUR.zp0.cur[A].y; 7571 B1 = (FT_UShort)CUR.zp0.cur[A].y;
7489 else
7490 B1 = CUR.zp0.cur[A].x;
7491 7572
7492 #if 0 7573 /* Standard subpixel hinting: Allow y move for y-touched */
7493 /* Standard Subpixel Hinting: Allow y move. */ 7574 /* points. This messes up DejaVu ... */
7494 /* This messes up dejavu and may not be needed... */ 7575 if ( !CUR.face->sph_compatibility_mode &&
7495 if ( !CUR.face->sph_compatibility_mode && 7576 ( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
7496 CUR.GS.freeVector.y != 0 )
7497 CUR_Func_move( &CUR.zp0, A, B ); 7577 CUR_Func_move( &CUR.zp0, A, B );
7498 else
7499 #endif /* 0 */
7500 7578
7501 /* Compatibility Mode: Allow x or y move if point touched in */ 7579 /* compatibility mode */
7502 /* Y direction. */ 7580 else if ( CUR.face->sph_compatibility_mode &&
7503 if ( CUR.face->sph_compatibility_mode && 7581 !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) )
7504 !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) )
7505 { 7582 {
7506 /* save the y value of the point now; compare after move */
7507 B1 = CUR.zp0.cur[A].y;
7508
7509 if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES ) 7583 if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
7510 B = FT_PIX_ROUND( B1 + B ) - B1; 7584 B = FT_PIX_ROUND( B1 + B ) - B1;
7511 7585
7512 /* Allow delta move if using sph_compatibility_mode, */ 7586 /* Allow delta move if using sph_compatibility_mode, */
7513 /* IUP has not been called, and point is touched on Y. */ 7587 /* IUP has not been called, and point is touched on Y. */
7514 if ( !CUR.iup_called && 7588 if ( !CUR.iup_called &&
7515 ( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) ) 7589 ( CUR.zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
7516 CUR_Func_move( &CUR.zp0, A, B ); 7590 CUR_Func_move( &CUR.zp0, A, B );
7517 } 7591 }
7518 7592
7519 B2 = CUR.zp0.cur[A].y; 7593 B2 = (FT_UShort)CUR.zp0.cur[A].y;
7520 7594
7521 /* Reverse this move if it results in a disallowed move */ 7595 /* Reverse this move if it results in a disallowed move */
7522 if ( CUR.GS.freeVector.y != 0 && 7596 if ( CUR.GS.freeVector.y != 0 &&
7523 ( ( CUR.face->sph_compatibility_mode && 7597 ( ( CUR.face->sph_compatibility_mode &&
7524 ( B1 & 63 ) == 0 && 7598 ( B1 & 63 ) == 0 &&
7525 ( B2 & 63 ) != 0 ) || 7599 ( B2 & 63 ) != 0 ) ||
7526 ( ( CUR.sph_tweak_flags & 7600 ( ( CUR.sph_tweak_flags &
7527 SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP ) && 7601 SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP ) &&
7528 ( B1 & 63 ) != 0 && 7602 ( B1 & 63 ) != 0 &&
7529 ( B2 & 63 ) != 0 ) ) ) 7603 ( B2 & 63 ) != 0 ) ) )
(...skipping 19 matching lines...) Expand all
7549 /*************************************************************************/ 7623 /*************************************************************************/
7550 /* */ 7624 /* */
7551 /* DELTACn[]: DELTA exceptions C1, C2, C3 */ 7625 /* DELTACn[]: DELTA exceptions C1, C2, C3 */
7552 /* Opcode range: 0x73,0x74,0x75 */ 7626 /* Opcode range: 0x73,0x74,0x75 */
7553 /* Stack: uint32 (2 * uint32)... --> */ 7627 /* Stack: uint32 (2 * uint32)... --> */
7554 /* */ 7628 /* */
7555 static void 7629 static void
7556 Ins_DELTAC( INS_ARG ) 7630 Ins_DELTAC( INS_ARG )
7557 { 7631 {
7558 FT_ULong nump, k; 7632 FT_ULong nump, k;
7559 FT_ULong A, C; 7633 FT_ULong A, C, P;
7560 FT_Long B; 7634 FT_Long B;
7561 7635
7562 7636
7563 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING 7637 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
7564 /* Delta hinting is covered by US Patent 5159668. */ 7638 /* Delta hinting is covered by US Patent 5159668. */
7565 if ( CUR.face->unpatented_hinting ) 7639 if ( CUR.face->unpatented_hinting )
7566 { 7640 {
7567 FT_Long n = args[0] * 2; 7641 FT_Long n = args[0] * 2;
7568 7642
7569 7643
7570 if ( CUR.args < n ) 7644 if ( CUR.args < n )
7571 { 7645 {
7572 if ( CUR.pedantic_hinting ) 7646 if ( CUR.pedantic_hinting )
7573 CUR.error = FT_THROW( Too_Few_Arguments ); 7647 CUR.error = FT_THROW( Too_Few_Arguments );
7574 n = CUR.args; 7648 n = CUR.args;
7575 } 7649 }
7576 7650
7577 CUR.args -= n; 7651 CUR.args -= n;
7578 CUR.new_top = CUR.args; 7652 CUR.new_top = CUR.args;
7579 return; 7653 return;
7580 } 7654 }
7581 #endif 7655 #endif
7582 7656
7657 P = (FT_ULong)CUR_Func_cur_ppem();
7583 nump = (FT_ULong)args[0]; 7658 nump = (FT_ULong)args[0];
7584 7659
7585 for ( k = 1; k <= nump; k++ ) 7660 for ( k = 1; k <= nump; k++ )
7586 { 7661 {
7587 if ( CUR.args < 2 ) 7662 if ( CUR.args < 2 )
7588 { 7663 {
7589 if ( CUR.pedantic_hinting ) 7664 if ( CUR.pedantic_hinting )
7590 CUR.error = FT_THROW( Too_Few_Arguments ); 7665 CUR.error = FT_THROW( Too_Few_Arguments );
7591 CUR.args = 0; 7666 CUR.args = 0;
7592 goto Fail; 7667 goto Fail;
(...skipping 25 matching lines...) Expand all
7618 C += 16; 7693 C += 16;
7619 break; 7694 break;
7620 7695
7621 case 0x75: 7696 case 0x75:
7622 C += 32; 7697 C += 32;
7623 break; 7698 break;
7624 } 7699 }
7625 7700
7626 C += CUR.GS.delta_base; 7701 C += CUR.GS.delta_base;
7627 7702
7628 if ( CURRENT_Ppem() == (FT_Long)C ) 7703 if ( P == C )
7629 { 7704 {
7630 B = ( (FT_ULong)B & 0xF ) - 8; 7705 B = ( (FT_ULong)B & 0xF ) - 8;
7631 if ( B >= 0 ) 7706 if ( B >= 0 )
7632 B++; 7707 B++;
7633 B = B * 64 / ( 1L << CUR.GS.delta_shift ); 7708 B *= 1L << ( 6 - CUR.GS.delta_shift );
7634 7709
7635 CUR_Func_move_cvt( A, B ); 7710 CUR_Func_move_cvt( A, B );
7636 } 7711 }
7637 } 7712 }
7638 } 7713 }
7639 7714
7640 Fail: 7715 Fail:
7641 CUR.new_top = CUR.args; 7716 CUR.new_top = CUR.args;
7642 } 7717 }
7643 7718
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
7705 /* */ 7780 /* */
7706 if ( ( args[0] & 32 ) != 0 && CUR.grayscale ) 7781 if ( ( args[0] & 32 ) != 0 && CUR.grayscale )
7707 K |= 1 << 12; 7782 K |= 1 << 12;
7708 7783
7709 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 7784 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
7710 7785
7711 if ( SUBPIXEL_HINTING && 7786 if ( SUBPIXEL_HINTING &&
7712 CUR.ignore_x_mode && 7787 CUR.ignore_x_mode &&
7713 CUR.rasterizer_version >= TT_INTERPRETER_VERSION_35 ) 7788 CUR.rasterizer_version >= TT_INTERPRETER_VERSION_35 )
7714 { 7789 {
7715 /********************************/
7716 /* HINTING FOR GRAYSCALE */
7717 /* Selector Bit: 5 */
7718 /* Return Bit(s): 12 */
7719 /* */
7720 if ( ( args[0] & 32 ) != 0 && CUR.grayscale_hinting )
7721 K |= 1 << 12;
7722 7790
7723 /********************************/ 7791 if ( CUR.rasterizer_version >= 37 )
7724 /* HINTING FOR SUBPIXEL */
7725 /* Selector Bit: 6 */
7726 /* Return Bit(s): 13 */
7727 /* */
7728 if ( ( args[0] & 64 ) != 0 &&
7729 CUR.subpixel_hinting &&
7730 CUR.rasterizer_version >= 37 )
7731 { 7792 {
7732 K |= 1 << 13; 7793 /********************************/
7733 7794 /* HINTING FOR SUBPIXEL */
7734 /* the stuff below is irrelevant if subpixel_hinting is not set */ 7795 /* Selector Bit: 6 */
7796 /* Return Bit(s): 13 */
7797 /* */
7798 if ( ( args[0] & 64 ) != 0 && CUR.subpixel )
7799 K |= 1 << 13;
7735 7800
7736 /********************************/ 7801 /********************************/
7737 /* COMPATIBLE WIDTHS ENABLED */ 7802 /* COMPATIBLE WIDTHS ENABLED */
7738 /* Selector Bit: 7 */ 7803 /* Selector Bit: 7 */
7739 /* Return Bit(s): 14 */ 7804 /* Return Bit(s): 14 */
7740 /* */ 7805 /* */
7741 /* Functionality still needs to be added */ 7806 /* Functionality still needs to be added */
7742 if ( ( args[0] & 128 ) != 0 && CUR.compatible_widths ) 7807 if ( ( args[0] & 128 ) != 0 && CUR.compatible_widths )
7743 K |= 1 << 14; 7808 K |= 1 << 14;
7744 7809
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
7800 { 7865 {
7801 CUR.error = FT_THROW( Stack_Overflow ); 7866 CUR.error = FT_THROW( Stack_Overflow );
7802 return; 7867 return;
7803 } 7868 }
7804 7869
7805 call = CUR.callStack + CUR.callTop++; 7870 call = CUR.callStack + CUR.callTop++;
7806 7871
7807 call->Caller_Range = CUR.curRange; 7872 call->Caller_Range = CUR.curRange;
7808 call->Caller_IP = CUR.IP + 1; 7873 call->Caller_IP = CUR.IP + 1;
7809 call->Cur_Count = 1; 7874 call->Cur_Count = 1;
7810 call->Cur_Restart = def->start; 7875 call->Def = def;
7811 call->Cur_End = def->end;
7812 7876
7813 INS_Goto_CodeRange( def->range, def->start ); 7877 INS_Goto_CodeRange( def->range, def->start );
7814 7878
7815 CUR.step_ins = FALSE; 7879 CUR.step_ins = FALSE;
7816 return; 7880 return;
7817 } 7881 }
7818 } 7882 }
7819 7883
7820 CUR.error = FT_THROW( Invalid_Opcode ); 7884 CUR.error = FT_THROW( Invalid_Opcode );
7821 } 7885 }
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
8155 0x7D, /* RDTG */ 8219 0x7D, /* RDTG */
8156 }, 8220 },
8157 }; 8221 };
8158 FT_UShort opcode_patterns = 1; 8222 FT_UShort opcode_patterns = 1;
8159 FT_UShort opcode_pointer[1] = { 0 }; 8223 FT_UShort opcode_pointer[1] = { 0 };
8160 FT_UShort opcode_size[1] = { 1 }; 8224 FT_UShort opcode_size[1] = { 1 };
8161 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 8225 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
8162 8226
8163 8227
8164 #ifdef TT_CONFIG_OPTION_STATIC_RASTER 8228 #ifdef TT_CONFIG_OPTION_STATIC_RASTER
8229 if ( !exc )
8230 return FT_THROW( Invalid_Argument );
8231
8165 cur = *exc; 8232 cur = *exc;
8166 #endif 8233 #endif
8167 8234
8168 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING 8235 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
8169 CUR.iup_called = FALSE; 8236 CUR.iup_called = FALSE;
8170 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ 8237 #endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
8171 8238
8172 /* set CVT functions */ 8239 /* set PPEM and CVT functions */
8173 CUR.tt_metrics.ratio = 0; 8240 CUR.tt_metrics.ratio = 0;
8174 if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem ) 8241 if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem )
8175 { 8242 {
8176 /* non-square pixels, use the stretched routines */ 8243 /* non-square pixels, use the stretched routines */
8244 CUR.func_cur_ppem = Current_Ppem_Stretched;
8177 CUR.func_read_cvt = Read_CVT_Stretched; 8245 CUR.func_read_cvt = Read_CVT_Stretched;
8178 CUR.func_write_cvt = Write_CVT_Stretched; 8246 CUR.func_write_cvt = Write_CVT_Stretched;
8179 CUR.func_move_cvt = Move_CVT_Stretched; 8247 CUR.func_move_cvt = Move_CVT_Stretched;
8180 } 8248 }
8181 else 8249 else
8182 { 8250 {
8183 /* square pixels, use normal routines */ 8251 /* square pixels, use normal routines */
8252 CUR.func_cur_ppem = Current_Ppem;
8184 CUR.func_read_cvt = Read_CVT; 8253 CUR.func_read_cvt = Read_CVT;
8185 CUR.func_write_cvt = Write_CVT; 8254 CUR.func_write_cvt = Write_CVT;
8186 CUR.func_move_cvt = Move_CVT; 8255 CUR.func_move_cvt = Move_CVT;
8187 } 8256 }
8188 8257
8189 COMPUTE_Funcs(); 8258 COMPUTE_Funcs();
8190 COMPUTE_Round( (FT_Byte)exc->GS.round_state ); 8259 COMPUTE_Round( (FT_Byte)exc->GS.round_state );
8191 8260
8192 do 8261 do
8193 { 8262 {
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after
8857 { 8926 {
8858 CUR.error = FT_THROW( Invalid_Reference ); 8927 CUR.error = FT_THROW( Invalid_Reference );
8859 goto LErrorLabel_; 8928 goto LErrorLabel_;
8860 } 8929 }
8861 8930
8862 callrec = &CUR.callStack[CUR.callTop]; 8931 callrec = &CUR.callStack[CUR.callTop];
8863 8932
8864 callrec->Caller_Range = CUR.curRange; 8933 callrec->Caller_Range = CUR.curRange;
8865 callrec->Caller_IP = CUR.IP + 1; 8934 callrec->Caller_IP = CUR.IP + 1;
8866 callrec->Cur_Count = 1; 8935 callrec->Cur_Count = 1;
8867 callrec->Cur_Restart = def->start; 8936 callrec->Def = def;
8868 callrec->Cur_End = def->end;
8869 8937
8870 if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE ) 8938 if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE )
8871 goto LErrorLabel_; 8939 goto LErrorLabel_;
8872 8940
8873 goto LSuiteLabel_; 8941 goto LSuiteLabel_;
8874 } 8942 }
8875 } 8943 }
8876 } 8944 }
8877 8945
8878 CUR.error = FT_THROW( Invalid_Opcode ); 8946 CUR.error = FT_THROW( Invalid_Opcode );
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
8929 8997
8930 LErrorLabel_: 8998 LErrorLabel_:
8931 8999
8932 #ifdef TT_CONFIG_OPTION_STATIC_RASTER 9000 #ifdef TT_CONFIG_OPTION_STATIC_RASTER
8933 *exc = cur; 9001 *exc = cur;
8934 #endif 9002 #endif
8935 9003
8936 /* If any errors have occurred, function tables may be broken. */ 9004 /* If any errors have occurred, function tables may be broken. */
8937 /* Force a re-execution of `prep' and `fpgm' tables if no */ 9005 /* Force a re-execution of `prep' and `fpgm' tables if no */
8938 /* bytecode debugger is run. */ 9006 /* bytecode debugger is run. */
8939 if ( CUR.error && !CUR.instruction_trap ) 9007 if ( CUR.error
9008 && !CUR.instruction_trap
9009 && CUR.curRange == tt_coderange_glyph )
8940 { 9010 {
8941 FT_TRACE1(( " The interpreter returned error 0x%x\n", CUR.error )); 9011 FT_TRACE1(( " The interpreter returned error 0x%x\n", CUR.error ));
8942 exc->size->cvt_ready = FALSE; 9012 exc->size->bytecode_ready = -1;
9013 exc->size->cvt_ready = -1;
8943 } 9014 }
8944 9015
8945 return CUR.error; 9016 return CUR.error;
8946 } 9017 }
8947 9018
8948 9019
8949 #endif /* TT_USE_BYTECODE_INTERPRETER */ 9020 #endif /* TT_USE_BYTECODE_INTERPRETER */
8950 9021
8951 9022
8952 /* END */ 9023 /* END */
OLDNEW
« no previous file with comments | « third_party/freetype/src/truetype/ttinterp.h ('k') | third_party/freetype/src/truetype/ttobjs.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698