emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 05495bfa6c3 1/2: Correct values of INSTCTRL flags tested


From: Po Lu
Subject: master 05495bfa6c3 1/2: Correct values of INSTCTRL flags tested
Date: Mon, 22 Jan 2024 03:02:18 -0500 (EST)

branch: master
commit 05495bfa6c39816e210bf655c0cbd44ba6dfcc7c
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    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.
---
 src/sfnt.c | 82 +++++++++++++++++++++++++++-----------------------------------
 1 file 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)
 #endif
 }
 
-/* Multiply the specified 2.14 number with another signed 32 bit
-   number.  Return the result as a signed 32 bit number.  */
+/* Multiply the specified two 26.6 fixed point numbers A and B, with
+   rounding.  Return the result, or an undefined value upon
+   overflow.  */
 
-static int32_t
-sfnt_mul_f2dot14 (sfnt_f2dot14 a, int32_t b)
+static sfnt_f26dot6
+sfnt_mul_f26dot6_round (sfnt_f26dot6 a, sfnt_f26dot6 b)
 {
 #ifdef INT64_MAX
   int64_t product;
 
   product = (int64_t) a * (int64_t) b;
 
-  return product / (int64_t) 16384;
-#else
+  /* This can be done quickly with int64_t.  */
+  return (product + 32) / (int64_t) 64;
+#else /* !INT64_MAX */
   int sign;
 
   sign = 1;
@@ -6513,61 +6515,48 @@ sfnt_mul_f2dot14 (sfnt_f2dot14 a, int32_t b)
   if (b < 0)
     sign = -sign;
 
-  return sfnt_multiply_divide (abs (a), abs (b),
-                              16384) * sign;
-#endif
+  return sfnt_multiply_divide_round (abs (a), abs (b),
+                                    32, 64) * sign;
+#endif /* INT64_MAX */
 }
 
-/* Multiply the specified 26.6 fixed point number X by the specified
-   16.16 fixed point number Y with symmetric rounding.
-
-   The 26.6 fixed point number must fit inside -32768 to 32767.ffff.
-   Value is otherwise undefined.  */
+/* Multiply the specified 2.14 number with another signed 32 bit
+   number.  Return the result as a signed 32 bit number.  */
 
-static sfnt_f26dot6
-sfnt_mul_f26dot6_fixed (sfnt_f26dot6 x, sfnt_fixed y)
+static int32_t
+sfnt_mul_f2dot14 (sfnt_f2dot14 a, int32_t b)
 {
 #ifdef INT64_MAX
-  uint64_t product;
-  int sign;
-
-  sign = 1;
-
-  if (x < 0)
-    {
-      x = -x;
-      sign = -sign;
-    }
-
-  if (y < 0)
-    {
-      y = -y;
-      sign = -sign;
-    }
+  int64_t product;
 
-  product = (uint64_t) y * (uint64_t) x;
+  product = (int64_t) a * (int64_t) b;
 
-  /* This can be done quickly with int64_t.  */
-  return ((int64_t) (product + 32768)
-         / (int64_t) 65536) * sign;
+  return product / (int64_t) 16384;
 #else
-  struct sfnt_large_integer temp;
   int sign;
 
   sign = 1;
 
-  if (x < 0)
+  if (a < 0)
     sign = -sign;
 
-  if (y < 0)
+  if (b < 0)
     sign = -sign;
 
-  sfnt_multiply_divide_1 (abs (x), abs (y), &temp);
-  sfnt_large_integer_add (&temp, 32768);
-  return sfnt_multiply_divide_2 (&temp, 65536) * sign;
+  return sfnt_multiply_divide (abs (a), abs (b),
+                              16384) * sign;
 #endif
 }
 
+/* Multiply the specified 26.6 fixed point number X by the specified
+   16.16 fixed point number Y with rounding.  */
+
+static sfnt_f26dot6
+sfnt_mul_f26dot6_fixed (sfnt_f26dot6 x, sfnt_fixed y)
+{
+  return sfnt_mul_fixed (x, y);
+}
+
 /* Return the floor of the specified 26.6 fixed point value X.  */
 
 static sfnt_f26dot6
@@ -7582,12 +7571,13 @@ sfnt_interpret_trap (struct sfnt_interpreter 
*interpreter,
 
 #define MUL()                                  \
   {                                            \
-    sfnt_f26dot6 n2, n1;                       \
+    sfnt_f26dot6 n2, n1, r;                    \
                                                \
     n2 = POP ();                               \
     n1 = POP ();                               \
                                                \
-    PUSH_UNCHECKED (sfnt_mul_f26dot6 (n2, n1));        \
+    r = sfnt_mul_f26dot6_round (n2, n1);       \
+    PUSH_UNCHECKED (r);                                \
   }
 
 #define ABS()                                  \
@@ -12357,10 +12347,10 @@ sfnt_interpret_control_value_program (struct 
sfnt_interpreter *interpreter,
   sfnt_interpret_run (interpreter,
                      SFNT_RUN_CONTEXT_CONTROL_VALUE_PROGRAM);
 
-  /* If instruct_control & 4, then changes to the graphics state made
+  /* If instruct_control & 2, then changes to the graphics state made
      in this program should be reverted.  */
 
-  if (interpreter->state.instruct_control & 4)
+  if (interpreter->state.instruct_control & 2)
     sfnt_init_graphics_state (&interpreter->state);
   else
     {



reply via email to

[Prev in Thread] Current Thread [Next in Thread]