aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2023-12-09 11:49:04 +0800
committerPo Lu2023-12-09 11:49:04 +0800
commit414301bce19e24889ce970d60f798e178e556818 (patch)
tree8d8201348329c793de0079a37d50704f7e4fb447
parentef732bd2083c5f28c37dc52a6f96923eed2f5aa8 (diff)
downloademacs-414301bce19e24889ce970d60f798e178e556818.tar.gz
emacs-414301bce19e24889ce970d60f798e178e556818.zip
Correct phantom point generation and MDAP
* src/sfnt.c (sfnt_interpret_mdrp): Cease applying cvt cut in, as this is contrary to the specification. (sfnt_interpret_simple_glyph): Correct typo. (main): Revise tests.
-rw-r--r--src/sfnt.c67
1 files changed, 32 insertions, 35 deletions
diff --git a/src/sfnt.c b/src/sfnt.c
index 34239973797..bc2ffdea9dc 100644
--- a/src/sfnt.c
+++ b/src/sfnt.c
@@ -10381,8 +10381,8 @@ sfnt_interpret_mdrp (struct sfnt_interpreter *interpreter,
10381 uint32_t opcode) 10381 uint32_t opcode)
10382{ 10382{
10383 uint32_t p; 10383 uint32_t p;
10384 sfnt_f26dot6 distance, delta; 10384 sfnt_f26dot6 distance, applied;
10385 sfnt_f26dot6 current_projection, original_projection; 10385 sfnt_f26dot6 current_projection;
10386 sfnt_f26dot6 x, y, org_x, org_y; 10386 sfnt_f26dot6 x, y, org_x, org_y;
10387 sfnt_f26dot6 rx, ry, org_rx, org_ry; 10387 sfnt_f26dot6 rx, ry, org_rx, org_ry;
10388 10388
@@ -10394,20 +10394,21 @@ sfnt_interpret_mdrp (struct sfnt_interpreter *interpreter,
10394 sfnt_address_zp0 (interpreter, interpreter->state.rp0, 10394 sfnt_address_zp0 (interpreter, interpreter->state.rp0,
10395 &rx, &ry, &org_rx, &org_ry); 10395 &rx, &ry, &org_rx, &org_ry);
10396 10396
10397 /* Calculate the distance between P and rp0 prior to hinting. */
10397 distance = DUAL_PROJECT (org_x - org_rx, 10398 distance = DUAL_PROJECT (org_x - org_rx,
10398 org_y - org_ry); 10399 org_y - org_ry);
10399 original_projection = distance; 10400
10401 /* Calculate the distance between P and rp0 as of now in the hinting
10402 process. */
10400 current_projection = PROJECT (x - rx, y - ry); 10403 current_projection = PROJECT (x - rx, y - ry);
10401 10404
10402 /* Test against the single width value. */ 10405 /* Test against the single width value. */
10403 10406
10404 delta = sfnt_sub (distance, 10407 if (interpreter->state.sw_cut_in > 0
10405 interpreter->state.single_width_value); 10408 && distance < (interpreter->state.single_width_value
10406 10409 + interpreter->state.sw_cut_in)
10407 if (delta < 0) 10410 && distance > (interpreter->state.single_width_value
10408 delta = -delta; 10411 - interpreter->state.sw_cut_in))
10409
10410 if (delta < interpreter->state.sw_cut_in)
10411 { 10412 {
10412 /* Use the single width instead, as the CVT entry is too 10413 /* Use the single width instead, as the CVT entry is too
10413 small. */ 10414 small. */
@@ -10418,38 +10419,34 @@ sfnt_interpret_mdrp (struct sfnt_interpreter *interpreter,
10418 distance = -interpreter->state.single_width_value; 10419 distance = -interpreter->state.single_width_value;
10419 } 10420 }
10420 10421
10421 /* Flag B means look at the cvt cut in and round the 10422 /* Flag B implies that the distance should be rounded. The CVT cut
10422 distance. */ 10423 in is not taken into account by MDRP, contrary to earlier
10424 presumptions. */
10423 10425
10424 if (opcode & 4) 10426 if (opcode & 4)
10425 { 10427 applied = sfnt_round_symmetric (interpreter, distance);
10426 delta = sfnt_sub (distance, original_projection); 10428 else
10427 10429 applied = distance;
10428 if (delta < 0)
10429 delta = -delta;
10430
10431 if (delta > interpreter->state.cvt_cut_in)
10432 distance = original_projection;
10433
10434 /* Now, round the distance. */
10435 distance = sfnt_round_symmetric (interpreter, distance);
10436 }
10437 10430
10438 /* Flag C means look at the minimum distance. */ 10431 /* Flag C means look at the minimum distance. */
10439 10432
10440 if (opcode & 8) 10433 if (opcode & 8)
10441 { 10434 {
10442 if (original_projection >= 0 10435 /* Test the sign of the initial distance, but compare the
10443 && distance < interpreter->state.minimum_distance) 10436 distance that will be applied in reality against the minimum
10444 distance = interpreter->state.minimum_distance; 10437 distance. */
10445 else if (original_projection < 0 10438
10446 && distance > -interpreter->state.minimum_distance) 10439 if (distance >= 0
10447 distance = -interpreter->state.minimum_distance; 10440 && applied < interpreter->state.minimum_distance)
10441 applied = interpreter->state.minimum_distance;
10442 else if (distance < 0
10443 && applied > -interpreter->state.minimum_distance)
10444 applied = -interpreter->state.minimum_distance;
10448 } 10445 }
10449 10446
10450 /* Finally, move the point. */ 10447 /* Finally, move the point. */
10451 sfnt_move_zp1 (interpreter, p, 1, 10448 sfnt_move_zp1 (interpreter, p, 1,
10452 sfnt_sub (distance, current_projection)); 10449 sfnt_sub (applied, current_projection));
10453 10450
10454 /* Set RP1 to RP0 and RP2 to the point. If flag 3 is set, also make 10451 /* Set RP1 to RP0 and RP2 to the point. If flag 3 is set, also make
10455 it RP0. */ 10452 it RP0. */
@@ -11431,8 +11428,8 @@ sfnt_interpret_simple_glyph (struct sfnt_glyph *glyph,
11431 /* Load phantom points. */ 11428 /* Load phantom points. */
11432 zone->y_points[i] = phantom_point_1_y; 11429 zone->y_points[i] = phantom_point_1_y;
11433 zone->y_points[i + 1] = phantom_point_2_y; 11430 zone->y_points[i + 1] = phantom_point_2_y;
11434 zone->y_current[i] = phantom_point_1_x; 11431 zone->y_current[i] = phantom_point_1_y;
11435 zone->y_current[i + 1] = phantom_point_2_x; 11432 zone->y_current[i + 1] = phantom_point_2_y;
11436 11433
11437 /* Load phantom point flags. */ 11434 /* Load phantom point flags. */
11438 zone->flags[i] = SFNT_POINT_PHANTOM; 11435 zone->flags[i] = SFNT_POINT_PHANTOM;
@@ -19549,8 +19546,8 @@ main (int argc, char **argv)
19549 return 1; 19546 return 1;
19550 } 19547 }
19551 19548
19552#define FANCY_PPEM 18 19549#define FANCY_PPEM 40
19553#define EASY_PPEM 18 19550#define EASY_PPEM 40
19554 19551
19555 interpreter = NULL; 19552 interpreter = NULL;
19556 head = sfnt_read_head_table (fd, font); 19553 head = sfnt_read_head_table (fd, font);