aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2024-01-22 15:29:18 +0800
committerPo Lu2024-01-22 16:02:05 +0800
commit05495bfa6c39816e210bf655c0cbd44ba6dfcc7c (patch)
treec63538976c84bdce7867970132730daa81c3ecf2 /src
parent088afa7e2f08f4eb4e39aae5db4faa33857bf544 (diff)
downloademacs-05495bfa6c39816e210bf655c0cbd44ba6dfcc7c.tar.gz
emacs-05495bfa6c39816e210bf655c0cbd44ba6dfcc7c.zip
Correct values of INSTCTRL flags tested
* src/sfnt.c (sfnt_mul_f26dot6_round): New function. (sfnt_mul_f26dot6_fixed): Replace by call to sfnt_mul_fixed_round. (MUL): Round result, as the Apple and MS scalers do. (sfnt_interpret_control_value_program): The instruction control flag which reverts CVT modifications is 2, not 4.
Diffstat (limited to 'src')
-rw-r--r--src/sfnt.c82
1 files changed, 36 insertions, 46 deletions
diff --git a/src/sfnt.c b/src/sfnt.c
index a70994fbe67..7b4c5544dc1 100644
--- a/src/sfnt.c
+++ b/src/sfnt.c
@@ -6490,19 +6490,21 @@ sfnt_mul_f26dot6 (sfnt_f26dot6 a, sfnt_f26dot6 b)
6490#endif 6490#endif
6491} 6491}
6492 6492
6493/* Multiply the specified 2.14 number with another signed 32 bit 6493/* Multiply the specified two 26.6 fixed point numbers A and B, with
6494 number. Return the result as a signed 32 bit number. */ 6494 rounding. Return the result, or an undefined value upon
6495 overflow. */
6495 6496
6496static int32_t 6497static sfnt_f26dot6
6497sfnt_mul_f2dot14 (sfnt_f2dot14 a, int32_t b) 6498sfnt_mul_f26dot6_round (sfnt_f26dot6 a, sfnt_f26dot6 b)
6498{ 6499{
6499#ifdef INT64_MAX 6500#ifdef INT64_MAX
6500 int64_t product; 6501 int64_t product;
6501 6502
6502 product = (int64_t) a * (int64_t) b; 6503 product = (int64_t) a * (int64_t) b;
6503 6504
6504 return product / (int64_t) 16384; 6505 /* This can be done quickly with int64_t. */
6505#else 6506 return (product + 32) / (int64_t) 64;
6507#else /* !INT64_MAX */
6506 int sign; 6508 int sign;
6507 6509
6508 sign = 1; 6510 sign = 1;
@@ -6513,61 +6515,48 @@ sfnt_mul_f2dot14 (sfnt_f2dot14 a, int32_t b)
6513 if (b < 0) 6515 if (b < 0)
6514 sign = -sign; 6516 sign = -sign;
6515 6517
6516 return sfnt_multiply_divide (abs (a), abs (b), 6518 return sfnt_multiply_divide_round (abs (a), abs (b),
6517 16384) * sign; 6519 32, 64) * sign;
6518#endif 6520#endif /* INT64_MAX */
6519} 6521}
6520 6522
6521/* Multiply the specified 26.6 fixed point number X by the specified 6523/* Multiply the specified 2.14 number with another signed 32 bit
6522 16.16 fixed point number Y with symmetric rounding. 6524 number. Return the result as a signed 32 bit number. */
6523
6524 The 26.6 fixed point number must fit inside -32768 to 32767.ffff.
6525 Value is otherwise undefined. */
6526 6525
6527static sfnt_f26dot6 6526static int32_t
6528sfnt_mul_f26dot6_fixed (sfnt_f26dot6 x, sfnt_fixed y) 6527sfnt_mul_f2dot14 (sfnt_f2dot14 a, int32_t b)
6529{ 6528{
6530#ifdef INT64_MAX 6529#ifdef INT64_MAX
6531 uint64_t product; 6530 int64_t product;
6532 int sign;
6533
6534 sign = 1;
6535
6536 if (x < 0)
6537 {
6538 x = -x;
6539 sign = -sign;
6540 }
6541
6542 if (y < 0)
6543 {
6544 y = -y;
6545 sign = -sign;
6546 }
6547 6531
6548 product = (uint64_t) y * (uint64_t) x; 6532 product = (int64_t) a * (int64_t) b;
6549 6533
6550 /* This can be done quickly with int64_t. */ 6534 return product / (int64_t) 16384;
6551 return ((int64_t) (product + 32768)
6552 / (int64_t) 65536) * sign;
6553#else 6535#else
6554 struct sfnt_large_integer temp;
6555 int sign; 6536 int sign;
6556 6537
6557 sign = 1; 6538 sign = 1;
6558 6539
6559 if (x < 0) 6540 if (a < 0)
6560 sign = -sign; 6541 sign = -sign;
6561 6542
6562 if (y < 0) 6543 if (b < 0)
6563 sign = -sign; 6544 sign = -sign;
6564 6545
6565 sfnt_multiply_divide_1 (abs (x), abs (y), &temp); 6546 return sfnt_multiply_divide (abs (a), abs (b),
6566 sfnt_large_integer_add (&temp, 32768); 6547 16384) * sign;
6567 return sfnt_multiply_divide_2 (&temp, 65536) * sign;
6568#endif 6548#endif
6569} 6549}
6570 6550
6551/* Multiply the specified 26.6 fixed point number X by the specified
6552 16.16 fixed point number Y with rounding. */
6553
6554static sfnt_f26dot6
6555sfnt_mul_f26dot6_fixed (sfnt_f26dot6 x, sfnt_fixed y)
6556{
6557 return sfnt_mul_fixed (x, y);
6558}
6559
6571/* Return the floor of the specified 26.6 fixed point value X. */ 6560/* Return the floor of the specified 26.6 fixed point value X. */
6572 6561
6573static sfnt_f26dot6 6562static sfnt_f26dot6
@@ -7582,12 +7571,13 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
7582 7571
7583#define MUL() \ 7572#define MUL() \
7584 { \ 7573 { \
7585 sfnt_f26dot6 n2, n1; \ 7574 sfnt_f26dot6 n2, n1, r; \
7586 \ 7575 \
7587 n2 = POP (); \ 7576 n2 = POP (); \
7588 n1 = POP (); \ 7577 n1 = POP (); \
7589 \ 7578 \
7590 PUSH_UNCHECKED (sfnt_mul_f26dot6 (n2, n1)); \ 7579 r = sfnt_mul_f26dot6_round (n2, n1); \
7580 PUSH_UNCHECKED (r); \
7591 } 7581 }
7592 7582
7593#define ABS() \ 7583#define ABS() \
@@ -12357,10 +12347,10 @@ sfnt_interpret_control_value_program (struct sfnt_interpreter *interpreter,
12357 sfnt_interpret_run (interpreter, 12347 sfnt_interpret_run (interpreter,
12358 SFNT_RUN_CONTEXT_CONTROL_VALUE_PROGRAM); 12348 SFNT_RUN_CONTEXT_CONTROL_VALUE_PROGRAM);
12359 12349
12360 /* If instruct_control & 4, then changes to the graphics state made 12350 /* If instruct_control & 2, then changes to the graphics state made
12361 in this program should be reverted. */ 12351 in this program should be reverted. */
12362 12352
12363 if (interpreter->state.instruct_control & 4) 12353 if (interpreter->state.instruct_control & 2)
12364 sfnt_init_graphics_state (&interpreter->state); 12354 sfnt_init_graphics_state (&interpreter->state);
12365 else 12355 else
12366 { 12356 {