aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2023-02-07 22:25:54 +0800
committerPo Lu2023-02-07 22:25:54 +0800
commit795f5a16b56a757fbb77562f47aaa4513ca52dbc (patch)
treedeb9862ce9e62e9023a93b4b4b66b3f5a3a82146 /src
parent9b79f429edd173efd6ecbdcb2f0a5fafa8d6e523 (diff)
downloademacs-795f5a16b56a757fbb77562f47aaa4513ca52dbc.tar.gz
emacs-795f5a16b56a757fbb77562f47aaa4513ca52dbc.zip
Update Android port
* INSTALL.android: Describe patches for BoringSSL on ARM. * src/sfnt.c (sfnt_build_glyph_outline): Remove redundant multiplication. (sfnt_prepare_raster): Update offset calculation for changes. (sfnt_step_edge, sfnt_step_edge_n): Handle bresenham terms. (sfnt_build_outline_edges): Don't subtract floored xmin, just xmin. (sfnt_saturate_short): Make clang generate better code. (sfnt_fill_span): Stop rounding coordinates. (sfnt_poly_span): Poly consecutive on transitions all in one go. (sfnt_lookup_glyph_metrics): Remove redundant multiplication. (struct sfnt_interpreter): New hooks for debugging. (sfnt_large_integer_add): New function. (sfnt_mul_f26dot6_fixed): Round product. (sfnt_make_interpreter): Remove redundant multiplication. (CHECK_STACK_ELEMENTS, POP_UNCHECKED, PUSH_UNCHECKED): New macros. (MOVE, POP, SWAP, CINDEX, RS, RCVT, LT, LTEQ, GT, GTEQ, EQ, NEQ) (EVEN, AND, OR, NOT, ADD, SUB, DIV, MUL, ABS, NEG, FLOOR, CEILING) (GETINFO, ROLL, _MAX, _MIN, ROUND, NROUND, GC, MD): Don't check SP redundantly, especially when pushing an element right after popping one. (sfnt_move_glyph_zone): Don't touch points by passing NULL as flags. (sfnt_direct_move_zp2): Touch P in the directions of the movement. (sfnt_interpret_scfs): Fix coding style. (sfnt_interpret_simple_glyph): Don't round Y coordinates. (sfnt_test_span, sfnt_test_edges, sfnt_debug_edges, sfnt_test_edge) (sfnt_x_raster, sfnt_test_raster, rcvt_test_args) (deltac1_test_args, deltac2_test_args, deltac3_test_args) (roll_1_test_args, sfnt_run_hook, sfnt_identify_instruction) (sfnt_verbose, main): Improve debug code and tests. * src/sfnt.h (struct sfnt_edge): Add bresenham terms.
Diffstat (limited to 'src')
-rw-r--r--src/sfnt.c769
-rw-r--r--src/sfnt.h21
2 files changed, 639 insertions, 151 deletions
diff --git a/src/sfnt.c b/src/sfnt.c
index 124185a5073..13a73f057bd 100644
--- a/src/sfnt.c
+++ b/src/sfnt.c
@@ -47,6 +47,7 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
47#include <errno.h> 47#include <errno.h>
48 48
49#include <X11/Xlib.h> 49#include <X11/Xlib.h>
50#include <X11/extensions/Xrender.h>
50 51
51static void * 52static void *
52xmalloc (size_t size) 53xmalloc (size_t size)
@@ -3489,8 +3490,7 @@ sfnt_build_glyph_outline (struct sfnt_glyph *glyph,
3489 PIXEL = UNIT * PPEM / UPEM */ 3490 PIXEL = UNIT * PPEM / UPEM */
3490 3491
3491 build_outline_context.factor 3492 build_outline_context.factor
3492 = sfnt_div_fixed (pixel_size * 65536, 3493 = sfnt_div_fixed (pixel_size, head->units_per_em);
3493 head->units_per_em * 65536);
3494 3494
3495 /* Decompose the outline. */ 3495 /* Decompose the outline. */
3496 rc = sfnt_decompose_glyph (glyph, sfnt_move_to_and_build, 3496 rc = sfnt_decompose_glyph (glyph, sfnt_move_to_and_build,
@@ -3566,10 +3566,8 @@ sfnt_prepare_raster (struct sfnt_raster *raster,
3566 + (SFNT_POLY_ALIGNMENT - 1)) 3566 + (SFNT_POLY_ALIGNMENT - 1))
3567 & ~(SFNT_POLY_ALIGNMENT - 1)); 3567 & ~(SFNT_POLY_ALIGNMENT - 1));
3568 3568
3569 raster->offx 3569 raster->offx = sfnt_round_fixed (outline->xmin) >> 16;
3570 = sfnt_floor_fixed (outline->xmin) >> 16; 3570 raster->offy = sfnt_floor_fixed (outline->ymin) >> 16;
3571 raster->offy
3572 = sfnt_floor_fixed (outline->ymin) >> 16;
3573} 3571}
3574 3572
3575typedef void (*sfnt_edge_proc) (struct sfnt_edge *, size_t, 3573typedef void (*sfnt_edge_proc) (struct sfnt_edge *, size_t,
@@ -3582,15 +3580,41 @@ typedef void (*sfnt_span_proc) (struct sfnt_edge *, sfnt_fixed, void *);
3582static void 3580static void
3583sfnt_step_edge (struct sfnt_edge *edge) 3581sfnt_step_edge (struct sfnt_edge *edge)
3584{ 3582{
3585 /* Step edge. */ 3583 /* Add error accumulator. */
3586 edge->x += edge->step_x; 3584 edge->error += edge->step_x;
3585
3586 while (edge->error > 0)
3587 {
3588 /* Subtract error and add 1. */
3589 edge->x += edge->signed_step;
3590 edge->error -= 65536;
3591 }
3587} 3592}
3588 3593
3589/* Build a list of edges for each contour in OUTLINE, applying 3594/* Move EDGE->x forward, assuming that the scanline has moved upwards
3590 OUTLINE->xmin and floor (OUTLINE->ymin) as the offset to each edge. 3595 by N, and that N is less than or equal to SFNT_POLY_STEP. */
3591 Call EDGE_PROC with DCONTEXT and the resulting edges as arguments. 3596
3592 It is OK to modify the edges given to EDGE_PROC. Align all edges 3597static void
3593 to the sub-pixel grid. */ 3598sfnt_step_edge_n (struct sfnt_edge *edge, sfnt_fixed n)
3599{
3600 /* Add error accumulator. */
3601 edge->error += sfnt_mul_fixed (edge->step_x, n);
3602
3603 /* See if error is more than 0, and bring the line back to where it
3604 should be. */
3605
3606 while (edge->error > 0)
3607 {
3608 /* Subtract error and add 1. */
3609 edge->x += edge->signed_step;
3610 edge->error -= 65536;
3611 }
3612}
3613
3614/* Build a list of edges for each contour in OUTLINE, applying xmin
3615 and ymin as the offset to each edge. Call EDGE_PROC with DCONTEXT
3616 and the resulting edges as arguments. It is OK to modify the edges
3617 given to EDGE_PROC. Align all edges to the sub-pixel grid. */
3594 3618
3595static void 3619static void
3596sfnt_build_outline_edges (struct sfnt_glyph_outline *outline, 3620sfnt_build_outline_edges (struct sfnt_glyph_outline *outline,
@@ -3606,9 +3630,10 @@ sfnt_build_outline_edges (struct sfnt_glyph_outline *outline,
3606 edge = 0; 3630 edge = 0;
3607 3631
3608 /* ymin and xmin must be the same as the offset used to set offy and 3632 /* ymin and xmin must be the same as the offset used to set offy and
3609 offx in rasters. */ 3633 offx in rasters. However, xmin is not floored; otherwise, glyphs
3634 like ``e'' look bad at certain ppem. */
3610 ymin = sfnt_floor_fixed (outline->ymin); 3635 ymin = sfnt_floor_fixed (outline->ymin);
3611 xmin = sfnt_floor_fixed (outline->xmin); 3636 xmin = outline->xmin;
3612 3637
3613 for (i = 0; i < outline->outline_used; ++i) 3638 for (i = 0; i < outline->outline_used; ++i)
3614 { 3639 {
@@ -3666,9 +3691,21 @@ sfnt_build_outline_edges (struct sfnt_glyph_outline *outline,
3666 dy = abs (outline->outline[top].y 3691 dy = abs (outline->outline[top].y
3667 - outline->outline[bottom].y); 3692 - outline->outline[bottom].y);
3668 3693
3669#ifdef TEST 3694 /* Step to first grid point. */
3670 edges[edge].source_x = edges[edge].x; 3695 y = sfnt_poly_grid_ceil (bot);
3671#endif 3696
3697 /* If rounding would make the edge not cover any area, skip this
3698 edge. */
3699 if (y >= edges[edge].top)
3700 continue;
3701
3702 /* Compute the slope error. This is how much X changes for each
3703 increase in Y. */
3704
3705 if (dx >= 0)
3706 step_x = sfnt_div_fixed (dx, dy);
3707 else
3708 step_x = sfnt_div_fixed (-dx, dy);
3672 3709
3673 /* Compute the increment. This is which direction X moves in 3710 /* Compute the increment. This is which direction X moves in
3674 for each increase in Y. */ 3711 for each increase in Y. */
@@ -3676,30 +3713,19 @@ sfnt_build_outline_edges (struct sfnt_glyph_outline *outline,
3676 if (dx >= 0) 3713 if (dx >= 0)
3677 inc_x = 1; 3714 inc_x = 1;
3678 else 3715 else
3679 { 3716 inc_x = -1;
3680 inc_x = -1;
3681 dx = -dx;
3682 }
3683 3717
3684 /* Compute the step X. This is how much X changes for each 3718 edges[edge].signed_step = SFNT_POLY_STEP * inc_x;
3685 increase in Y. */ 3719 edges[edge].next = NULL;
3686 step_x = inc_x * sfnt_div_fixed (dx, dy);
3687 3720
3688 /* Step to first grid point. */ 3721 /* Set the initial Bresenham terms. */
3689 y = sfnt_poly_grid_ceil (bot); 3722 edges[edge].error = step_x - 65536;
3723 edges[edge].step_x = step_x;
3690 3724
3691 /* If rounding would make the edge not cover any area, skip this 3725 sfnt_step_edge_n (&edges[edge], bot - y);
3692 edge. */
3693 if (y > edges[edge].top)
3694 continue;
3695 3726
3696 edges[edge].x += sfnt_mul_fixed (step_x, bot - y); 3727 /* Set the bottom position. */
3697 edges[edge].bottom = y; 3728 edges[edge].bottom = y;
3698 edges[edge].next = NULL;
3699
3700 /* Compute the step X scaled to the poly step. */
3701 edges[edge].step_x
3702 = sfnt_mul_fixed (step_x, SFNT_POLY_STEP);
3703 3729
3704 edge++; 3730 edge++;
3705 } 3731 }
@@ -3741,7 +3767,16 @@ sfnt_compare_edges (const void *a, const void *b)
3741 coordinates, and incrementing the Y axis by SFNT_POLY_STEP instead 3767 coordinates, and incrementing the Y axis by SFNT_POLY_STEP instead
3742 of 1. SFNT_POLY_STEP is chosen to always keep Y aligned to a grid 3768 of 1. SFNT_POLY_STEP is chosen to always keep Y aligned to a grid
3743 placed such that there are always 1 << SFNT_POLY_SHIFT positions 3769 placed such that there are always 1 << SFNT_POLY_SHIFT positions
3744 available for each integral pixel coordinate. */ 3770 available for each integral pixel coordinate.
3771
3772 Moving upwards is performed using Bresenham's algorithm. Prior to
3773 an edge being created, a single slope error is computed. This is
3774 how much X should increase for each increase in Y.
3775
3776 Upon each increase in Y, X initially does not move. Instead, the
3777 ``slope error'' is accumulated; once it exceeds the sample size,
3778 one sample is subtracted from the accumulator, and X is increased
3779 by one step. */
3745 3780
3746static void 3781static void
3747sfnt_poly_edges (struct sfnt_edge *edges, size_t size, 3782sfnt_poly_edges (struct sfnt_edge *edges, size_t size,
@@ -3822,13 +3857,16 @@ sfnt_poly_edges (struct sfnt_edge *edges, size_t size,
3822 } 3857 }
3823} 3858}
3824 3859
3825/* Saturate-convert the given unsigned short value X to an unsigned 3860/* Saturate and convert the given unsigned short value X to an
3826 char. */ 3861 unsigned char. */
3827 3862
3828static unsigned char 3863static unsigned char
3829sfnt_saturate_short (unsigned short x) 3864sfnt_saturate_short (unsigned short x)
3830{ 3865{
3831 return (unsigned char) ((x) | (0 - ((x) >> 8))); 3866 if (x > 255)
3867 return 255;
3868
3869 return x;
3832} 3870}
3833 3871
3834/* Fill a single span of pixels between X0 and X1 at Y, a raster 3872/* Fill a single span of pixels between X0 and X1 at Y, a raster
@@ -3855,11 +3893,6 @@ sfnt_fill_span (struct sfnt_raster *raster, sfnt_fixed y,
3855 if (x1 <= x0) 3893 if (x1 <= x0)
3856 return; 3894 return;
3857 3895
3858 /* Round Y, X0 and X1. */
3859 y += SFNT_POLY_ROUND;
3860 x0 += SFNT_POLY_ROUND;
3861 x1 += SFNT_POLY_ROUND;
3862
3863 /* Figure out coverage based on Y axis fractional. */ 3896 /* Figure out coverage based on Y axis fractional. */
3864 coverage = sfnt_poly_coverage[(y >> (16 - SFNT_POLY_SHIFT)) 3897 coverage = sfnt_poly_coverage[(y >> (16 - SFNT_POLY_SHIFT))
3865 & SFNT_POLY_MASK]; 3898 & SFNT_POLY_MASK];
@@ -3882,11 +3915,11 @@ sfnt_fill_span (struct sfnt_raster *raster, sfnt_fixed y,
3882#endif 3915#endif
3883 start += left >> SFNT_POLY_SHIFT; 3916 start += left >> SFNT_POLY_SHIFT;
3884 3917
3918 w = 0;
3919
3885 /* Compute coverage for first pixel, then poly. */ 3920 /* Compute coverage for first pixel, then poly. */
3886 if (left & SFNT_POLY_MASK) 3921 if (left & SFNT_POLY_MASK)
3887 { 3922 {
3888 w = 0;
3889
3890 /* Note that col is an index into the columns of the coverage 3923 /* Note that col is an index into the columns of the coverage
3891 map, unlike row which indexes the raster. */ 3924 map, unlike row which indexes the raster. */
3892 col = 0; 3925 col = 0;
@@ -3941,24 +3974,47 @@ sfnt_poly_span (struct sfnt_edge *start, sfnt_fixed y,
3941{ 3974{
3942 struct sfnt_edge *edge; 3975 struct sfnt_edge *edge;
3943 int winding; 3976 int winding;
3944 sfnt_fixed x0; 3977 sfnt_fixed x0, x1;
3978
3979 /* Pacify -Wmaybe-uninitialized; x1 and x0 are only used when edge
3980 != start, at which point x0 has already been set. */
3981 x0 = x1 = 0;
3945 3982
3946 /* Generate the X axis coverage map. Then poly it onto RASTER. 3983 /* Generate the X axis coverage map. Then poly it onto RASTER.
3947 winding on each edge determines the winding direction: when it is 3984 winding on each edge determines the winding direction: when it is
3948 positive, winding is 1. When it is negative, winding is -1. */ 3985 positive, winding is 1. When it is negative, winding is -1.
3986
3987 Fill each consecutive stretch of spans that are inside the glyph;
3988 otherwise, coverage will overlap for some spans, but not
3989 others.
3990
3991 The spans must be terminated with an edge that causes an
3992 off-transition, or some spans will not be filled. */
3949 3993
3950 winding = 0; 3994 winding = 0;
3951 3995
3952 for (edge = start; edge; edge = edge->next) 3996 for (edge = start; edge; edge = edge->next)
3953 { 3997 {
3954 if (!winding) 3998 if (!winding)
3955 x0 = edge->x; 3999 {
4000 if (edge != start && x0 != x1)
4001 /* Draw this section of spans that are on. */
4002 sfnt_fill_span (raster, (raster->height << 16) - y,
4003 x0, x1);
4004
4005 x0 = x1 = edge->x;
4006 }
3956 else 4007 else
3957 sfnt_fill_span (raster, (raster->height << 16) - y, 4008 x1 = edge->x;
3958 x0, edge->x);
3959 4009
3960 winding += edge->winding; 4010 winding += edge->winding;
3961 } 4011 }
4012
4013 /* Draw the last span following the last off-transition. */
4014
4015 if (!winding && edge != start && x0 != x1)
4016 sfnt_fill_span (raster, (raster->height << 16) - y,
4017 x0, x1);
3962} 4018}
3963 4019
3964 4020
@@ -4143,8 +4199,7 @@ sfnt_lookup_glyph_metrics (sfnt_glyph glyph, int pixel_size,
4143 } 4199 }
4144 4200
4145 /* Now scale lbearing and advance up to the pixel size. */ 4201 /* Now scale lbearing and advance up to the pixel size. */
4146 factor = sfnt_div_fixed (pixel_size << 16, 4202 factor = sfnt_div_fixed (pixel_size, head->units_per_em);
4147 head->units_per_em << 16);
4148 4203
4149 /* Save them. */ 4204 /* Save them. */
4150 metrics->lbearing = sfnt_mul_fixed (lbearing << 16, factor); 4205 metrics->lbearing = sfnt_mul_fixed (lbearing << 16, factor);
@@ -5148,6 +5203,14 @@ struct sfnt_interpreter
5148 /* If non-NULL, function called before each instruction is 5203 /* If non-NULL, function called before each instruction is
5149 executed. */ 5204 executed. */
5150 void (*run_hook) (struct sfnt_interpreter *); 5205 void (*run_hook) (struct sfnt_interpreter *);
5206
5207 /* If non-NULL, function called before each stack element is
5208 pushed. */
5209 void (*push_hook) (struct sfnt_interpreter *, uint32_t);
5210
5211 /* If non-NULL, function called before each stack element is
5212 popped. */
5213 void (*pop_hook) (struct sfnt_interpreter *, uint32_t);
5151#endif 5214#endif
5152}; 5215};
5153 5216
@@ -5239,8 +5302,28 @@ sfnt_mul_f2dot14 (sfnt_f2dot14 a, int32_t b)
5239#endif 5302#endif
5240} 5303}
5241 5304
5305#ifndef INT64_MAX
5306
5307/* Add the specified unsigned 32-bit N to the large integer
5308 INTEGER. */
5309
5310static void
5311sfnt_large_integer_add (struct sfnt_large_integer *integer,
5312 uint32_t n)
5313{
5314 struct sfnt_large_integer number;
5315
5316 number.low = integer->low + n;
5317 number.high = integer->high + (number.low
5318 < integer->low);
5319
5320 *integer = number;
5321}
5322
5323#endif
5324
5242/* Multiply the specified 26.6 fixed point number X by the specified 5325/* Multiply the specified 26.6 fixed point number X by the specified
5243 16.16 fixed point number Y. 5326 16.16 fixed point number Y with symmetric rounding.
5244 5327
5245 The 26.6 fixed point number must fit inside -32768 to 32767.ffff. 5328 The 26.6 fixed point number must fit inside -32768 to 32767.ffff.
5246 Value is otherwise undefined. */ 5329 Value is otherwise undefined. */
@@ -5248,10 +5331,44 @@ sfnt_mul_f2dot14 (sfnt_f2dot14 a, int32_t b)
5248static sfnt_f26dot6 5331static sfnt_f26dot6
5249sfnt_mul_f26dot6_fixed (sfnt_f26dot6 x, sfnt_fixed y) 5332sfnt_mul_f26dot6_fixed (sfnt_f26dot6 x, sfnt_fixed y)
5250{ 5333{
5251 sfnt_fixed result; 5334#ifdef INT64_MAX
5335 uint64_t product;
5336 int sign;
5252 5337
5253 result = sfnt_mul_fixed (y, x); 5338 sign = 1;
5254 return result; 5339
5340 if (x < 0)
5341 {
5342 x = -x;
5343 sign = -sign;
5344 }
5345
5346 if (y < 0)
5347 {
5348 y = -y;
5349 sign = -sign;
5350 }
5351
5352 product = (uint64_t) y * (uint64_t) x;
5353
5354 /* This can be done quickly with int64_t. */
5355 return ((int64_t) (product + 32676) / (int64_t) 65536) * sign;
5356#else
5357 struct sfnt_large_integer temp;
5358 int sign;
5359
5360 sign = 1;
5361
5362 if (x < 0)
5363 sign = -sign;
5364
5365 if (y < 0)
5366 sign = -sign;
5367
5368 sfnt_multiply_divide_1 (abs (x), abs (y), &temp);
5369 sfnt_large_integer_add (&temp, 32676);
5370 return sfnt_multiply_divide_2 (&temp, 65536) * sign;
5371#endif
5255} 5372}
5256 5373
5257/* Return the floor of the specified 26.6 fixed point value X. */ 5374/* Return the floor of the specified 26.6 fixed point value X. */
@@ -5411,6 +5528,8 @@ sfnt_make_interpreter (struct sfnt_maxp_table *maxp,
5411 5528
5412#ifdef TEST 5529#ifdef TEST
5413 interpreter->run_hook = NULL; 5530 interpreter->run_hook = NULL;
5531 interpreter->push_hook = NULL;
5532 interpreter->pop_hook = NULL;
5414#endif 5533#endif
5415 5534
5416 /* Fill in pointers and default values. */ 5535 /* Fill in pointers and default values. */
@@ -5461,8 +5580,7 @@ sfnt_make_interpreter (struct sfnt_maxp_table *maxp,
5461 /* Now compute the scale. Then, scale up the control value table 5580 /* Now compute the scale. Then, scale up the control value table
5462 values. */ 5581 values. */
5463 interpreter->scale 5582 interpreter->scale
5464 = sfnt_div_fixed (pixel_size * 64, 5583 = sfnt_div_fixed (pixel_size, head->units_per_em);
5465 head->units_per_em * 64);
5466 5584
5467 /* Set the PPEM. */ 5585 /* Set the PPEM. */
5468 interpreter->ppem = pixel_size; 5586 interpreter->ppem = pixel_size;
@@ -5537,6 +5655,13 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
5537#define MOVE(a, b, n) \ 5655#define MOVE(a, b, n) \
5538 memmove (a, b, (n) * sizeof (uint32_t)) 5656 memmove (a, b, (n) * sizeof (uint32_t))
5539 5657
5658#define CHECK_STACK_ELEMENTS(n) \
5659 { \
5660 if ((interpreter->SP \
5661 - interpreter->stack) < n) \
5662 TRAP ("stack underflow"); \
5663 }
5664
5540#define CHECK_PREP() \ 5665#define CHECK_PREP() \
5541 if (!is_prep) \ 5666 if (!is_prep) \
5542 TRAP ("instruction executed not valid" \ 5667 TRAP ("instruction executed not valid" \
@@ -5555,26 +5680,88 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
5555 5680
5556/* Register, alu and logic instructions. */ 5681/* Register, alu and logic instructions. */
5557 5682
5683#ifndef TEST
5684
5558#define POP() \ 5685#define POP() \
5559 (interpreter->SP == interpreter->stack \ 5686 (interpreter->SP == interpreter->stack \
5560 ? (TRAP ("stack underflow"), 0) \ 5687 ? (TRAP ("stack underflow"), 0) \
5561 : (*(--interpreter->SP))) 5688 : (*(--interpreter->SP)))
5562 5689
5690#define POP_UNCHECKED() (*(--interpreter->SP))
5691
5692#else
5693
5694#define POP() \
5695 (interpreter->SP == interpreter->stack \
5696 ? (TRAP ("stack underflow"), 0) \
5697 : ({uint32_t _value; \
5698 _value = *(--interpreter->SP); \
5699 if (interpreter->pop_hook) \
5700 interpreter->pop_hook (interpreter, \
5701 _value); \
5702 _value;}))
5703
5704#define POP_UNCHECKED() \
5705 ({uint32_t _value; \
5706 _value = *(--interpreter->SP); \
5707 if (interpreter->pop_hook) \
5708 interpreter->pop_hook (interpreter, \
5709 _value); \
5710 _value;})
5711
5712#endif
5713
5563#define LOOK() \ 5714#define LOOK() \
5564 (interpreter->SP == interpreter->stack \ 5715 (interpreter->SP == interpreter->stack \
5565 ? (TRAP ("stack underflow"), 0) \ 5716 ? (TRAP ("stack underflow"), 0) \
5566 : *(interpreter->SP - 1)) 5717 : *(interpreter->SP - 1))
5567 5718
5719#ifndef TEST
5720
5721#define PUSH(value) \
5722 { \
5723 if ((char *) (interpreter->SP + 1) \
5724 > (char *) interpreter->twilight_x) \
5725 TRAP ("stack overflow"); \
5726 \
5727 *interpreter->SP = (value); \
5728 interpreter->SP++; \
5729 }
5730
5731#define PUSH_UNCHECKED(value) \
5732 { \
5733 *interpreter->SP = (value); \
5734 interpreter->SP++; \
5735 }
5736
5737#else
5738
5568#define PUSH(value) \ 5739#define PUSH(value) \
5569 { \ 5740 { \
5570 if ((char *) (interpreter->SP + 1) \ 5741 if ((char *) (interpreter->SP + 1) \
5571 > (char *) interpreter->twilight_x) \ 5742 > (char *) interpreter->twilight_x) \
5572 TRAP ("stack overflow"); \ 5743 TRAP ("stack overflow"); \
5573 \ 5744 \
5745 if (interpreter->push_hook) \
5746 interpreter->push_hook (interpreter, \
5747 value); \
5748 \
5574 *interpreter->SP = value; \ 5749 *interpreter->SP = value; \
5575 interpreter->SP++; \ 5750 interpreter->SP++; \
5576 } 5751 }
5577 5752
5753#define PUSH_UNCHECKED(value) \
5754 { \
5755 if (interpreter->push_hook) \
5756 interpreter->push_hook (interpreter, \
5757 value); \
5758 \
5759 *interpreter->SP = value; \
5760 interpreter->SP++; \
5761 }
5762
5763#endif
5764
5578#define PUSH2(high, low) \ 5765#define PUSH2(high, low) \
5579 { \ 5766 { \
5580 PUSH ((int16_t) ((int8_t) high) << 8 \ 5767 PUSH ((int16_t) ((int8_t) high) << 8 \
@@ -5746,8 +5933,8 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
5746 a = POP (); \ 5933 a = POP (); \
5747 b = POP (); \ 5934 b = POP (); \
5748 \ 5935 \
5749 PUSH (a); \ 5936 PUSH_UNCHECKED (a); \
5750 PUSH (b); \ 5937 PUSH_UNCHECKED (b); \
5751 } 5938 }
5752 5939
5753#define DEPTH() \ 5940#define DEPTH() \
@@ -5768,7 +5955,8 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
5768 if (index <= 0 || index > STACKSIZE ()) \ 5955 if (index <= 0 || index > STACKSIZE ()) \
5769 TRAP ("stack overflow"); \ 5956 TRAP ("stack overflow"); \
5770 \ 5957 \
5771 PUSH (*(interpreter->SP - index)); \ 5958 PUSH_UNCHECKED (*(interpreter->SP \
5959 - index)); \
5772 } 5960 }
5773 5961
5774#define MINDEX() \ 5962#define MINDEX() \
@@ -5934,14 +6122,15 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
5934 6122
5935#define RS() \ 6123#define RS() \
5936 { \ 6124 { \
5937 uint32_t address; \ 6125 uint32_t address, value; \
5938 \ 6126 \
5939 address = POP (); \ 6127 address = POP (); \
5940 \ 6128 \
5941 if (address >= interpreter->storage_size) \ 6129 if (address >= interpreter->storage_size) \
5942 TRAP ("invalid RS"); \ 6130 TRAP ("invalid RS"); \
5943 \ 6131 \
5944 PUSH (interpreter->storage[address]); \ 6132 value = interpreter->storage[address]; \
6133 PUSH_UNCHECKED (value); \
5945 } 6134 }
5946 6135
5947#define WCVTP() \ 6136#define WCVTP() \
@@ -5969,7 +6158,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
5969 TRAP ("out of bounds RCVT"); \ 6158 TRAP ("out of bounds RCVT"); \
5970 \ 6159 \
5971 value = interpreter->cvt[location]; \ 6160 value = interpreter->cvt[location]; \
5972 PUSH (value); \ 6161 PUSH_UNCHECKED (value); \
5973 } 6162 }
5974 6163
5975#define MPPEM() \ 6164#define MPPEM() \
@@ -6004,7 +6193,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6004 e2 = POP (); \ 6193 e2 = POP (); \
6005 e1 = POP (); \ 6194 e1 = POP (); \
6006 \ 6195 \
6007 PUSH (e1 < e2 ? 1 : 0); \ 6196 PUSH_UNCHECKED (e1 < e2 ? 1 : 0); \
6008 } 6197 }
6009 6198
6010#define LTEQ() \ 6199#define LTEQ() \
@@ -6014,7 +6203,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6014 e2 = POP (); \ 6203 e2 = POP (); \
6015 e1 = POP (); \ 6204 e1 = POP (); \
6016 \ 6205 \
6017 PUSH (e1 <= e2 ? 1 : 0); \ 6206 PUSH_UNCHECKED (e1 <= e2 ? 1 : 0); \
6018 } 6207 }
6019 6208
6020#define GT() \ 6209#define GT() \
@@ -6024,7 +6213,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6024 e2 = POP (); \ 6213 e2 = POP (); \
6025 e1 = POP (); \ 6214 e1 = POP (); \
6026 \ 6215 \
6027 PUSH (e1 > e2 ? 1 : 0); \ 6216 PUSH_UNCHECKED (e1 > e2 ? 1 : 0); \
6028 } 6217 }
6029 6218
6030#define GTEQ() \ 6219#define GTEQ() \
@@ -6034,7 +6223,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6034 e2 = POP (); \ 6223 e2 = POP (); \
6035 e1 = POP (); \ 6224 e1 = POP (); \
6036 \ 6225 \
6037 PUSH (e1 >= e2 ? 1 : 0); \ 6226 PUSH_UNCHECKED (e1 >= e2 ? 1 : 0); \
6038 } 6227 }
6039 6228
6040#define EQ() \ 6229#define EQ() \
@@ -6044,7 +6233,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6044 e1 = POP (); \ 6233 e1 = POP (); \
6045 e2 = POP (); \ 6234 e2 = POP (); \
6046 \ 6235 \
6047 PUSH (e1 == e2 ? 1 : 0); \ 6236 PUSH_UNCHECKED (e1 == e2 ? 1 : 0); \
6048 } 6237 }
6049 6238
6050#define NEQ() \ 6239#define NEQ() \
@@ -6054,7 +6243,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6054 e1 = POP (); \ 6243 e1 = POP (); \
6055 e2 = POP (); \ 6244 e2 = POP (); \
6056 \ 6245 \
6057 PUSH (e1 != e2 ? 1 : 0); \ 6246 PUSH_UNCHECKED (e1 != e2 ? 1 : 0); \
6058 } 6247 }
6059 6248
6060#define ODD() \ 6249#define ODD() \
@@ -6073,6 +6262,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6073#define EVEN() \ 6262#define EVEN() \
6074 { \ 6263 { \
6075 sfnt_f26dot6 e1, result; \ 6264 sfnt_f26dot6 e1, result; \
6265 uint32_t value; \
6076 \ 6266 \
6077 e1 = POP (); \ 6267 e1 = POP (); \
6078 result = abs (e1); \ 6268 result = abs (e1); \
@@ -6080,7 +6270,8 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6080 result \ 6270 result \
6081 = interpreter->state.round (result, \ 6271 = interpreter->state.round (result, \
6082 interpreter); \ 6272 interpreter); \
6083 PUSH (((result & 127) == 64) ? 0 : 1); \ 6273 value = ((result & 127) == 64) ? 0 : 1; \
6274 PUSH_UNCHECKED (value); \
6084 } 6275 }
6085 6276
6086#define IF() \ 6277#define IF() \
@@ -6104,7 +6295,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6104 e1 = POP (); \ 6295 e1 = POP (); \
6105 e2 = POP (); \ 6296 e2 = POP (); \
6106 \ 6297 \
6107 PUSH (e1 && e2 ? 1 : 0); \ 6298 PUSH_UNCHECKED (e1 && e2 ? 1 : 0); \
6108 } 6299 }
6109 6300
6110#define OR() \ 6301#define OR() \
@@ -6114,7 +6305,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6114 e1 = POP (); \ 6305 e1 = POP (); \
6115 e2 = POP (); \ 6306 e2 = POP (); \
6116 \ 6307 \
6117 PUSH (e1 || e2 ? 1 : 0); \ 6308 PUSH_UNCHECKED (e1 || e2 ? 1 : 0); \
6118 } 6309 }
6119 6310
6120#define NOT() \ 6311#define NOT() \
@@ -6123,7 +6314,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6123 \ 6314 \
6124 e1 = POP (); \ 6315 e1 = POP (); \
6125 \ 6316 \
6126 PUSH (!e1 ? 1 : 0); \ 6317 PUSH_UNCHECKED (!e1 ? 1 : 0); \
6127 } 6318 }
6128 6319
6129#define SDB() \ 6320#define SDB() \
@@ -6154,7 +6345,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6154 n1 = POP (); \ 6345 n1 = POP (); \
6155 n2 = POP (); \ 6346 n2 = POP (); \
6156 \ 6347 \
6157 PUSH (sfnt_add (n1, n2)); \ 6348 PUSH_UNCHECKED (sfnt_add (n1, n2)); \
6158 } 6349 }
6159 6350
6160#define SUB() \ 6351#define SUB() \
@@ -6164,7 +6355,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6164 n2 = POP (); \ 6355 n2 = POP (); \
6165 n1 = POP (); \ 6356 n1 = POP (); \
6166 \ 6357 \
6167 PUSH (sfnt_sub (n1, n2)); \ 6358 PUSH_UNCHECKED (sfnt_sub (n1, n2)); \
6168 } 6359 }
6169 6360
6170#define DIV() \ 6361#define DIV() \
@@ -6177,7 +6368,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6177 if (!n2) \ 6368 if (!n2) \
6178 TRAP ("DIV by 0"); \ 6369 TRAP ("DIV by 0"); \
6179 \ 6370 \
6180 PUSH (sfnt_div_f26dot6 (n1, n2)); \ 6371 PUSH_UNCHECKED (sfnt_div_f26dot6 (n1, n2)); \
6181 } 6372 }
6182 6373
6183#define MUL() \ 6374#define MUL() \
@@ -6187,7 +6378,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6187 n2 = POP (); \ 6378 n2 = POP (); \
6188 n1 = POP (); \ 6379 n1 = POP (); \
6189 \ 6380 \
6190 PUSH (sfnt_mul_f26dot6 (n2, n1)); \ 6381 PUSH_UNCHECKED (sfnt_mul_f26dot6 (n2, n1)); \
6191 } 6382 }
6192 6383
6193#define ABS() \ 6384#define ABS() \
@@ -6196,10 +6387,10 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6196 \ 6387 \
6197 n = POP (); \ 6388 n = POP (); \
6198 \ 6389 \
6199 if (n == INT_MIN) \ 6390 if (n == INT32_MIN) \
6200 PUSH (0) \ 6391 PUSH_UNCHECKED (0) \
6201 else \ 6392 else \
6202 PUSH (n < 0 ? -n : n) \ 6393 PUSH_UNCHECKED (n < 0 ? -n : n) \
6203 } 6394 }
6204 6395
6205#define NEG() \ 6396#define NEG() \
@@ -6208,10 +6399,10 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6208 \ 6399 \
6209 n = POP (); \ 6400 n = POP (); \
6210 \ 6401 \
6211 if (n == INT_MIN) \ 6402 if (n == INT32_MIN) \
6212 PUSH (0) \ 6403 PUSH_UNCHECKED (0) \
6213 else \ 6404 else \
6214 PUSH (-n) \ 6405 PUSH_UNCHECKED (-n) \
6215 } 6406 }
6216 6407
6217#define FLOOR() \ 6408#define FLOOR() \
@@ -6219,7 +6410,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6219 sfnt_f26dot6 n; \ 6410 sfnt_f26dot6 n; \
6220 \ 6411 \
6221 n = POP (); \ 6412 n = POP (); \
6222 PUSH (sfnt_floor_f26dot6 (n)); \ 6413 PUSH_UNCHECKED (sfnt_floor_f26dot6 (n)); \
6223 } 6414 }
6224 6415
6225#define CEILING() \ 6416#define CEILING() \
@@ -6227,7 +6418,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6227 sfnt_f26dot6 n; \ 6418 sfnt_f26dot6 n; \
6228 \ 6419 \
6229 n = POP (); \ 6420 n = POP (); \
6230 PUSH (sfnt_ceil_f26dot6 (n)); \ 6421 PUSH_UNCHECKED (sfnt_ceil_f26dot6 (n)); \
6231 } 6422 }
6232 6423
6233#define WCVTF() \ 6424#define WCVTF() \
@@ -6306,9 +6497,9 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6306 selector = POP (); \ 6497 selector = POP (); \
6307 \ 6498 \
6308 if (selector & 1) \ 6499 if (selector & 1) \
6309 PUSH (2) \ 6500 PUSH_UNCHECKED (2) \
6310 else \ 6501 else \
6311 PUSH (0) \ 6502 PUSH_UNCHECKED (0) \
6312 } 6503 }
6313 6504
6314#define IDEF() \ 6505#define IDEF() \
@@ -6324,13 +6515,15 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6324 { \ 6515 { \
6325 uint32_t a, b, c; \ 6516 uint32_t a, b, c; \
6326 \ 6517 \
6327 a = POP (); \ 6518 CHECK_STACK_ELEMENTS (3); \
6328 b = POP (); \
6329 c = POP (); \
6330 \ 6519 \
6331 PUSH (b); \ 6520 a = POP_UNCHECKED (); \
6332 PUSH (a); \ 6521 b = POP_UNCHECKED (); \
6333 PUSH (c); \ 6522 c = POP_UNCHECKED (); \
6523 \
6524 PUSH_UNCHECKED (b); \
6525 PUSH_UNCHECKED (a); \
6526 PUSH_UNCHECKED (c); \
6334 } 6527 }
6335 6528
6336#define _MAX() \ 6529#define _MAX() \
@@ -6340,7 +6533,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6340 e1 = POP (); \ 6533 e1 = POP (); \
6341 e2 = POP (); \ 6534 e2 = POP (); \
6342 \ 6535 \
6343 PUSH (MAX (e1, e2)); \ 6536 PUSH_UNCHECKED (MAX (e1, e2)); \
6344 } 6537 }
6345 6538
6346#define _MIN() \ 6539#define _MIN() \
@@ -6350,7 +6543,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6350 e1 = POP (); \ 6543 e1 = POP (); \
6351 e2 = POP (); \ 6544 e2 = POP (); \
6352 \ 6545 \
6353 PUSH (MIN (e1, e2)); \ 6546 PUSH_UNCHECKED (MIN (e1, e2)); \
6354 } 6547 }
6355 6548
6356#define SCANTYPE() \ 6549#define SCANTYPE() \
@@ -6427,7 +6620,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6427 result \ 6620 result \
6428 = interpreter->state.round (result, \ 6621 = interpreter->state.round (result, \
6429 interpreter); \ 6622 interpreter); \
6430 PUSH (n < 0 ? -result : result); \ 6623 PUSH_UNCHECKED (n < 0 ? -result : result); \
6431 } 6624 }
6432 6625
6433#define NROUND() \ 6626#define NROUND() \
@@ -6435,7 +6628,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6435 sfnt_f26dot6 n; \ 6628 sfnt_f26dot6 n; \
6436 \ 6629 \
6437 n = POP (); \ 6630 n = POP (); \
6438 PUSH (n); \ 6631 PUSH_UNCHECKED (n); \
6439 } 6632 }
6440 6633
6441#define ROFF() \ 6634#define ROFF() \
@@ -6904,7 +7097,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6904 else \ 7097 else \
6905 value = PROJECT (x, y); \ 7098 value = PROJECT (x, y); \
6906 \ 7099 \
6907 PUSH (value); \ 7100 PUSH_UNCHECKED (value); \
6908 } 7101 }
6909 7102
6910#define SCFS() \ 7103#define SCFS() \
@@ -6923,14 +7116,14 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6923 uint32_t p1, p2; \ 7116 uint32_t p1, p2; \
6924 sfnt_f26dot6 distance; \ 7117 sfnt_f26dot6 distance; \
6925 \ 7118 \
6926 p1 = POP (); \
6927 p2 = POP (); \ 7119 p2 = POP (); \
7120 p1 = POP (); \
6928 \ 7121 \
6929 distance \ 7122 distance \
6930 = sfnt_measure_distance (interpreter, \ 7123 = sfnt_measure_distance (interpreter, \
6931 p1, p2, \ 7124 p1, p2, \
6932 opcode); \ 7125 opcode); \
6933 PUSH (distance); \ 7126 PUSH_UNCHECKED (distance); \
6934 } 7127 }
6935 7128
6936#define FLIPPT() \ 7129#define FLIPPT() \
@@ -7405,6 +7598,8 @@ sfnt_move_zp2 (struct sfnt_interpreter *interpreter, uint32_t point,
7405/* Move N points from the specified POINT in INTERPRETER's glyph zone 7598/* Move N points from the specified POINT in INTERPRETER's glyph zone
7406 by the given DISTANCE along the freedom vector. 7599 by the given DISTANCE along the freedom vector.
7407 7600
7601 Do not touch the points that are moved.
7602
7408 No checking is done to ensure that POINT lies inside the zone, or 7603 No checking is done to ensure that POINT lies inside the zone, or
7409 even that the zone exists at all. */ 7604 even that the zone exists at all. */
7410 7605
@@ -7414,13 +7609,14 @@ sfnt_move_glyph_zone (struct sfnt_interpreter *interpreter, uint32_t point,
7414{ 7609{
7415 interpreter->state.move (&interpreter->glyph_zone->x_current[point], 7610 interpreter->state.move (&interpreter->glyph_zone->x_current[point],
7416 &interpreter->glyph_zone->y_current[point], 7611 &interpreter->glyph_zone->y_current[point],
7417 n, interpreter, distance, 7612 n, interpreter, distance, NULL);
7418 &interpreter->glyph_zone->flags[point]);
7419} 7613}
7420 7614
7421/* Move N points from the specified POINT in INTERPRETER's twilight 7615/* Move N points from the specified POINT in INTERPRETER's twilight
7422 zone by the given DISTANCE along the freedom vector. 7616 zone by the given DISTANCE along the freedom vector.
7423 7617
7618 Do not touch the points that are moved.
7619
7424 No checking is done to ensure that POINT lies inside the zone, or 7620 No checking is done to ensure that POINT lies inside the zone, or
7425 even that the zone exists at all. */ 7621 even that the zone exists at all. */
7426 7622
@@ -7436,6 +7632,8 @@ sfnt_move_twilight_zone (struct sfnt_interpreter *interpreter, uint32_t point,
7436/* Move the point P in the zone pointed to by the ZP2 register in 7632/* Move the point P in the zone pointed to by the ZP2 register in
7437 INTERPRETER's graphics state by DX, and DY. 7633 INTERPRETER's graphics state by DX, and DY.
7438 7634
7635 Touch the point P in the directions of the movement.
7636
7439 Check that P is valid; if not, trap. Else, perform the move 7637 Check that P is valid; if not, trap. Else, perform the move
7440 directly without converting it from the projection vector or to the 7638 directly without converting it from the projection vector or to the
7441 freedom vector. */ 7639 freedom vector. */
@@ -7464,6 +7662,12 @@ sfnt_direct_move_zp2 (struct sfnt_interpreter *interpreter, uint32_t p,
7464 = sfnt_add (interpreter->glyph_zone->x_current[p], dx); 7662 = sfnt_add (interpreter->glyph_zone->x_current[p], dx);
7465 interpreter->glyph_zone->y_current[p] 7663 interpreter->glyph_zone->y_current[p]
7466 = sfnt_add (interpreter->glyph_zone->y_current[p], dy); 7664 = sfnt_add (interpreter->glyph_zone->y_current[p], dy);
7665
7666 if (dx)
7667 interpreter->glyph_zone->flags[p] |= SFNT_POINT_TOUCHED_X;
7668
7669 if (dy)
7670 interpreter->glyph_zone->flags[p] |= SFNT_POINT_TOUCHED_Y;
7467 } 7671 }
7468} 7672}
7469 7673
@@ -7578,10 +7782,8 @@ sfnt_interpret_scfs (struct sfnt_interpreter *interpreter,
7578 7782
7579 if (!interpreter->state.zp2) 7783 if (!interpreter->state.zp2)
7580 { 7784 {
7581 interpreter->twilight_original_x[p] 7785 interpreter->twilight_original_x[p] = interpreter->twilight_x[p];
7582 = interpreter->twilight_x[p]; 7786 interpreter->twilight_original_y[p] = interpreter->twilight_y[p];
7583 interpreter->twilight_original_y[p]
7584 = interpreter->twilight_y[p];
7585 } 7787 }
7586} 7788}
7587 7789
@@ -10974,8 +11176,9 @@ sfnt_interpret_simple_glyph (struct sfnt_glyph *glyph,
10974 /* Load the fword. */ 11176 /* Load the fword. */
10975 tem = glyph->simple->y_coordinates[i]; 11177 tem = glyph->simple->y_coordinates[i];
10976 11178
10977 /* Scale that fword. */ 11179 /* Scale that fword. Make sure not to round Y, as this could
10978 tem = sfnt_mul_f26dot6_fixed (tem * 64, interpreter->scale); 11180 lead to Y spilling over to the next line. */
11181 tem = sfnt_mul_fixed (tem * 64, interpreter->scale);
10979 11182
10980 /* Set y_points and y_current. */ 11183 /* Set y_points and y_current. */
10981 zone->y_points[i] = tem; 11184 zone->y_points[i] = tem;
@@ -11124,19 +11327,20 @@ static void
11124sfnt_test_span (struct sfnt_edge *edge, sfnt_fixed y, 11327sfnt_test_span (struct sfnt_edge *edge, sfnt_fixed y,
11125 void *dcontext) 11328 void *dcontext)
11126{ 11329{
11127#if 0 11330#if 1
11128 printf ("/* span at %g */\n", sfnt_coerce_fixed (y)); 11331 printf ("/* span at %g */\n", sfnt_coerce_fixed (y));
11129 for (; edge; edge = edge->next) 11332 for (; edge; edge = edge->next)
11130 { 11333 {
11131 if (y >= edge->bottom && y < edge->top) 11334 if (y >= edge->bottom && y < edge->top)
11132 printf ("ctx.fillRect (%g, %g, 1, 1); " 11335 printf ("ctx.fillRect (%g, %g, 1, 1); "
11133 "/* %g top: %g bot: %g stepx: %g */\n", 11336 "/* %g top: %g bot: %g stepx: %g winding: %d */\n",
11134 sfnt_coerce_fixed (edge->x), 11337 sfnt_coerce_fixed (edge->x),
11135 sfnt_coerce_fixed (sfnt_test_max - y), 11338 sfnt_coerce_fixed (sfnt_test_max - y),
11136 sfnt_coerce_fixed (y), 11339 sfnt_coerce_fixed (y),
11137 sfnt_coerce_fixed (edge->bottom), 11340 sfnt_coerce_fixed (edge->bottom),
11138 sfnt_coerce_fixed (edge->top), 11341 sfnt_coerce_fixed (edge->top),
11139 sfnt_coerce_fixed (edge->step_x)); 11342 sfnt_coerce_fixed (edge->step_x),
11343 edge->winding);
11140 } 11344 }
11141#elif 0 11345#elif 0
11142 int winding; 11346 int winding;
@@ -11171,6 +11375,74 @@ sfnt_test_edge_ignore (struct sfnt_edge *edges, size_t num_edges,
11171 11375
11172} 11376}
11173 11377
11378/* The same debugger stuff is used here. */
11379static void sfnt_setup_debugger (void);
11380
11381/* The debugger's X display. */
11382static Display *display;
11383
11384/* The debugger window. */
11385static Window window;
11386
11387/* The GC. */
11388static GC point_gc, background_gc;
11389
11390static void
11391sfnt_test_edges (struct sfnt_edge *edges, size_t num_edges)
11392{
11393 static sfnt_fixed y;
11394 size_t i;
11395
11396 for (i = 0; i < num_edges; ++i)
11397 {
11398 if (y >= edges[i].bottom && y < edges[i].top)
11399 {
11400 XDrawPoint (display, window, point_gc,
11401 edges[i].x / 65536, 100 - (y / 65536));
11402 printf ("sfnt_test_edges: %d %d\n",
11403 edges[i].x / 65536, 100 - (y / 65536));
11404 }
11405 }
11406
11407 y += SFNT_POLY_STEP;
11408
11409 for (i = 0; i < num_edges; ++i)
11410 sfnt_step_edge (&edges[i]);
11411}
11412
11413static void
11414sfnt_debug_edges (struct sfnt_edge *edges, size_t num_edges)
11415{
11416 XEvent event;
11417
11418 sfnt_setup_debugger ();
11419
11420 while (true)
11421 {
11422 XNextEvent (display, &event);
11423
11424 switch (event.type)
11425 {
11426 case KeyPress:
11427 XDestroyWindow (display, window);
11428 XCloseDisplay (display);
11429 exit (0);
11430 break;
11431
11432 case Expose:
11433
11434 while (true)
11435 {
11436 sfnt_test_edges (edges, num_edges);
11437 XFlush (display);
11438 usleep (50000);
11439 }
11440
11441 break;
11442 }
11443 }
11444}
11445
11174static void 11446static void
11175sfnt_test_edge (struct sfnt_edge *edges, size_t num_edges, 11447sfnt_test_edge (struct sfnt_edge *edges, size_t num_edges,
11176 void *dcontext) 11448 void *dcontext)
@@ -11182,14 +11454,13 @@ sfnt_test_edge (struct sfnt_edge *edges, size_t num_edges,
11182 for (i = 0; i < num_edges; ++i) 11454 for (i = 0; i < num_edges; ++i)
11183 { 11455 {
11184 printf ("/* edge x, top, bot: %g, %g - %g. winding: %d */\n" 11456 printf ("/* edge x, top, bot: %g, %g - %g. winding: %d */\n"
11185 "/* edge step_x: %g, source_x: %g (%d) */\n", 11457 "/* edge step_x: %g, sign: %d */\n",
11186 sfnt_coerce_fixed (edges[i].x), 11458 sfnt_coerce_fixed (edges[i].x),
11187 sfnt_coerce_fixed (edges[i].top), 11459 sfnt_coerce_fixed (edges[i].top),
11188 sfnt_coerce_fixed (edges[i].bottom), 11460 sfnt_coerce_fixed (edges[i].bottom),
11189 edges[i].winding, 11461 edges[i].winding,
11190 sfnt_coerce_fixed (edges[i].step_x), 11462 sfnt_coerce_fixed (edges[i].step_x),
11191 sfnt_coerce_fixed (edges[i].source_x), 11463 edges[i].signed_step);
11192 edges[i].source_x);
11193#ifdef TEST_VERTEX 11464#ifdef TEST_VERTEX
11194 printf ("ctx.fillRect (%g, %g, 1, 1);\n", 11465 printf ("ctx.fillRect (%g, %g, 1, 1);\n",
11195 sfnt_coerce_fixed (edges[i].x), 11466 sfnt_coerce_fixed (edges[i].x),
@@ -11203,12 +11474,134 @@ sfnt_test_edge (struct sfnt_edge *edges, size_t num_edges,
11203#endif 11474#endif
11204 } 11475 }
11205 11476
11477 if (getenv ("SFNT_DEBUG_STEP"))
11478 {
11479 if (!fork ())
11480 sfnt_debug_edges (edges, num_edges);
11481 }
11482
11206 printf ("==end of edges==\n"); 11483 printf ("==end of edges==\n");
11207 11484
11208 sfnt_poly_edges (edges, num_edges, sfnt_test_span, NULL); 11485 sfnt_poly_edges (edges, num_edges, sfnt_test_span, NULL);
11209} 11486}
11210 11487
11211static void 11488static void
11489sfnt_x_raster (struct sfnt_raster *raster)
11490{
11491 Display *display;
11492 Window window;
11493 Pixmap pixmap;
11494 Picture glyph, drawable, solid;
11495 int event_base, error_base;
11496 int major, minor, *depths, count;
11497 XRenderPictFormat *format, *glyph_format;
11498 Visual *visual;
11499 XImage image;
11500 GC gc;
11501 XGCValues gcvalues;
11502 XEvent event;
11503 XRenderColor white, black;
11504 int i;
11505
11506 display = XOpenDisplay (NULL);
11507
11508 if (!display)
11509 exit (0);
11510
11511 if (!XRenderQueryExtension (display, &event_base, &error_base)
11512 || !XRenderQueryVersion (display, &major, &minor))
11513 exit (0);
11514
11515 if (major == 0 && minor < 10)
11516 exit (0);
11517
11518 window = XCreateSimpleWindow (display, DefaultRootWindow (display),
11519 0, 0, 40, 40, 0, 0,
11520 WhitePixel (display,
11521 DefaultScreen (display)));
11522 XSelectInput (display, window, ExposureMask);
11523 XMapWindow (display, window);
11524
11525 visual = DefaultVisual (display, DefaultScreen (display));
11526 format = XRenderFindVisualFormat (display, visual);
11527
11528 if (!format)
11529 exit (0);
11530
11531 glyph_format = XRenderFindStandardFormat (display, PictStandardA8);
11532 depths = XListDepths (display, DefaultScreen (display), &count);
11533
11534 for (i = 0; i < count; ++i)
11535 {
11536 if (depths[i] == 8)
11537 goto depth_found;
11538 }
11539
11540 exit (0);
11541
11542 depth_found:
11543
11544 XFree (depths);
11545 pixmap = XCreatePixmap (display, DefaultRootWindow (display),
11546 raster->width, raster->height, 8);
11547
11548 /* Upload the raster. */
11549 image.width = raster->width;
11550 image.height = raster->height;
11551 image.xoffset = 0;
11552 image.format = ZPixmap;
11553 image.data = (char *) raster->cells;
11554 image.byte_order = MSBFirst;
11555 image.bitmap_unit = 8;
11556 image.bitmap_bit_order = LSBFirst;
11557 image.bitmap_pad = SFNT_POLY_ALIGNMENT * 8;
11558 image.depth = 8;
11559 image.bytes_per_line = raster->stride;
11560 image.bits_per_pixel = 8;
11561 image.red_mask = 0;
11562 image.green_mask = 0;
11563 image.blue_mask = 0;
11564
11565 if (!XInitImage (&image))
11566 abort ();
11567
11568 gc = XCreateGC (display, pixmap, 0, &gcvalues);
11569 XPutImage (display, pixmap, gc, &image,
11570 0, 0, 0, 0, image.width, image.height);
11571
11572 drawable = XRenderCreatePicture (display, window, format,
11573 0, NULL);
11574 glyph = XRenderCreatePicture (display, pixmap, glyph_format,
11575 0, NULL);
11576 memset (&black, 0, sizeof black);
11577 black.alpha = 65535;
11578
11579 solid = XRenderCreateSolidFill (display, &black);
11580
11581 while (true)
11582 {
11583 XNextEvent (display, &event);
11584
11585 if (event.type == Expose)
11586 {
11587 white.red = 65535;
11588 white.green = 65535;
11589 white.blue = 65535;
11590 white.alpha = 65535;
11591
11592 /* Clear the background. */
11593 XRenderFillRectangle (display, PictOpSrc, drawable,
11594 &white, 0, 0, 65535, 65535);
11595
11596 /* Draw the solid fill with the glyph as clip mask. */
11597 XRenderComposite (display, PictOpOver, solid, glyph,
11598 drawable, 0, 0, 0, 0, 0, 0,
11599 raster->width, raster->height);
11600 }
11601 }
11602}
11603
11604static void
11212sfnt_test_raster (struct sfnt_raster *raster) 11605sfnt_test_raster (struct sfnt_raster *raster)
11213{ 11606{
11214 int x, y; 11607 int x, y;
@@ -11219,6 +11612,12 @@ sfnt_test_raster (struct sfnt_raster *raster)
11219 printf ("%3d ", (int) raster->cells[y * raster->stride + x]); 11612 printf ("%3d ", (int) raster->cells[y * raster->stride + x]);
11220 puts (""); 11613 puts ("");
11221 } 11614 }
11615
11616 if (getenv ("SFNT_X"))
11617 {
11618 if (!fork ())
11619 sfnt_x_raster (raster);
11620 }
11222} 11621}
11223 11622
11224 11623
@@ -12060,7 +12459,7 @@ static struct sfnt_generic_test_args wcvtp_test_args =
12060 12459
12061static struct sfnt_generic_test_args rcvt_test_args = 12460static struct sfnt_generic_test_args rcvt_test_args =
12062 { 12461 {
12063 (uint32_t []) { 135, }, 12462 (uint32_t []) { 136, },
12064 1, 12463 1,
12065 true, 12464 true,
12066 5, 12465 5,
@@ -12309,8 +12708,8 @@ static struct sfnt_generic_test_args jrof_test_args =
12309 12708
12310static struct sfnt_generic_test_args deltac1_test_args = 12709static struct sfnt_generic_test_args deltac1_test_args =
12311 { 12710 {
12312 (uint32_t []) { ((50 * 17 * 65535 / 800) >> 10) + 8, 12711 (uint32_t []) { ((((50 * 17 * 65535) + 32767) / 800) >> 10) + 8,
12313 ((50 * 17 * 65535 / 800) >> 10) + 8, }, 12712 ((((50 * 17 * 65535) + 32767) / 800) >> 10) + 8, },
12314 2, 12713 2,
12315 false, 12714 false,
12316 22, 12715 22,
@@ -12318,8 +12717,8 @@ static struct sfnt_generic_test_args deltac1_test_args =
12318 12717
12319static struct sfnt_generic_test_args deltac2_test_args = 12718static struct sfnt_generic_test_args deltac2_test_args =
12320 { 12719 {
12321 (uint32_t []) { ((50 * 17 * 65535 / 800) >> 10) + 8, 12720 (uint32_t []) { ((((50 * 17 * 65535) + 32767) / 800) >> 10) + 8,
12322 ((50 * 17 * 65535 / 800) >> 10) + 8, }, 12721 ((((50 * 17 * 65535) + 32767) / 800) >> 10) + 8, },
12323 2, 12722 2,
12324 false, 12723 false,
12325 22, 12724 22,
@@ -12327,8 +12726,8 @@ static struct sfnt_generic_test_args deltac2_test_args =
12327 12726
12328static struct sfnt_generic_test_args deltac3_test_args = 12727static struct sfnt_generic_test_args deltac3_test_args =
12329 { 12728 {
12330 (uint32_t []) { ((50 * 17 * 65535 / 800) >> 10) + 8, 12729 (uint32_t []) { ((((50 * 17 * 65535) + 32767) / 800) >> 10) + 8,
12331 ((50 * 17 * 65535 / 800) >> 10) + 8, }, 12730 ((((50 * 17 * 65535) + 32767) / 800) >> 10) + 8, },
12332 2, 12731 2,
12333 false, 12732 false,
12334 22, 12733 22,
@@ -12489,8 +12888,8 @@ static struct sfnt_generic_test_args roll_test_args =
12489 12888
12490static struct sfnt_generic_test_args roll_1_test_args = 12889static struct sfnt_generic_test_args roll_1_test_args =
12491 { 12890 {
12492 (uint32_t []) { }, 12891 (uint32_t []) { 1, 2, },
12493 0, 12892 2,
12494 true, 12893 true,
12495 3, 12894 3,
12496 }; 12895 };
@@ -13993,15 +14392,6 @@ static struct sfnt_interpreter_test all_tests[] =
13993 14392
13994/* Instruction debugger. */ 14393/* Instruction debugger. */
13995 14394
13996/* The debugger's X display. */
13997static Display *display;
13998
13999/* The debugger window. */
14000static Window window;
14001
14002/* The GC. */
14003static GC point_gc, background_gc;
14004
14005static void 14395static void
14006sfnt_setup_debugger (void) 14396sfnt_setup_debugger (void)
14007{ 14397{
@@ -14383,6 +14773,13 @@ sfnt_run_hook (struct sfnt_interpreter *interpreter)
14383 pid_t pid; 14773 pid_t pid;
14384 XEvent event; 14774 XEvent event;
14385 14775
14776#ifdef TEST_BREAK_AFTER
14777 static unsigned int instructions;
14778
14779 if (++instructions < TEST_BREAK_AFTER)
14780 return;
14781#endif
14782
14386 pid = fork (); 14783 pid = fork ();
14387 14784
14388 if (pid == 0) 14785 if (pid == 0)
@@ -14414,6 +14811,41 @@ sfnt_run_hook (struct sfnt_interpreter *interpreter)
14414 } 14811 }
14415} 14812}
14416 14813
14814static struct sfnt_prep_table *exec_prep;
14815static struct sfnt_fpgm_table *exec_fpgm;
14816
14817static const char *
14818sfnt_identify_instruction (struct sfnt_interpreter *interpreter)
14819{
14820 static char buffer[256];
14821 unsigned char *where;
14822
14823 where = interpreter->instructions + interpreter->IP;
14824
14825 if (exec_prep
14826 && where >= exec_prep->instructions
14827 && where < (exec_prep->instructions
14828 + exec_prep->num_instructions))
14829 {
14830 sprintf (buffer, "prep+%td",
14831 where - exec_prep->instructions);
14832 return buffer;
14833 }
14834
14835 if (exec_fpgm->instructions
14836 && where >= exec_fpgm->instructions
14837 && where < (exec_fpgm->instructions
14838 + exec_fpgm->num_instructions))
14839 {
14840 sprintf (buffer, "fpgm+%td",
14841 where - exec_fpgm->instructions);
14842 return buffer;
14843 }
14844
14845 sprintf (buffer, "IP+%td", where - interpreter->instructions);
14846 return buffer;
14847}
14848
14417static void 14849static void
14418sfnt_verbose (struct sfnt_interpreter *interpreter) 14850sfnt_verbose (struct sfnt_interpreter *interpreter)
14419{ 14851{
@@ -14421,6 +14853,8 @@ sfnt_verbose (struct sfnt_interpreter *interpreter)
14421 struct sfnt_glyph_outline *outline; 14853 struct sfnt_glyph_outline *outline;
14422 struct sfnt_raster *raster; 14854 struct sfnt_raster *raster;
14423 unsigned char opcode; 14855 unsigned char opcode;
14856 const char *name;
14857 static unsigned int instructions;
14424 14858
14425 /* Build a temporary outline containing the values of the 14859 /* Build a temporary outline containing the values of the
14426 interpreter's glyph zone. */ 14860 interpreter's glyph zone. */
@@ -14444,7 +14878,43 @@ sfnt_verbose (struct sfnt_interpreter *interpreter)
14444 xfree (raster); 14878 xfree (raster);
14445 14879
14446 opcode = interpreter->instructions[interpreter->IP]; 14880 opcode = interpreter->instructions[interpreter->IP];
14447 printf ("opcode: %s\n", sfnt_name_instruction (opcode)); 14881 printf ("opcode, number of instructions: %s %u\n",
14882 sfnt_name_instruction (opcode), instructions++);
14883 printf ("instruction: %s\n",
14884 sfnt_identify_instruction (interpreter));
14885
14886 if (interpreter->state.project
14887 == sfnt_project_onto_x_axis_vector)
14888 name = "X axis";
14889 else if (interpreter->state.project
14890 == sfnt_project_onto_y_axis_vector)
14891 name = "Y axis";
14892 else
14893 name = "Any";
14894
14895 printf ("projection function: %s\n", name);
14896}
14897
14898static void
14899sfnt_push_hook (struct sfnt_interpreter *interpreter,
14900 uint32_t value)
14901{
14902 int32_t alternate;
14903
14904 alternate = value;
14905
14906 fprintf (stderr, "--> %"PRIi32"\n", alternate);
14907}
14908
14909static void
14910sfnt_pop_hook (struct sfnt_interpreter *interpreter,
14911 uint32_t value)
14912{
14913 int32_t alternate;
14914
14915 alternate = value;
14916
14917 fprintf (stderr, "<<- %"PRIi32"\n", alternate);
14448} 14918}
14449 14919
14450 14920
@@ -14473,7 +14943,7 @@ sfnt_verbose (struct sfnt_interpreter *interpreter)
14473 -Wno-missing-field-initializers -Wno-override-init 14943 -Wno-missing-field-initializers -Wno-override-init
14474 -Wno-sign-compare -Wno-type-limits -Wno-unused-parameter 14944 -Wno-sign-compare -Wno-type-limits -Wno-unused-parameter
14475 -Wno-format-nonliteral -Wno-bidi-chars -g3 -O0 -DTEST sfnt.c -o 14945 -Wno-format-nonliteral -Wno-bidi-chars -g3 -O0 -DTEST sfnt.c -o
14476 sfnt ../lib/libgnu.a -lX11 14946 sfnt ../lib/libgnu.a -lX11 -lXrender
14477 14947
14478 after gnulib has been built. Then, run ./sfnt 14948 after gnulib has been built. Then, run ./sfnt
14479 /path/to/font.ttf. */ 14949 /path/to/font.ttf. */
@@ -14496,7 +14966,7 @@ main (int argc, char **argv)
14496 sfnt_glyph code; 14966 sfnt_glyph code;
14497 struct sfnt_test_dcontext dcontext; 14967 struct sfnt_test_dcontext dcontext;
14498 struct sfnt_glyph_outline *outline; 14968 struct sfnt_glyph_outline *outline;
14499 struct timespec start, end, sub, sub1, sub2; 14969 struct timespec start, end, sub, sub1, sub2, sub3;
14500 static struct sfnt_maxp_table *maxp; 14970 static struct sfnt_maxp_table *maxp;
14501 struct sfnt_raster *raster; 14971 struct sfnt_raster *raster;
14502 struct sfnt_hmtx_table *hmtx; 14972 struct sfnt_hmtx_table *hmtx;
@@ -14613,6 +15083,9 @@ main (int argc, char **argv)
14613 prep = sfnt_read_prep_table (fd, font); 15083 prep = sfnt_read_prep_table (fd, font);
14614 hmtx = NULL; 15084 hmtx = NULL;
14615 15085
15086 exec_prep = prep;
15087 exec_fpgm = fpgm;
15088
14616 if (head && maxp && maxp->version >= 0x00010000) 15089 if (head && maxp && maxp->version >= 0x00010000)
14617 { 15090 {
14618 fprintf (stderr, "creating interpreter\n" 15091 fprintf (stderr, "creating interpreter\n"
@@ -14696,7 +15169,7 @@ main (int argc, char **argv)
14696 "checksum_adjustment: \t\t%"PRIu32"\n" 15169 "checksum_adjustment: \t\t%"PRIu32"\n"
14697 "magic: \t\t\t\t%"PRIx32"\n" 15170 "magic: \t\t\t\t%"PRIx32"\n"
14698 "flags: \t\t\t\t%"PRIx16"\n" 15171 "flags: \t\t\t\t%"PRIx16"\n"
14699 "units_per_em: \t\t\t%"PRIx16"\n" 15172 "units_per_em: \t\t\t%"PRIu16"\n"
14700 "xmin, ymin, xmax, ymax: \t%d, %d, %d, %d\n" 15173 "xmin, ymin, xmax, ymax: \t%d, %d, %d, %d\n"
14701 "mac_style: \t\t\t%"PRIx16"\n" 15174 "mac_style: \t\t\t%"PRIx16"\n"
14702 "lowest_rec_ppem: \t\t%"PRIu16"\n" 15175 "lowest_rec_ppem: \t\t%"PRIu16"\n"
@@ -14848,7 +15321,7 @@ main (int argc, char **argv)
14848 15321
14849 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start); 15322 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start);
14850 15323
14851 for (i = 0; i < 400; ++i) 15324 for (i = 0; i < 1; ++i)
14852 { 15325 {
14853 xfree (raster); 15326 xfree (raster);
14854 raster = sfnt_raster_glyph_outline (outline); 15327 raster = sfnt_raster_glyph_outline (outline);
@@ -14886,7 +15359,11 @@ main (int argc, char **argv)
14886 if (getenv ("SFNT_DEBUG")) 15359 if (getenv ("SFNT_DEBUG"))
14887 interpreter->run_hook = sfnt_run_hook; 15360 interpreter->run_hook = sfnt_run_hook;
14888 else if (getenv ("SFNT_VERBOSE")) 15361 else if (getenv ("SFNT_VERBOSE"))
14889 interpreter->run_hook = sfnt_verbose; 15362 {
15363 interpreter->run_hook = sfnt_verbose;
15364 interpreter->push_hook = sfnt_push_hook;
15365 interpreter->pop_hook = sfnt_pop_hook;
15366 }
14890 15367
14891 if (glyph->simple 15368 if (glyph->simple
14892 && sfnt_lookup_glyph_metrics (code, -1, 15369 && sfnt_lookup_glyph_metrics (code, -1,
@@ -14896,8 +15373,11 @@ main (int argc, char **argv)
14896 { 15373 {
14897 printf ("interpreting glyph\n"); 15374 printf ("interpreting glyph\n");
14898 interpreter->state = state; 15375 interpreter->state = state;
15376 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start);
14899 trap = sfnt_interpret_simple_glyph (glyph, interpreter, 15377 trap = sfnt_interpret_simple_glyph (glyph, interpreter,
14900 &metrics, &value); 15378 &metrics, &value);
15379 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &end);
15380 sub3 = timespec_sub (end, start);
14901 15381
14902 if (trap) 15382 if (trap)
14903 printf ("**TRAP**: %s\n", trap); 15383 printf ("**TRAP**: %s\n", trap);
@@ -14920,6 +15400,9 @@ main (int argc, char **argv)
14920 } 15400 }
14921 } 15401 }
14922 } 15402 }
15403
15404 fprintf (stderr, "execution time: %lld sec %ld nsec\n",
15405 (long long) sub3.tv_sec, sub3.tv_nsec);
14923 } 15406 }
14924 15407
14925 interpreter->run_hook = NULL; 15408 interpreter->run_hook = NULL;
@@ -14931,7 +15414,7 @@ main (int argc, char **argv)
14931 printf ("time spent building edges: %lld sec %ld nsec\n", 15414 printf ("time spent building edges: %lld sec %ld nsec\n",
14932 (long long) sub1.tv_sec, sub1.tv_nsec); 15415 (long long) sub1.tv_sec, sub1.tv_nsec);
14933 printf ("time spent rasterizing: %lld sec %ld nsec\n", 15416 printf ("time spent rasterizing: %lld sec %ld nsec\n",
14934 (long long) sub2.tv_sec / 400, sub2.tv_nsec / 400); 15417 (long long) sub2.tv_sec / 1, sub2.tv_nsec / 1);
14935 15418
14936 xfree (outline); 15419 xfree (outline);
14937 } 15420 }
diff --git a/src/sfnt.h b/src/sfnt.h
index baed1d257dd..48522960043 100644
--- a/src/sfnt.h
+++ b/src/sfnt.h
@@ -698,6 +698,13 @@ struct sfnt_raster
698 unsigned short refcount; 698 unsigned short refcount;
699}; 699};
700 700
701/* Bresenham's algorithm.
702 This rasterizer uses Bresenham's algorithm, with the minor
703 detail being that it does not use device pixels, but rather
704 pixels in a sample grid defined by SFNT_POLY_SHIFT, which is
705 normally set to 4x oversampling. See sfnt_poly_edges for
706 an explanation of how Bresenham's algorithm works. */
707
701struct sfnt_edge 708struct sfnt_edge
702{ 709{
703 /* Next edge in this chain. */ 710 /* Next edge in this chain. */
@@ -709,15 +716,14 @@ struct sfnt_edge
709 /* X position, top and bottom of edges. */ 716 /* X position, top and bottom of edges. */
710 sfnt_fixed x, top, bottom; 717 sfnt_fixed x, top, bottom;
711 718
712 /* step_x is how many pixels to move for each increase in Y by 719 /* Slope error. */
713 SFNT_POLY_STEP. */
714 sfnt_fixed step_x; 720 sfnt_fixed step_x;
715 721
716#ifdef TEST 722 /* SFNT_POLY_STEP times the direction of movement. */
717 /* Value of x before initial adjustment of bottom to match the 723 sfnt_fixed signed_step;
718 grid. */ 724
719 sfnt_fixed source_x; 725 /* Slope error accumulator. */
720#endif 726 sfnt_fixed error;
721}; 727};
722 728
723 729
@@ -731,7 +737,6 @@ enum
731 SFNT_POLY_MASK = (SFNT_POLY_SAMPLE - 1), 737 SFNT_POLY_MASK = (SFNT_POLY_SAMPLE - 1),
732 SFNT_POLY_STEP = (0x10000 >> SFNT_POLY_SHIFT), 738 SFNT_POLY_STEP = (0x10000 >> SFNT_POLY_SHIFT),
733 SFNT_POLY_START = (SFNT_POLY_STEP >> 1), 739 SFNT_POLY_START = (SFNT_POLY_STEP >> 1),
734 SFNT_POLY_ROUND = ((1 << (16 - SFNT_POLY_SHIFT)) / 2) - 1,
735 }; 740 };
736 741
737 742