aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2023-12-19 16:42:38 +0800
committerPo Lu2023-12-19 16:42:38 +0800
commit0a57e1cd2c97db3a990f88043dc4a53619390228 (patch)
tree4ea79d103cfb19e2de9748f3c50c2fc8e8a58bb9 /src
parentd0e3dfa764cdb5c15c2a525b455df495097a86bb (diff)
downloademacs-0a57e1cd2c97db3a990f88043dc4a53619390228.tar.gz
emacs-0a57e1cd2c97db3a990f88043dc4a53619390228.zip
Improve efficiency of operations involving font interpreter scale
* src/sfnt.c (sfnt_mul_f26dot6_fixed): Correct rounding constant. (sfnt_make_interpreter, SSW, WCVTF, sfnt_compute_phantom_points) (sfnt_interpret_simple_glyph, sfnt_interpret_compound_glyph_1) (sfnt_vary_interpreter, sfnt_check_ssw): Account for the fractional bits in a f26dot6 when computing the interpreter scale factor.
Diffstat (limited to 'src')
-rw-r--r--src/sfnt.c41
1 files changed, 21 insertions, 20 deletions
diff --git a/src/sfnt.c b/src/sfnt.c
index c33f21215a6..eb3add7390e 100644
--- a/src/sfnt.c
+++ b/src/sfnt.c
@@ -6456,7 +6456,8 @@ sfnt_mul_f26dot6_fixed (sfnt_f26dot6 x, sfnt_fixed y)
6456 product = (uint64_t) y * (uint64_t) x; 6456 product = (uint64_t) y * (uint64_t) x;
6457 6457
6458 /* This can be done quickly with int64_t. */ 6458 /* This can be done quickly with int64_t. */
6459 return ((int64_t) (product + 32676) / (int64_t) 65536) * sign; 6459 return ((int64_t) (product + 32768)
6460 / (int64_t) 65536) * sign;
6460#else 6461#else
6461 struct sfnt_large_integer temp; 6462 struct sfnt_large_integer temp;
6462 int sign; 6463 int sign;
@@ -6685,7 +6686,7 @@ sfnt_make_interpreter (struct sfnt_maxp_table *maxp,
6685 /* Now compute the scale. Then, scale up the control value table 6686 /* Now compute the scale. Then, scale up the control value table
6686 values. */ 6687 values. */
6687 interpreter->scale 6688 interpreter->scale
6688 = sfnt_div_fixed (pixel_size, head->units_per_em); 6689 = sfnt_div_fixed (pixel_size * 64, head->units_per_em);
6689 6690
6690 /* Set the PPEM. */ 6691 /* Set the PPEM. */
6691 interpreter->ppem = pixel_size; 6692 interpreter->ppem = pixel_size;
@@ -6701,7 +6702,7 @@ sfnt_make_interpreter (struct sfnt_maxp_table *maxp,
6701 /* Load the control value table. */ 6702 /* Load the control value table. */
6702 for (i = 0; i < interpreter->cvt_size; ++i) 6703 for (i = 0; i < interpreter->cvt_size; ++i)
6703 interpreter->cvt[i] 6704 interpreter->cvt[i]
6704 = sfnt_mul_f26dot6_fixed (cvt->values[i] * 64, 6705 = sfnt_mul_f26dot6_fixed (cvt->values[i],
6705 interpreter->scale); 6706 interpreter->scale);
6706 6707
6707 /* Fill in the default values for phase, period and threshold. */ 6708 /* Fill in the default values for phase, period and threshold. */
@@ -7016,8 +7017,8 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
7016 single_width = POP (); \ 7017 single_width = POP (); \
7017 \ 7018 \
7018 interpreter->state.single_width_value \ 7019 interpreter->state.single_width_value \
7019 = (interpreter->scale * single_width \ 7020 = sfnt_mul_fixed (single_width, \
7020 / 1024); \ 7021 interpreter->scale); \
7021 } 7022 }
7022 7023
7023#define DUP() \ 7024#define DUP() \
@@ -7545,8 +7546,8 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
7545 TRAP ("WCVTF out of bounds"); \ 7546 TRAP ("WCVTF out of bounds"); \
7546 \ 7547 \
7547 interpreter->cvt[location] \ 7548 interpreter->cvt[location] \
7548 = (interpreter->scale * value \ 7549 = sfnt_mul_fixed (value, \
7549 / 1024); \ 7550 interpreter->scale); \
7550 } 7551 }
7551 7552
7552#define JROT() \ 7553#define JROT() \
@@ -12258,8 +12259,8 @@ sfnt_compute_phantom_points (struct sfnt_glyph *glyph,
12258 f2 += glyph->advance_distortion; 12259 f2 += glyph->advance_distortion;
12259 12260
12260 /* Next, scale both up. */ 12261 /* Next, scale both up. */
12261 *s1 = sfnt_mul_f26dot6_fixed (f1 * 64, scale); 12262 *s1 = sfnt_mul_f26dot6_fixed (f1, scale);
12262 *s2 = sfnt_mul_f26dot6_fixed (f2 * 64, scale); 12263 *s2 = sfnt_mul_f26dot6_fixed (f2, scale);
12263 12264
12264 /* While not expressly provided in the manual, the phantom points 12265 /* While not expressly provided in the manual, the phantom points
12265 (at times termed the advance and origin points) represent pixel 12266 (at times termed the advance and origin points) represent pixel
@@ -12343,7 +12344,7 @@ sfnt_interpret_simple_glyph (struct sfnt_glyph *glyph,
12343 tem = glyph->simple->x_coordinates[i]; 12344 tem = glyph->simple->x_coordinates[i];
12344 12345
12345 /* Scale that fword. */ 12346 /* Scale that fword. */
12346 tem = sfnt_mul_f26dot6_fixed (tem * 64, interpreter->scale); 12347 tem = sfnt_mul_f26dot6_fixed (tem, interpreter->scale);
12347 12348
12348 /* Set x_points and x_current. */ 12349 /* Set x_points and x_current. */
12349 zone->x_points[i] = tem; 12350 zone->x_points[i] = tem;
@@ -12371,7 +12372,7 @@ sfnt_interpret_simple_glyph (struct sfnt_glyph *glyph,
12371 12372
12372 /* Scale that fword. Make sure not to round Y, as this could 12373 /* Scale that fword. Make sure not to round Y, as this could
12373 lead to Y spilling over to the next line. */ 12374 lead to Y spilling over to the next line. */
12374 tem = sfnt_mul_fixed (tem * 64, interpreter->scale); 12375 tem = sfnt_mul_f26dot6_fixed (tem, interpreter->scale);
12375 12376
12376 /* Set y_points and y_current. */ 12377 /* Set y_points and y_current. */
12377 zone->y_points[i] = tem; 12378 zone->y_points[i] = tem;
@@ -12824,14 +12825,14 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph *glyph,
12824 if (!(component->flags & 01)) /* ARG_1_AND_2_ARE_WORDS */ 12825 if (!(component->flags & 01)) /* ARG_1_AND_2_ARE_WORDS */
12825 { 12826 {
12826 /* X and Y are signed bytes. */ 12827 /* X and Y are signed bytes. */
12827 x = component->argument1.b * 64; 12828 x = component->argument1.b;
12828 y = component->argument2.b * 64; 12829 y = component->argument2.b;
12829 } 12830 }
12830 else 12831 else
12831 { 12832 {
12832 /* X and Y are signed words. */ 12833 /* X and Y are signed words. */
12833 x = component->argument1.d * 64; 12834 x = component->argument1.d;
12834 y = component->argument2.d * 64; 12835 y = component->argument2.d;
12835 } 12836 }
12836 12837
12837 /* Now convert X and Y into device coordinates. */ 12838 /* Now convert X and Y into device coordinates. */
@@ -16335,7 +16336,7 @@ sfnt_vary_interpreter (struct sfnt_interpreter *interpreter,
16335 16336
16336 /* Multiply the delta by the interpreter scale factor and 16337 /* Multiply the delta by the interpreter scale factor and
16337 then the tuple scale factor. */ 16338 then the tuple scale factor. */
16338 delta = sfnt_mul_f26dot6_fixed (variation->deltas[j] * 64, 16339 delta = sfnt_mul_f26dot6_fixed (variation->deltas[j],
16339 interpreter->scale); 16340 interpreter->scale);
16340 delta = sfnt_mul_fixed_round (delta, scale); 16341 delta = sfnt_mul_fixed_round (delta, scale);
16341 16342
@@ -17352,13 +17353,13 @@ sfnt_check_ssw (struct sfnt_interpreter *interpreter,
17352 } 17353 }
17353 17354
17354 if (interpreter->state.single_width_value 17355 if (interpreter->state.single_width_value
17355 != sfnt_mul_f26dot6_fixed (-64, interpreter->scale)) 17356 != sfnt_mul_f26dot6_fixed (-1, interpreter->scale))
17356 { 17357 {
17357 fprintf (stderr, "failed, got %d at scale %d," 17358 fprintf (stderr, "failed, got %d at scale %d,"
17358 " expected %d\n", 17359 " expected %d\n",
17359 interpreter->state.single_width_value, 17360 interpreter->state.single_width_value,
17360 interpreter->scale, 17361 interpreter->scale,
17361 sfnt_mul_f26dot6_fixed (-64, interpreter->scale)); 17362 sfnt_mul_f26dot6_fixed (-1, interpreter->scale));
17362 return; 17363 return;
17363 } 17364 }
17364 17365
@@ -20532,8 +20533,8 @@ main (int argc, char **argv)
20532 return 1; 20533 return 1;
20533 } 20534 }
20534 20535
20535#define FANCY_PPEM 14 20536#define FANCY_PPEM 12
20536#define EASY_PPEM 14 20537#define EASY_PPEM 12
20537 20538
20538 interpreter = NULL; 20539 interpreter = NULL;
20539 head = sfnt_read_head_table (fd, font); 20540 head = sfnt_read_head_table (fd, font);