summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2026-05-23 11:52:09 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2026-05-23 19:18:54 -0700
commit7e0d4fae01f2f1c7411297b1fb99ecdf82bfdea4 (patch)
tree8781bc96d8e0e92b92f8dcc78e549bb46125513e
parent2e91ed5f129a4c03f7345d15d61232bd15028a4e (diff)
Simplify sfnt.c by using long long
Even the earliest Android had plain ‘long long’, so use that instead of doing it by hand. * src/sfnt.c (struct sfnt_large_integer, sfnt_multiply_divide_1) (sfnt_multiply_divide_2, sfnt_large_integer_add) (sfnt_multiply_divide_round) [!INT64_MAX]: Remove. (sfnt_multiply_divide, sfnt_multiply_divide_rounded) (sfnt_mul_fixed, sfnt_mul_fixed_round, sfnt_div_fixed) (sfnt_div_f26dot6, sfnt_mul_f26dot6, sfnt_mul_f26dot6_round) (sfnt_mul_f2dot14, sfnt_dot_fix_14): Simplify by using long long.
-rw-r--r--src/sfnt.c353
1 files changed, 17 insertions, 336 deletions
diff --git a/src/sfnt.c b/src/sfnt.c
index e46ebc3a08b..225b172cb40 100644
--- a/src/sfnt.c
+++ b/src/sfnt.c
@@ -3647,161 +3647,23 @@ sfnt_build_append (int flags, sfnt_fixed x, sfnt_fixed y)
return outline;
}
-#ifndef INT64_MAX
-
-/* 64 bit integer type. */
-
-struct sfnt_large_integer
-{
- unsigned int high, low;
-};
-
-/* Calculate (A * B), placing the result in *VALUE. */
-
-static void
-sfnt_multiply_divide_1 (unsigned int a, unsigned int b,
- struct sfnt_large_integer *value)
-{
- unsigned int lo1, hi1, lo2, hi2, lo, hi, i1, i2;
-
- lo1 = a & 0x0000ffffu;
- hi1 = a >> 16;
- lo2 = b & 0x0000ffffu;
- hi2 = b >> 16;
-
- lo = lo1 * lo2;
- i1 = lo1 * hi2;
- i2 = lo2 * hi1;
- hi = hi1 * hi2;
-
- /* Check carry overflow of i1 + i2. */
- i1 += i2;
- hi += (unsigned int) (i1 < i2) << 16;
-
- hi += i1 >> 16;
- i1 = i1 << 16;
-
- /* Check carry overflow of i1 + lo. */
- lo += i1;
- hi += (lo < i1);
-
- value->low = lo;
- value->high = hi;
-}
-
-/* Calculate AB / C. Value is a 32 bit unsigned integer. */
-
-static unsigned int
-sfnt_multiply_divide_2 (struct sfnt_large_integer *ab,
- unsigned int c)
-{
- unsigned int hi, lo;
- int i;
- unsigned int r, q; /* Remainder and quotient. */
-
- hi = ab->high;
- lo = ab->low;
-
- i = stdc_leading_zeros (hi);
- r = (hi << i) | (lo >> (32 - i));
- lo <<= i;
- q = r / c;
- r -= q * c;
- i = 32 - i;
-
- do
- {
- q <<= 1;
- r = (r << 1) | (lo >> 31);
- lo <<= 1;
-
- if (r >= c)
- {
- r -= c;
- q |= 1;
- }
- }
- while (--i);
-
- return q;
-}
-
-/* Add the specified unsigned 32-bit N to the large integer
- INTEGER. */
-
-static void
-sfnt_large_integer_add (struct sfnt_large_integer *integer,
- uint32_t n)
-{
- struct sfnt_large_integer number;
-
- number.low = integer->low + n;
- number.high = integer->high + (number.low
- < integer->low);
-
- *integer = number;
-}
-
-#endif /* !INT64_MAX */
-
-/* Calculate (A * B) / C with no rounding and return the result, using
- a 64 bit integer if necessary. */
+/* Calculate (A * B) / C with no rounding and return the result. */
static unsigned int
sfnt_multiply_divide (unsigned int a, unsigned int b, unsigned int c)
{
-#ifndef INT64_MAX
- struct sfnt_large_integer temp;
-
- sfnt_multiply_divide_1 (a, b, &temp);
- return sfnt_multiply_divide_2 (&temp, c);
-#else /* INT64_MAX */
- uint64_t temp;
-
- temp = (uint64_t) a * (uint64_t) b;
- return temp / c;
-#endif /* !INT64_MAX */
+ return a * (unsigned long long int) {b} / c;
}
-/* Calculate (A * B) / C with rounding and return the result, using a
- 64 bit integer if necessary. */
+/* Calculate (A * B) / C with rounding and return the result. */
static unsigned int
sfnt_multiply_divide_rounded (unsigned int a, unsigned int b,
unsigned int c)
{
-#ifndef INT64_MAX
- struct sfnt_large_integer temp;
-
- sfnt_multiply_divide_1 (a, b, &temp);
- sfnt_large_integer_add (&temp, c / 2);
- return sfnt_multiply_divide_2 (&temp, c);
-#else /* INT64_MAX */
- uint64_t temp;
-
- temp = (uint64_t) a * (uint64_t) b + c / 2;
- return temp / c;
-#endif /* !INT64_MAX */
-}
-
-#ifndef INT64_MAX
-
-/* Calculate (A * B) / C, rounding the result with a threshold of N.
- Use a 64 bit temporary. */
-
-static unsigned int
-sfnt_multiply_divide_round (unsigned int a, unsigned int b,
- unsigned int n, unsigned int c)
-{
- struct sfnt_large_integer temp;
-
- sfnt_multiply_divide_1 (a, b, &temp);
- sfnt_large_integer_add (&temp, n);
- return sfnt_multiply_divide_2 (&temp, c);
+ return (a * (unsigned long long int) {b} + c / 2) / c;
}
-#endif /* !INT64_MAX */
-
/* The same as sfnt_multiply_divide_rounded, but handle signed values
instead. */
@@ -3831,27 +3693,7 @@ sfnt_multiply_divide_signed (int a, int b, int c)
static sfnt_fixed
sfnt_mul_fixed (sfnt_fixed x, sfnt_fixed y)
{
-#ifdef INT64_MAX
- int64_t product;
-
- product = (int64_t) x * (int64_t) y;
-
- /* This can be done quickly with int64_t. */
- return product / (int64_t) 65536;
-#else /* !INT64_MAX */
- int sign;
-
- sign = 1;
-
- if (x < 0)
- sign = -sign;
-
- if (y < 0)
- sign = -sign;
-
- return sfnt_multiply_divide (abs (x), abs (y),
- 65536) * sign;
-#endif /* INT64_MAX */
+ return x * (long long int) {y} / (1 << 16);
}
/* Multiply the two 16.16 fixed point numbers X and Y, with rounding
@@ -3860,28 +3702,8 @@ sfnt_mul_fixed (sfnt_fixed x, sfnt_fixed y)
static sfnt_fixed
sfnt_mul_fixed_round (sfnt_fixed x, sfnt_fixed y)
{
-#ifdef INT64_MAX
- int64_t product, round;
-
- product = (int64_t) x * (int64_t) y;
- round = product < 0 ? -32768 : 32768;
-
- /* This can be done quickly with int64_t. */
- return (product + round) / (int64_t) 65536;
-#else /* !INT64_MAX */
- int sign;
-
- sign = 1;
-
- if (x < 0)
- sign = -sign;
-
- if (y < 0)
- sign = -sign;
-
- return sfnt_multiply_divide_round (abs (x), abs (y),
- 32768, 65536) * sign;
-#endif /* INT64_MAX */
+ long long int product = x * (long long int) {y};
+ return (product + (product < 0 ? -(1 << 15) : 1 << 15)) / (1 << 16);
}
/* Set the pen size to the specified point and return. POINT will be
@@ -3924,29 +3746,7 @@ sfnt_line_to_and_build (struct sfnt_point point, void *dcontext)
static sfnt_fixed
sfnt_div_fixed (sfnt_fixed x, sfnt_fixed y)
{
-#ifdef INT64_MAX
- int64_t result;
-
- result = ((int64_t) x * 65536) / y;
-
- return result;
-#else
- int sign;
- unsigned int a, b;
-
- sign = 1;
-
- if (x < 0)
- sign = -sign;
-
- if (y < 0)
- sign = -sign;
-
- a = abs (x);
- b = abs (y);
-
- return sfnt_multiply_divide (a, 65536, b) * sign;
-#endif
+ return x * (1LL << 16) / y;
}
/* Return the ceiling value of the specified fixed point number X. */
@@ -6391,29 +6191,7 @@ sfnt_read_prep_table (int fd, struct sfnt_offset_subtable *subtable)
static sfnt_f26dot6
sfnt_div_f26dot6 (sfnt_f26dot6 x, sfnt_f26dot6 y)
{
-#ifdef INT64_MAX
- int64_t result;
-
- result = ((int64_t) x * 64) / y;
-
- return result;
-#else
- int sign;
- unsigned int a, b;
-
- sign = 1;
-
- if (x < 0)
- sign = -sign;
-
- if (y < 0)
- sign = -sign;
-
- a = abs (x);
- b = abs (y);
-
- return sfnt_multiply_divide (a, 64, b) * sign;
-#endif
+ return x * (1LL << 6) / y;
}
/* Multiply the specified two 26.6 fixed point numbers A and B.
@@ -6422,27 +6200,7 @@ sfnt_div_f26dot6 (sfnt_f26dot6 x, sfnt_f26dot6 y)
static sfnt_f26dot6
sfnt_mul_f26dot6 (sfnt_f26dot6 a, sfnt_f26dot6 b)
{
-#ifdef INT64_MAX
- int64_t product;
-
- product = (int64_t) a * (int64_t) b;
-
- /* This can be done quickly with int64_t. */
- return product / (int64_t) 64;
-#else
- int sign;
-
- sign = 1;
-
- if (a < 0)
- sign = -sign;
-
- if (b < 0)
- sign = -sign;
-
- return sfnt_multiply_divide (abs (a), abs (b),
- 64) * sign;
-#endif
+ return a * (long long int) {b} / (1 << 6);
}
/* Multiply the specified two 26.6 fixed point numbers A and B, with
@@ -6452,27 +6210,7 @@ sfnt_mul_f26dot6 (sfnt_f26dot6 a, sfnt_f26dot6 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;
-
- /* This can be done quickly with int64_t. */
- return (product + 32) / (int64_t) 64;
-#else /* !INT64_MAX */
- int sign;
-
- sign = 1;
-
- if (a < 0)
- sign = -sign;
-
- if (b < 0)
- sign = -sign;
-
- return sfnt_multiply_divide_round (abs (a), abs (b),
- 32, 64) * sign;
-#endif /* INT64_MAX */
+ return (a * (long long int) {b} + (1 << 5)) / (1 << 6);
}
/* Multiply the specified 2.14 number with another signed 32 bit
@@ -6481,26 +6219,7 @@ sfnt_mul_f26dot6_round (sfnt_f26dot6 a, sfnt_f26dot6 b)
static int32_t
sfnt_mul_f2dot14 (sfnt_f2dot14 a, int32_t b)
{
-#ifdef INT64_MAX
- int64_t product;
-
- product = (int64_t) a * (int64_t) b;
-
- return product / (int64_t) 16384;
-#else
- int sign;
-
- sign = 1;
-
- if (a < 0)
- sign = -sign;
-
- if (b < 0)
- sign = -sign;
-
- return sfnt_multiply_divide (abs (a), abs (b),
- 16384) * sign;
-#endif
+ return a * (long long int) {b} / (1 << 14);
}
/* Multiply the specified 26.6 fixed point number X by the specified
@@ -10596,46 +10315,9 @@ sfnt_project_onto_y_axis_vector (sfnt_f26dot6 vx, sfnt_f26dot6 vy,
static int32_t
sfnt_dot_fix_14 (int32_t ax, int32_t ay, int bx, int by)
{
-#ifndef INT64_MAX
- int32_t m, s, hi1, hi2, hi;
- uint32_t l, lo1, lo2, lo;
-
-
- /* Compute ax*bx as 64-bit value. */
- l = (uint32_t) ((ax & 0xffffu) * bx);
- m = (ax >> 16) * bx;
-
- lo1 = l + ((uint32_t) m << 16);
- hi1 = (m >> 16) + ((int32_t) l >> 31) + (lo1 < l);
-
- /* Compute ay*by as 64-bit value. */
- l = (uint32_t) ((ay & 0xffffu) * by);
- m = (ay >> 16) * by;
-
- lo2 = l + ((uint32_t) m << 16);
- hi2 = (m >> 16) + ((int32_t) l >> 31) + (lo2 < l);
-
- /* Add them. */
- lo = lo1 + lo2;
- hi = hi1 + hi2 + (lo < lo1);
-
- /* Divide the result by 2^14 with rounding. */
- s = hi >> 31;
- l = lo + (uint32_t) s;
- hi += s + (l < lo);
- lo = l;
-
- l = lo + 0x2000u;
- hi += (l < lo);
-
- return (int32_t) (((uint32_t) hi << 18) | (l >> 14));
-#else
- int64_t xx, yy;
- int64_t temp;
-
- xx = (int64_t) ax * bx;
- yy = (int64_t) ay * by;
-
+ long long int
+ xx = ax * (long long int) {bx},
+ yy = ay * (long long int) {by};
xx += yy;
yy = xx >> 63;
xx += 0x2000 + yy;
@@ -10643,10 +10325,9 @@ sfnt_dot_fix_14 (int32_t ax, int32_t ay, int bx, int by)
/* TrueType fonts rely on "division" here truncating towards
negative infinity, so compute the arithmetic right shift in place
of division. */
- temp = -(xx < 0);
+ long long int temp = -(xx < 0);
temp = (temp ^ xx) >> 14 ^ temp;
- return (int32_t) (temp);
-#endif
+ return temp;
}
/* Project the specified vector VX and VY onto the unit vector that is