From: Keith Packard Date: Sun, 26 Feb 2023 07:45:25 +0000 (-0800) Subject: altos/draw: Use float for polygon coords X-Git-Tag: 1.9.16~1^2~43 X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=commitdiff_plain;h=331e2833e178a1a4b0400e1ea06e1e387009f245 altos/draw: Use float for polygon coords This makes polygons look way better. Signed-off-by: Keith Packard --- diff --git a/src/draw/Makefile b/src/draw/Makefile index e56acf29..ca5628b6 100644 --- a/src/draw/Makefile +++ b/src/draw/Makefile @@ -35,7 +35,7 @@ SRCS=\ OBJS=$(SRCS:.c=.o) -LIBS=-lXrender -lX11 +LIBS=-lXrender -lX11 -lm CFLAGS=-O0 -g diff --git a/src/draw/ao_draw.h b/src/draw/ao_draw.h index 43301caf..8d487a99 100644 --- a/src/draw/ao_draw.h +++ b/src/draw/ao_draw.h @@ -27,7 +27,7 @@ struct ao_bitmap { }; struct ao_coord { - int16_t x, y; + float x, y; }; struct ao_pattern { diff --git a/src/draw/ao_poly.c b/src/draw/ao_poly.c index d60d7334..7fa351be 100644 --- a/src/draw/ao_poly.c +++ b/src/draw/ao_poly.c @@ -19,6 +19,8 @@ #include "ao_draw.h" #include "ao_draw_int.h" #include +#include +#include /* * Return if the given edge is 'live' at the specified y coordinate. @@ -29,11 +31,11 @@ static bool ao_edge_live(const struct ao_coord *coords, uint16_t ncoords, uint16_t edge, - int16_t y) + float y) { int next_edge = (edge == ncoords - 1) ? 0 : edge + 1; - int16_t y1 = coords[edge].y; - int16_t y2 = coords[next_edge].y; + float y1 = coords[edge].y; + float y2 = coords[next_edge].y; if (y1 > y2) return y2 <= y && y < y1; @@ -48,22 +50,22 @@ static int16_t ao_edge_x(const struct ao_coord *coords, uint16_t ncoords, uint16_t edge, - int16_t y) + float y) { int next_edge = (edge == ncoords - 1) ? 0 : edge + 1; - int16_t x1 = coords[edge].x; - int16_t x2 = coords[next_edge].x; - int16_t y1 = coords[edge].y; - int16_t y2 = coords[next_edge].y; - int16_t dx = x2 - x1; - int16_t dy = y2 - y1; - int16_t off_y = y - y1; + float x1 = coords[edge].x; + float x2 = coords[next_edge].x; + float y1 = coords[edge].y; + float y2 = coords[next_edge].y; + float dx = x2 - x1; + float dy = y2 - y1; + float off_y = y - y1; return x1 + (off_y * dx) / dy; } struct next_x { - int16_t x; + float x; uint16_t edge; }; @@ -76,16 +78,16 @@ static bool ao_next_x(const struct ao_coord *coords, uint16_t ncoords, struct next_x *this_x, - int16_t y) + float y) { uint16_t edge; - int16_t next_x = INT16_MAX; + float next_x = FLT_MAX; uint16_t next_edge = UINT16_MAX; bool ret = false; for (edge = 0; edge < ncoords; edge++) { if (ao_edge_live(coords, ncoords, edge, y)) { - int16_t nx = ao_edge_x(coords, ncoords, edge, y); + float nx = ao_edge_x(coords, ncoords, edge, y); if (this_x->x < nx || (this_x->x == nx && this_x->edge < edge)) { if (nx < next_x) { next_x = nx; @@ -105,13 +107,16 @@ ao_next_x(const struct ao_coord *coords, */ static void ao_span(const struct ao_bitmap *dst, - int16_t x1, - int16_t x2, - int16_t y, + float x1, + float x2, + float y, uint32_t fill, uint8_t rop) { - ao_rect(dst, x1, y, x2 - x1, 1, fill, rop); + int16_t ix1 = floorf(x1 + 0.5f); + int16_t ix2 = floorf(x2 + 0.5f); + int16_t iy = (int16_t) y; + ao_rect(dst, ix1, iy, ix2 - ix1, 1, fill, rop); } /* @@ -137,10 +142,10 @@ ao_poly(const struct ao_bitmap *dst, uint32_t fill, uint8_t rop) { - int16_t y_min, y_max; + float y_min, y_max; uint16_t edge; - int16_t y; - int16_t x; + float y; + float x; struct next_x next_x; int wind; @@ -156,6 +161,9 @@ ao_poly(const struct ao_bitmap *dst, y_max = y; } + y_min = floorf(y_min); + y_max = ceilf(y_max); + /* * Walk each scanline in the range and fill included spans */