diff options
| author | Po Lu | 2024-01-01 11:27:59 +0800 |
|---|---|---|
| committer | Po Lu | 2024-01-01 11:27:59 +0800 |
| commit | f80f1b23bfd277a9db0ee6961a3d9f09c4cba219 (patch) | |
| tree | f7f167f20fc1076118064e82f5b0d870f22e4f96 /src | |
| parent | 82bb8de74617b3af083412614c126c82153c2a29 (diff) | |
| download | emacs-f80f1b23bfd277a9db0ee6961a3d9f09c4cba219.tar.gz emacs-f80f1b23bfd277a9db0ee6961a3d9f09c4cba219.zip | |
Bring GX point interpolation further into standards compliance
* src/sfnt.c (sfnt_infer_deltas_2): New function; factor much of
sfnt_infer_deltas_1 into this function, then modify its
treatment of untouched points positioned at their reference
points to align with standard GX treatment.
(sfnt_infer_deltas_1): Remove all code not concerning anchor
point discovery.
(main): Adjust tests.
Diffstat (limited to 'src')
| -rw-r--r-- | src/sfnt.c | 451 |
1 files changed, 182 insertions, 269 deletions
diff --git a/src/sfnt.c b/src/sfnt.c index 7625254d0bd..deafaec31e7 100644 --- a/src/sfnt.c +++ b/src/sfnt.c | |||
| @@ -15314,322 +15314,235 @@ sfnt_compute_tuple_scale (struct sfnt_blend *blend, bool intermediate_p, | |||
| 15314 | return scale; | 15314 | return scale; |
| 15315 | } | 15315 | } |
| 15316 | 15316 | ||
| 15317 | /* Infer point positions for points that have been partially moved | 15317 | /* Move each point in the simple glyph GLYPH between PAIR_START and |
| 15318 | within the contour in GLYPH denoted by START and END. */ | 15318 | PAIR_END to agree with the positions of those two anchor points as |
| 15319 | compared with their initial positions recorded within the arrays X | ||
| 15320 | and Y. | ||
| 15321 | |||
| 15322 | The range formed between PAIR_START and PAIR_END may encompass the | ||
| 15323 | upper extreme of the contour between START and END. */ | ||
| 15319 | 15324 | ||
| 15320 | static void | 15325 | static void |
| 15321 | sfnt_infer_deltas_1 (struct sfnt_glyph *glyph, size_t start, | 15326 | sfnt_infer_deltas_2 (struct sfnt_glyph *glyph, size_t pair_start, |
| 15322 | size_t end, bool *touched, sfnt_fword *x, | 15327 | size_t pair_end, size_t start, size_t end, |
| 15323 | sfnt_fword *y) | 15328 | sfnt_fword *x, sfnt_fword *y) |
| 15324 | { | 15329 | { |
| 15325 | size_t i, pair_start, pair_end, pair_first, j; | 15330 | size_t j; |
| 15326 | sfnt_fword min_pos, max_pos, position; | 15331 | sfnt_fword min_pos, max_pos, position, d1, d2; |
| 15327 | sfnt_fixed ratio, delta; | 15332 | sfnt_fixed ratio, delta; |
| 15328 | 15333 | ||
| 15329 | pair_start = pair_first = -1; | 15334 | j = pair_start + 1; |
| 15330 | |||
| 15331 | /* Look for pairs of touched points. */ | ||
| 15332 | 15335 | ||
| 15333 | for (i = start; i <= end; ++i) | 15336 | while (j != pair_end) |
| 15334 | { | 15337 | { |
| 15335 | if (!touched[i]) | 15338 | /* Reset j to the contour's start position if it is about to |
| 15336 | continue; | 15339 | overrun this contour. */ |
| 15337 | 15340 | ||
| 15338 | if (pair_start == -1) | 15341 | if (j > end) |
| 15339 | { | 15342 | { |
| 15340 | pair_first = i; | 15343 | /* The start of the contour might also be the end of this |
| 15341 | goto next; | 15344 | reference point. */ |
| 15345 | if (start == pair_end) | ||
| 15346 | return; | ||
| 15347 | |||
| 15348 | j = start; | ||
| 15342 | } | 15349 | } |
| 15343 | 15350 | ||
| 15344 | pair_end = i; | 15351 | /* Consider the X axis. Set min_pos and max_pos to the |
| 15352 | smallest and greatest values along that axis. */ | ||
| 15353 | min_pos = MIN (x[pair_start], x[pair_end]); | ||
| 15354 | max_pos = MAX (x[pair_start], x[pair_end]); | ||
| 15345 | 15355 | ||
| 15346 | /* pair_start to pair_end are now a pair of points, where points | 15356 | /* Now see if the current point lies between min and |
| 15347 | in between should be interpolated. */ | 15357 | max... |
| 15348 | 15358 | ||
| 15349 | for (j = pair_start + 1; j < pair_end; ++j) | 15359 | GX interpolation differs from IUP in one important detail: |
| 15360 | points are shifted to follow the movement of their reference | ||
| 15361 | points if their positions are identical to those of any of | ||
| 15362 | their reference points, whereas IUP considers such points to | ||
| 15363 | fall within their reference points. */ | ||
| 15364 | if (x[j] > min_pos && x[j] < max_pos) | ||
| 15365 | { | ||
| 15366 | /* Interpolate between min_pos and max_pos. */ | ||
| 15367 | ratio = sfnt_div_fixed ((sfnt_sub (x[j], min_pos) | ||
| 15368 | * 65536), | ||
| 15369 | (sfnt_sub (max_pos, min_pos) | ||
| 15370 | * 65536)); | ||
| 15371 | |||
| 15372 | /* Load the current positions of pair_start and pair_end | ||
| 15373 | along this axis. */ | ||
| 15374 | min_pos = MIN (glyph->simple->x_coordinates[pair_start], | ||
| 15375 | glyph->simple->x_coordinates[pair_end]); | ||
| 15376 | max_pos = MAX (glyph->simple->x_coordinates[pair_start], | ||
| 15377 | glyph->simple->x_coordinates[pair_end]); | ||
| 15378 | |||
| 15379 | /* Lerp in between. */ | ||
| 15380 | delta = sfnt_sub (max_pos, min_pos); | ||
| 15381 | delta = sfnt_mul_fixed (ratio, delta); | ||
| 15382 | glyph->simple->x_coordinates[j] = min_pos + delta; | ||
| 15383 | } | ||
| 15384 | else | ||
| 15350 | { | 15385 | { |
| 15351 | /* Consider the X axis. Set min_pos and max_pos to the | 15386 | /* ... otherwise, move point j by the delta of the |
| 15352 | smallest and greatest values along that axis. */ | 15387 | nearest touched point. */ |
| 15353 | min_pos = MIN (x[pair_start], x[pair_end]); | 15388 | |
| 15354 | max_pos = MAX (x[pair_start], x[pair_end]); | 15389 | /* If min_pos and max_pos are the same, apply |
| 15355 | 15390 | pair_start's delta if it is identical to that of | |
| 15356 | /* Now see if the current point lies between min and | 15391 | pair_end, or apply nothing at all otherwise. */ |
| 15357 | max... */ | 15392 | |
| 15358 | if (x[j] >= min_pos && x[j] <= max_pos) | 15393 | if (min_pos == max_pos) |
| 15359 | { | 15394 | { |
| 15360 | /* If min_pos and max_pos are the same, apply | 15395 | d1 = (glyph->simple->x_coordinates[pair_start] |
| 15361 | pair_start's delta if it is identical to that of | 15396 | - x[pair_start]); |
| 15362 | pair_end, or apply nothing at all otherwise. */ | 15397 | d2 = (glyph->simple->x_coordinates[pair_end] |
| 15398 | - x[pair_start]); | ||
| 15363 | 15399 | ||
| 15364 | if (min_pos == max_pos) | 15400 | if (d1 == d2) |
| 15365 | { | 15401 | glyph->simple->x_coordinates[j] += d1; |
| 15366 | if ((glyph->simple->x_coordinates[pair_start] | ||
| 15367 | - x[pair_start]) | ||
| 15368 | == (glyph->simple->x_coordinates[pair_end] | ||
| 15369 | - x[pair_end])) | ||
| 15370 | glyph->simple->x_coordinates[j] | ||
| 15371 | += (glyph->simple->x_coordinates[pair_start] | ||
| 15372 | - x[pair_start]); | ||
| 15373 | 15402 | ||
| 15374 | continue; | 15403 | goto consider_y; |
| 15375 | } | 15404 | } |
| 15376 | 15405 | ||
| 15377 | /* Interpolate between min_pos and max_pos. */ | 15406 | if (x[j] >= max_pos) |
| 15378 | ratio = sfnt_div_fixed ((sfnt_sub (x[j], min_pos) | 15407 | { |
| 15379 | * 65536), | 15408 | position = MAX (glyph->simple->x_coordinates[pair_start], |
| 15380 | (sfnt_sub (max_pos, min_pos) | 15409 | glyph->simple->x_coordinates[pair_end]); |
| 15381 | * 65536)); | 15410 | delta = position - max_pos; |
| 15382 | |||
| 15383 | /* Load the current positions of pair_start and pair_end | ||
| 15384 | along this axis. */ | ||
| 15385 | min_pos = MIN (glyph->simple->x_coordinates[pair_start], | ||
| 15386 | glyph->simple->x_coordinates[pair_end]); | ||
| 15387 | max_pos = MAX (glyph->simple->x_coordinates[pair_start], | ||
| 15388 | glyph->simple->x_coordinates[pair_end]); | ||
| 15389 | |||
| 15390 | /* Lerp in between. */ | ||
| 15391 | delta = sfnt_sub (max_pos, min_pos); | ||
| 15392 | delta = sfnt_mul_fixed (ratio, delta); | ||
| 15393 | glyph->simple->x_coordinates[j] = min_pos + delta; | ||
| 15394 | } | 15411 | } |
| 15395 | else | 15412 | else |
| 15396 | { | 15413 | { |
| 15397 | /* ... otherwise, move point j by the delta of the | 15414 | position = MIN (glyph->simple->x_coordinates[pair_start], |
| 15398 | nearest touched point. */ | 15415 | glyph->simple->x_coordinates[pair_end]); |
| 15416 | delta = position - min_pos; | ||
| 15417 | } | ||
| 15399 | 15418 | ||
| 15400 | if (x[j] >= max_pos) | 15419 | glyph->simple->x_coordinates[j] = x[j] + delta; |
| 15401 | { | 15420 | } |
| 15402 | position = MAX (glyph->simple->x_coordinates[pair_start], | ||
| 15403 | glyph->simple->x_coordinates[pair_end]); | ||
| 15404 | delta = position - max_pos; | ||
| 15405 | } | ||
| 15406 | else | ||
| 15407 | { | ||
| 15408 | position = MIN (glyph->simple->x_coordinates[pair_start], | ||
| 15409 | glyph->simple->x_coordinates[pair_end]); | ||
| 15410 | delta = position - min_pos; | ||
| 15411 | } | ||
| 15412 | 15421 | ||
| 15413 | glyph->simple->x_coordinates[j] = x[j] + delta; | 15422 | consider_y: |
| 15414 | } | 15423 | |
| 15424 | /* Now, consider the Y axis. */ | ||
| 15425 | min_pos = MIN (y[pair_start], y[pair_end]); | ||
| 15426 | max_pos = MAX (y[pair_start], y[pair_end]); | ||
| 15415 | 15427 | ||
| 15416 | /* Now, consider the Y axis. */ | 15428 | /* Now see if the current point lies between min and |
| 15417 | min_pos = MIN (y[pair_start], y[pair_end]); | 15429 | max... |
| 15418 | max_pos = MAX (y[pair_start], y[pair_end]); | ||
| 15419 | 15430 | ||
| 15420 | /* Now see if the current point lies between min and | 15431 | GX interpolation differs from IUP in one important detail: |
| 15421 | max... */ | 15432 | points are shifted to follow the movement of their reference |
| 15422 | if (y[j] >= min_pos && y[j] <= max_pos) | 15433 | points if their positions are identical to those of any of |
| 15434 | their reference points, whereas IUP considers such points to | ||
| 15435 | fall within their reference points. */ | ||
| 15436 | if (y[j] > min_pos && y[j] < max_pos) | ||
| 15437 | { | ||
| 15438 | /* Interpolate between min_pos and max_pos. */ | ||
| 15439 | ratio = sfnt_div_fixed ((sfnt_sub (y[j], min_pos) | ||
| 15440 | * 65536), | ||
| 15441 | (sfnt_sub (max_pos, min_pos) | ||
| 15442 | * 65536)); | ||
| 15443 | |||
| 15444 | /* Load the current positions of pair_start and pair_end | ||
| 15445 | along this axis. */ | ||
| 15446 | min_pos = MIN (glyph->simple->y_coordinates[pair_start], | ||
| 15447 | glyph->simple->y_coordinates[pair_end]); | ||
| 15448 | max_pos = MAX (glyph->simple->y_coordinates[pair_start], | ||
| 15449 | glyph->simple->y_coordinates[pair_end]); | ||
| 15450 | |||
| 15451 | /* Lerp in between. */ | ||
| 15452 | delta = sfnt_sub (max_pos, min_pos); | ||
| 15453 | delta = sfnt_mul_fixed (ratio, delta); | ||
| 15454 | glyph->simple->y_coordinates[j] = min_pos + delta; | ||
| 15455 | } | ||
| 15456 | else | ||
| 15457 | { | ||
| 15458 | /* ... otherwise, move point j by the delta of the | ||
| 15459 | nearest touched point. */ | ||
| 15460 | |||
| 15461 | /* If min_pos and max_pos are the same, apply | ||
| 15462 | pair_start's delta if it is identical to that of | ||
| 15463 | pair_end, or apply nothing at all otherwise. */ | ||
| 15464 | |||
| 15465 | if (min_pos == max_pos) | ||
| 15423 | { | 15466 | { |
| 15424 | /* If min_pos and max_pos are the same, apply | 15467 | d1 = (glyph->simple->y_coordinates[pair_start] |
| 15425 | pair_start's delta if it is identical to that of | 15468 | - y[pair_start]); |
| 15426 | pair_end, or apply nothing at all otherwise. */ | 15469 | d2 = (glyph->simple->y_coordinates[pair_end] |
| 15470 | - y[pair_start]); | ||
| 15427 | 15471 | ||
| 15428 | if (min_pos == max_pos) | 15472 | if (d1 == d2) |
| 15429 | { | 15473 | glyph->simple->y_coordinates[j] += d1; |
| 15430 | if ((glyph->simple->y_coordinates[pair_start] | ||
| 15431 | - y[pair_start]) | ||
| 15432 | == (glyph->simple->y_coordinates[pair_end] | ||
| 15433 | - y[pair_end])) | ||
| 15434 | glyph->simple->y_coordinates[j] | ||
| 15435 | += (glyph->simple->y_coordinates[pair_start] | ||
| 15436 | - y[pair_start]); | ||
| 15437 | 15474 | ||
| 15438 | continue; | 15475 | goto next; |
| 15439 | } | 15476 | } |
| 15440 | 15477 | ||
| 15441 | /* Interpolate between min_pos and max_pos. */ | 15478 | if (y[j] >= max_pos) |
| 15442 | ratio = sfnt_div_fixed ((sfnt_sub (y[j], min_pos) | 15479 | { |
| 15443 | * 65536), | 15480 | position = MAX (glyph->simple->y_coordinates[pair_start], |
| 15444 | (sfnt_sub (max_pos, min_pos) | 15481 | glyph->simple->y_coordinates[pair_end]); |
| 15445 | * 65536)); | 15482 | delta = position - max_pos; |
| 15446 | |||
| 15447 | /* Load the current positions of pair_start and pair_end | ||
| 15448 | along this axis. */ | ||
| 15449 | min_pos = MIN (glyph->simple->y_coordinates[pair_start], | ||
| 15450 | glyph->simple->y_coordinates[pair_end]); | ||
| 15451 | max_pos = MAX (glyph->simple->y_coordinates[pair_start], | ||
| 15452 | glyph->simple->y_coordinates[pair_end]); | ||
| 15453 | |||
| 15454 | /* Lerp in between. */ | ||
| 15455 | delta = sfnt_sub (max_pos, min_pos); | ||
| 15456 | delta = sfnt_mul_fixed (ratio, delta); | ||
| 15457 | glyph->simple->y_coordinates[j] = min_pos + delta; | ||
| 15458 | } | 15483 | } |
| 15459 | else | 15484 | else |
| 15460 | { | 15485 | { |
| 15461 | /* ... otherwise, move point j by the delta of the | 15486 | position = MIN (glyph->simple->y_coordinates[pair_start], |
| 15462 | nearest touched point. */ | 15487 | glyph->simple->y_coordinates[pair_end]); |
| 15463 | 15488 | delta = position - min_pos; | |
| 15464 | if (y[j] >= max_pos) | ||
| 15465 | { | ||
| 15466 | position = MAX (glyph->simple->y_coordinates[pair_start], | ||
| 15467 | glyph->simple->y_coordinates[pair_end]); | ||
| 15468 | delta = position - max_pos; | ||
| 15469 | } | ||
| 15470 | else | ||
| 15471 | { | ||
| 15472 | position = MIN (glyph->simple->y_coordinates[pair_start], | ||
| 15473 | glyph->simple->y_coordinates[pair_end]); | ||
| 15474 | delta = position - min_pos; | ||
| 15475 | } | ||
| 15476 | |||
| 15477 | glyph->simple->y_coordinates[j] = y[j] + delta; | ||
| 15478 | } | 15489 | } |
| 15490 | |||
| 15491 | glyph->simple->y_coordinates[j] = y[j] + delta; | ||
| 15479 | } | 15492 | } |
| 15480 | 15493 | ||
| 15481 | next: | 15494 | next: |
| 15482 | pair_start = i; | 15495 | j++; |
| 15483 | } | 15496 | } |
| 15497 | } | ||
| 15484 | 15498 | ||
| 15485 | /* If pair_start is set, then lerp points between it and | 15499 | /* Infer point positions for points that have been partially moved |
| 15486 | pair_first. */ | 15500 | within the contour in GLYPH denoted by START and END. */ |
| 15487 | |||
| 15488 | if (pair_start != (size_t) -1) | ||
| 15489 | { | ||
| 15490 | j = pair_start + 1; | ||
| 15491 | |||
| 15492 | if (j > end) | ||
| 15493 | j = start; | ||
| 15494 | |||
| 15495 | pair_end = pair_first; | ||
| 15496 | |||
| 15497 | while (j != pair_first) | ||
| 15498 | { | ||
| 15499 | /* Consider the X axis. Set min_pos and max_pos to the | ||
| 15500 | smallest and greatest values along that axis. */ | ||
| 15501 | min_pos = MIN (x[pair_start], x[pair_end]); | ||
| 15502 | max_pos = MAX (x[pair_start], x[pair_end]); | ||
| 15503 | |||
| 15504 | /* Now see if the current point lies between min and | ||
| 15505 | max... */ | ||
| 15506 | if (x[j] >= min_pos && x[j] <= max_pos) | ||
| 15507 | { | ||
| 15508 | /* If min_pos and max_pos are the same, apply | ||
| 15509 | pair_start's delta if it is identical to that of | ||
| 15510 | pair_end, or apply nothing at all otherwise. */ | ||
| 15511 | 15501 | ||
| 15512 | if (min_pos == max_pos) | 15502 | static void |
| 15513 | { | 15503 | sfnt_infer_deltas_1 (struct sfnt_glyph *glyph, size_t start, |
| 15514 | if ((glyph->simple->x_coordinates[pair_start] | 15504 | size_t end, bool *touched, sfnt_fword *x, |
| 15515 | - x[pair_start]) | 15505 | sfnt_fword *y) |
| 15516 | == (glyph->simple->x_coordinates[pair_end] | 15506 | { |
| 15517 | - x[pair_end])) | 15507 | size_t i, pair_start, pair_end, pair_first; |
| 15518 | glyph->simple->x_coordinates[j] | ||
| 15519 | += (glyph->simple->x_coordinates[pair_start] | ||
| 15520 | - x[pair_start]); | ||
| 15521 | |||
| 15522 | goto next_1; | ||
| 15523 | } | ||
| 15524 | 15508 | ||
| 15525 | /* Interpolate between min_pos and max_pos. */ | 15509 | pair_start = pair_first = -1; |
| 15526 | ratio = sfnt_div_fixed ((sfnt_sub (x[j], min_pos) | ||
| 15527 | * 65536), | ||
| 15528 | (sfnt_sub (max_pos, min_pos) | ||
| 15529 | * 65536)); | ||
| 15530 | |||
| 15531 | /* Load the current positions of pair_start and pair_end | ||
| 15532 | along this axis. */ | ||
| 15533 | min_pos = MIN (glyph->simple->x_coordinates[pair_start], | ||
| 15534 | glyph->simple->x_coordinates[pair_end]); | ||
| 15535 | max_pos = MAX (glyph->simple->x_coordinates[pair_start], | ||
| 15536 | glyph->simple->x_coordinates[pair_end]); | ||
| 15537 | |||
| 15538 | /* Lerp in between. */ | ||
| 15539 | delta = sfnt_sub (max_pos, min_pos); | ||
| 15540 | delta = sfnt_mul_fixed (ratio, delta); | ||
| 15541 | glyph->simple->x_coordinates[j] = min_pos + delta; | ||
| 15542 | } | ||
| 15543 | else | ||
| 15544 | { | ||
| 15545 | /* ... otherwise, move point j by the delta of the | ||
| 15546 | nearest touched point. */ | ||
| 15547 | 15510 | ||
| 15548 | if (x[j] >= max_pos) | 15511 | /* Look for pairs of touched points. */ |
| 15549 | { | ||
| 15550 | position = MAX (glyph->simple->x_coordinates[pair_start], | ||
| 15551 | glyph->simple->x_coordinates[pair_end]); | ||
| 15552 | delta = position - max_pos; | ||
| 15553 | } | ||
| 15554 | else | ||
| 15555 | { | ||
| 15556 | position = MIN (glyph->simple->x_coordinates[pair_start], | ||
| 15557 | glyph->simple->x_coordinates[pair_end]); | ||
| 15558 | delta = position - min_pos; | ||
| 15559 | } | ||
| 15560 | 15512 | ||
| 15561 | glyph->simple->x_coordinates[j] = x[j] + delta; | 15513 | for (i = start; i <= end; ++i) |
| 15562 | } | 15514 | { |
| 15515 | if (!touched[i]) | ||
| 15516 | continue; | ||
| 15563 | 15517 | ||
| 15564 | /* Now, consider the Y axis. */ | 15518 | if (pair_start == -1) |
| 15565 | min_pos = MIN (y[pair_start], y[pair_end]); | 15519 | { |
| 15566 | max_pos = MAX (y[pair_start], y[pair_end]); | 15520 | pair_first = i; |
| 15521 | goto next; | ||
| 15522 | } | ||
| 15567 | 15523 | ||
| 15568 | /* Now see if the current point lies between min and | 15524 | pair_end = i; |
| 15569 | max... */ | ||
| 15570 | if (y[j] >= min_pos && y[j] <= max_pos) | ||
| 15571 | { | ||
| 15572 | /* If min_pos and max_pos are the same, apply | ||
| 15573 | pair_start's delta if it is identical to that of | ||
| 15574 | pair_end, or apply nothing at all otherwise. */ | ||
| 15575 | 15525 | ||
| 15576 | if (min_pos == max_pos) | 15526 | /* pair_start to pair_end are now a pair of points whose |
| 15577 | { | 15527 | intermediates should be interpolated. */ |
| 15578 | if ((glyph->simple->y_coordinates[pair_start] | 15528 | sfnt_infer_deltas_2 (glyph, pair_start, pair_end, |
| 15579 | - y[pair_start]) | 15529 | start, end, x, y); |
| 15580 | == (glyph->simple->y_coordinates[pair_end] | ||
| 15581 | - y[pair_end])) | ||
| 15582 | glyph->simple->y_coordinates[j] | ||
| 15583 | += (glyph->simple->y_coordinates[pair_start] | ||
| 15584 | - y[pair_start]); | ||
| 15585 | |||
| 15586 | goto next_1; | ||
| 15587 | } | ||
| 15588 | 15530 | ||
| 15589 | /* Interpolate between min_pos and max_pos. */ | 15531 | next: |
| 15590 | ratio = sfnt_div_fixed ((sfnt_sub (y[j], min_pos) | 15532 | pair_start = i; |
| 15591 | * 65536), | 15533 | } |
| 15592 | (sfnt_sub (max_pos, min_pos) | ||
| 15593 | * 65536)); | ||
| 15594 | |||
| 15595 | /* Load the current positions of pair_start and pair_end | ||
| 15596 | along this axis. */ | ||
| 15597 | min_pos = MIN (glyph->simple->y_coordinates[pair_start], | ||
| 15598 | glyph->simple->y_coordinates[pair_end]); | ||
| 15599 | max_pos = MAX (glyph->simple->y_coordinates[pair_start], | ||
| 15600 | glyph->simple->y_coordinates[pair_end]); | ||
| 15601 | |||
| 15602 | /* Lerp in between. */ | ||
| 15603 | delta = sfnt_sub (max_pos, min_pos); | ||
| 15604 | delta = sfnt_mul_fixed (ratio, delta); | ||
| 15605 | glyph->simple->y_coordinates[j] = min_pos + delta; | ||
| 15606 | } | ||
| 15607 | else | ||
| 15608 | { | ||
| 15609 | /* ... otherwise, move point j by the delta of the | ||
| 15610 | nearest touched point. */ | ||
| 15611 | 15534 | ||
| 15612 | if (y[j] >= max_pos) | 15535 | /* If pair_start is set, then lerp points between it and |
| 15613 | { | 15536 | pair_first. */ |
| 15614 | position = MAX (glyph->simple->y_coordinates[pair_start], | ||
| 15615 | glyph->simple->y_coordinates[pair_end]); | ||
| 15616 | delta = position - max_pos; | ||
| 15617 | } | ||
| 15618 | else | ||
| 15619 | { | ||
| 15620 | position = MIN (glyph->simple->y_coordinates[pair_start], | ||
| 15621 | glyph->simple->y_coordinates[pair_end]); | ||
| 15622 | delta = position - min_pos; | ||
| 15623 | } | ||
| 15624 | 15537 | ||
| 15625 | glyph->simple->y_coordinates[j] = y[j] + delta; | 15538 | if (pair_start != (size_t) -1) |
| 15626 | } | 15539 | { |
| 15540 | pair_end = pair_first; | ||
| 15627 | 15541 | ||
| 15628 | next_1: | 15542 | /* pair_start to pair_end are now a pair of points whose |
| 15629 | j++; | 15543 | intermediates should be interpolated. */ |
| 15630 | if (j > end) | 15544 | sfnt_infer_deltas_2 (glyph, pair_start, pair_end, |
| 15631 | j = start; | 15545 | start, end, x, y); |
| 15632 | } | ||
| 15633 | } | 15546 | } |
| 15634 | } | 15547 | } |
| 15635 | 15548 | ||
| @@ -20696,8 +20609,8 @@ main (int argc, char **argv) | |||
| 20696 | return 1; | 20609 | return 1; |
| 20697 | } | 20610 | } |
| 20698 | 20611 | ||
| 20699 | #define FANCY_PPEM 30 | 20612 | #define FANCY_PPEM 44 |
| 20700 | #define EASY_PPEM 30 | 20613 | #define EASY_PPEM 44 |
| 20701 | 20614 | ||
| 20702 | interpreter = NULL; | 20615 | interpreter = NULL; |
| 20703 | head = sfnt_read_head_table (fd, font); | 20616 | head = sfnt_read_head_table (fd, font); |