]> git.eshelyaron.com Git - emacs.git/commitdiff
Correct values of INSTCTRL flags tested
authorPo Lu <luangruo@yahoo.com>
Mon, 22 Jan 2024 07:29:18 +0000 (15:29 +0800)
committerEshel Yaron <me@eshelyaron.com>
Mon, 22 Jan 2024 16:55:06 +0000 (17:55 +0100)
* 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.

(cherry picked from commit 05495bfa6c39816e210bf655c0cbd44ba6dfcc7c)

src/sfnt.c

index a70994fbe6778c78a855fa5eadf9f5a1bd6ff4a2..7b4c5544dc10988465ba46b8621ac7520eb33b27 100644 (file)
@@ -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
     {