#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;
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
#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() \
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
{