diff options
| author | Po Lu | 2023-12-19 16:42:38 +0800 |
|---|---|---|
| committer | Po Lu | 2023-12-19 16:42:38 +0800 |
| commit | 0a57e1cd2c97db3a990f88043dc4a53619390228 (patch) | |
| tree | 4ea79d103cfb19e2de9748f3c50c2fc8e8a58bb9 /src | |
| parent | d0e3dfa764cdb5c15c2a525b455df495097a86bb (diff) | |
| download | emacs-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.c | 41 |
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); |