LIB_SRCS=\
ao_blt.c \
+ ao_box.c \
ao_copy.c \
ao_line.c \
ao_pattern.c \
TEST_LIBS=-lXrender -lXext -lX11 -lm -Wl,--gc-sections
-CFLAGS=-O0 -g $(WARN_FLAGS) -DVALIDATE
+CFLAGS=-O0 -g $(WARN_FLAGS) -DVALIDATE -I.
HEADERS=\
ao_draw.h \
* General Public License for more details.
*/
-#include "ao_draw.h"
-#include "ao_draw_int.h"
+#include <ao_draw.h>
+#include <ao_draw_int.h>
#define O 0
#define I AO_ALLONES
--- /dev/null
+/*
+ * Copyright © 2023 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <ao_box.h>
+
+void
+ao_box_union(struct ao_box *dst, int16_t x1, int16_t y1, int16_t x2, int16_t y2)
+{
+ if (x1 < dst->x1) dst->x1 = x1;
+ if (x2 > dst->x2) dst->x2 = x2;
+ if (y1 < dst->y1) dst->y1 = y1;
+ if (y2 > dst->y2) dst->y2 = y2;
+}
--- /dev/null
+/*
+ * Copyright © 2023 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _AO_BOX_H_
+#define _AO_BOX_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+struct ao_box {
+ int16_t x1, y1;
+ int16_t x2, y2;
+};
+
+static inline bool
+ao_box_is_empty(struct ao_box *box)
+{
+ return box->x1 == INT16_MAX;
+}
+
+static inline void
+ao_box_set_empty(struct ao_box *box)
+{
+ box->x1 = INT16_MAX;
+ box->y1 = INT16_MAX;
+ box->x2 = INT16_MIN;
+ box->y2 = INT16_MIN;
+}
+
+#define AO_BOX_INIT { .x1 = INT16_MAX, .y1 = INT16_MAX, .x2 = INT16_MIN, .y2 = INT16_MIN }
+
+void
+ao_box_union(struct ao_box *dst, int16_t x1, int16_t y1, int16_t x2, int16_t y2);
+
+#endif /* _AO_BOX_H_ */
* General Public License for more details.
*/
-#include "ao_draw.h"
-#include "ao_draw_int.h"
+#include <ao_draw.h>
+#include <ao_draw_int.h>
#define bound(val,max,other) do { \
if (val < 0) { \
} while (0)
void
-ao_copy(const struct ao_bitmap *dst,
+ao_copy(struct ao_bitmap *dst,
int16_t dst_x,
int16_t dst_y,
int16_t width,
upsidedown = (dst_y > src_y);
}
+ ao_damage(dst, dst_x, dst_y, dst_x2, dst_y2);
+
if (dst_x < dst_x2 && dst_y < dst_y2) {
ao_blt(src->base + src_y * src->stride,
src->stride,
#include <stdint.h>
#include <stdbool.h>
#include "ao_font.h"
+#include "ao_box.h"
struct ao_bitmap {
uint32_t *base;
int16_t stride; /* in units */
int16_t width; /* in pixels */
int16_t height; /* in pixels */
+ struct ao_box damage;
};
struct ao_coord {
return (int16_t) ((width + 7) >> 3);
}
+static inline void
+ao_damage_set_empty(struct ao_bitmap *dst)
+{
+ ao_box_set_empty(&dst->damage);
+}
+
struct ao_pattern {
uint8_t pattern[8];
};
};
void
-ao_copy(const struct ao_bitmap *dst,
+ao_copy(struct ao_bitmap *dst,
int16_t dst_x,
int16_t dst_y,
int16_t width,
uint8_t rop);
void
-ao_rect(const struct ao_bitmap *dst,
+ao_rect(struct ao_bitmap *dst,
int16_t x,
int16_t y,
int16_t width,
uint8_t rop);
void
-ao_pattern(const struct ao_bitmap *dst,
+ao_pattern(struct ao_bitmap *dst,
int16_t x,
int16_t y,
int16_t width,
uint8_t rop);
void
-ao_line(const struct ao_bitmap *dst,
+ao_line(struct ao_bitmap *dst,
int16_t x1,
int16_t y1,
int16_t x2,
uint8_t rop);
void
-ao_poly(const struct ao_bitmap *dst,
+ao_poly(struct ao_bitmap *dst,
const struct ao_coord *coords,
uint16_t ncoords,
const struct ao_transform *transform,
uint8_t rop);
void
-ao_text(const struct ao_bitmap *dst,
+ao_text(struct ao_bitmap *dst,
const struct ao_font *font,
int16_t x,
int16_t y,
uint8_t rop);
void
-ao_logo(const struct ao_bitmap *dst,
+ao_logo(struct ao_bitmap *dst,
const struct ao_transform *transform,
const struct ao_font *font,
uint32_t fill,
} \
} while (0)
+static inline int16_t
+ao_min16(int16_t a, int16_t b)
+{
+ return a < b ? a : b;
+}
+
+static inline int16_t
+ao_max16(int16_t a, int16_t b)
+{
+ return a > b ? a : b;
+}
+
static inline uint32_t
ao_do_mask_rrop(uint32_t dst, uint32_t and, uint32_t xor, uint32_t mask) {
return (dst & (and | ~mask)) ^ (xor & mask);
return (dst & and) ^ xor;
}
+static inline void
+ao_damage(struct ao_bitmap *dst,
+ int16_t x1,
+ int16_t y1,
+ int16_t x2,
+ int16_t y2)
+{
+ ao_box_union(&dst->damage, x1, y1, x2, y2);
+}
+
void
ao_blt(uint32_t *src_line,
int16_t src_stride,
* General Public License for more details.
*/
-#include "ao_draw.h"
-#include "ao_draw_int.h"
+#include <ao_draw.h>
+#include <ao_draw_int.h>
#define ao_mask(x,w) (ao_right(AO_ALLONES,(x) & AO_MASK) & \
ao_left(AO_ALLONES,(FB_UNIT - ((x)+(w))) & AO_MASK))
}
void
-ao_line(const struct ao_bitmap *dst,
+ao_line(struct ao_bitmap *dst,
int16_t x1,
int16_t y1,
int16_t x2,
if (adx > ady) {
x1 = clip_1.major;
y1 = clip_1.minor;
+ x2 = clip_2.major;
+ y2 = clip_2.minor;
} else {
x1 = clip_1.minor;
y1 = clip_1.major;
+ x2 = clip_2.minor;
+ y2 = clip_2.major;
}
+
+ ao_damage(dst, ao_min16(x1, x2), ao_max16(x1, x2), ao_min16(y1, y2), ao_max16(y1, y2));
+
ao_bres(dst,
signdx,
signdy,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#include "ao_draw.h"
+#include <ao_draw.h>
#include "ao_logo.h"
#define ARRAYSIZE(a) (sizeof(a) / sizeof((a)[0]))
void
-ao_logo(const struct ao_bitmap *dst,
+ao_logo(struct ao_bitmap *dst,
const struct ao_transform *transform,
const struct ao_font *font,
uint32_t fill,
* General Public License for more details.
*/
-#include "ao_draw.h"
-#include "ao_draw_int.h"
+#include <ao_draw.h>
+#include <ao_draw_int.h>
static inline uint32_t
ao_pattern_expand(uint8_t v, uint8_t rot)
}
void
-ao_pattern(const struct ao_bitmap *dst,
+ao_pattern(struct ao_bitmap *dst,
int16_t x,
int16_t y,
int16_t width,
ao_clip(y, 0, dst->height);
ao_clip(y2, 0, dst->height);
+ ao_damage(dst, x, y, x2, y2);
+
if (x < x2 && y < y2) {
uint8_t xrot = (x - pat_x) & 7;
uint8_t yrot = (y - pat_y) & 7;
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#include "ao_draw.h"
-#include "ao_draw_int.h"
+#include <ao_draw.h>
+#include <ao_draw_int.h>
#include <stdio.h>
#include <math.h>
#include <float.h>
* Fill the specified polygon with non-zero winding rule
*/
void
-ao_poly(const struct ao_bitmap *dst,
+ao_poly(struct ao_bitmap *dst,
const struct ao_coord *coords,
uint16_t ncoords,
const struct ao_transform *transform,
uint8_t rop)
{
float y_min, y_max;
+ float x_min, x_max;
uint16_t edge;
float y;
float x;
transform = &ao_identity;
/*
- * Find the y limits of the polygon
+ * Find the limits of the polygon
*/
+ x_min = x_max = _x(coords, transform, 0);
y_min = y_max = _y(coords, transform, 0);
for (edge = 1; edge < ncoords; edge++) {
+ x = _x(coords, transform, edge);
+ if (x < x_min)
+ x_min = x;
+ else if (x > x_max)
+ x_max = x;
y = _y(coords, transform, edge);
if (y < y_min)
y_min = y;
y_max = y;
}
+ x_min = floorf(x_min);
+ x_max = ceilf(x_max);
+ ao_clip(x_min, 0, dst->width);
+ ao_clip(x_max, 0, dst->width);
+
y_min = floorf(y_min);
y_max = ceilf(y_max);
-
ao_clip(y_min, 0, dst->height);
ao_clip(y_max, 0, dst->height);
+ ao_damage(dst, (int16_t) x_min, (int16_t) y_min, (int16_t) x_max, (int16_t) y_max);
+
/*
* Walk each scanline in the range and fill included spans
*/
* General Public License for more details.
*/
-#include "ao_draw.h"
-#include "ao_draw_int.h"
+#include <ao_draw.h>
+#include <ao_draw_int.h>
void
-ao_rect(const struct ao_bitmap *dst,
+ao_rect(struct ao_bitmap *dst,
int16_t x,
int16_t y,
int16_t width,
ao_clip(y, 0, dst->height);
ao_clip(y2, 0, dst->height);
+ ao_damage(dst, x, y, x2, y2);
+
if (x < x2 && y < y2) {
ao_solid(ao_and(rop, fill),
ao_xor(rop, fill),
* General Public License for more details.
*/
-#include "ao_draw.h"
-#include "ao_draw_int.h"
+#include <ao_draw.h>
+#include <ao_draw_int.h>
#include "ao_font.h"
#include <string.h>
#include <stdio.h>
void
-ao_text(const struct ao_bitmap *dst,
+ao_text(struct ao_bitmap *dst,
const struct ao_font *font,
int16_t x,
int16_t y,