diff options
Diffstat (limited to 'src/draw')
-rw-r--r-- | src/draw/ao_blt.c | 1 | ||||
-rw-r--r-- | src/draw/ao_copy.c | 75 | ||||
-rw-r--r-- | src/draw/ao_draw.h | 137 | ||||
-rw-r--r-- | src/draw/ao_draw_int.h | 128 | ||||
-rw-r--r-- | src/draw/ao_font.h | 138 | ||||
-rw-r--r-- | src/draw/ao_line.c | 164 | ||||
-rw-r--r-- | src/draw/ao_rect.c | 55 | ||||
-rw-r--r-- | src/draw/ao_text.c | 51 | ||||
-rwxr-xr-x | src/draw/font-convert | 20 |
9 files changed, 531 insertions, 238 deletions
diff --git a/src/draw/ao_blt.c b/src/draw/ao_blt.c index 2060f007..e3f45221 100644 --- a/src/draw/ao_blt.c +++ b/src/draw/ao_blt.c @@ -14,6 +14,7 @@ #include "ao.h" #include "ao_draw.h" +#include "ao_draw_int.h" #define O 0 #define I AO_ALLONES diff --git a/src/draw/ao_copy.c b/src/draw/ao_copy.c new file mode 100644 index 00000000..47067bb8 --- /dev/null +++ b/src/draw/ao_copy.c @@ -0,0 +1,75 @@ +/* + * Copyright © 2016 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. + */ + +#include "ao.h" +#include "ao_draw.h" +#include "ao_draw_int.h" + +#define bound(val,max,other) do { \ + if (val < 0) { \ + other -= val; \ + val = 0; \ + } \ + if (val > max) { \ + other -= (val - max); \ + val = max; \ + } \ + } while (0) + +#define bound2(a, max_a, b, max_b) do { \ + bound(a, max_a, b); \ + bound(b, max_b, a); \ + } while (0) + +void +ao_copy(const struct ao_bitmap *dst, + int16_t dst_x, + int16_t dst_y, + int16_t width, + int16_t height, + const struct ao_bitmap *src, + int16_t src_x, + int16_t src_y, + uint8_t rop) +{ + int16_t dst_x2 = dst_x + width, dst_y2 = dst_y + height; + int16_t src_x2 = src_x + width, src_y2 = src_y + height; + uint8_t reverse = 0; + uint8_t upsidedown = 0; + + bound2(dst_x, dst->width, src_x, src->width); + bound2(dst_x2, dst->width, src_x2, src->width); + bound2(dst_y, dst->height, src_y, src->height); + bound2(dst_y2, dst->height, src_y2, src->height); + + if (dst == src) { + reverse = (dst_x > src_x); + upsidedown = (dst_y > src_y); + } + + if (dst_x < dst_x2 && dst_y < dst_y2) { + ao_blt(src->base + src_y * src->stride, + src->stride, + src_x, + dst->base + dst_y * dst->stride, + dst->stride, + dst_x, + dst_x2 - dst_x, + dst_y2 - dst_y, + rop, + reverse, + upsidedown); + } +} + diff --git a/src/draw/ao_draw.h b/src/draw/ao_draw.h index 1ff3e748..f7dc75bf 100644 --- a/src/draw/ao_draw.h +++ b/src/draw/ao_draw.h @@ -15,99 +15,74 @@ #ifndef _AO_DRAW_H_ #define _AO_DRAW_H_ +struct ao_bitmap { + uint32_t *base; + int16_t stride; /* in units */ + int16_t width; /* in pixels */ + int16_t height; /* in pixels */ +}; + void -ao_blt(uint32_t *src_line, - int16_t src_stride, - int16_t src_x, - uint32_t *dst_line, - int16_t dst_stride, - int16_t dst_x, - int16_t width, - int16_t height, - uint8_t rop, - uint8_t reverse, - uint8_t upsidedown); +ao_copy(const struct ao_bitmap *dst, + int16_t dst_x, + int16_t dst_y, + int16_t width, + int16_t height, + const struct ao_bitmap *src, + int16_t src_x, + int16_t src_y, + uint8_t rop); void -ao_solid(uint32_t and, - uint32_t xor, - uint32_t *dst, - int16_t dst_stride, - int16_t dst_x, - int16_t width, - int16_t height); +ao_rect(const struct ao_bitmap *dst, + int16_t x, + int16_t y, + int16_t width, + int16_t height, + uint32_t fill, + uint8_t rop); void -ao_text(char *string, - uint32_t *dst_line, - int16_t dst_stride, - int16_t dst_x); +ao_line(const struct ao_bitmap *dst, + int16_t x1, + int16_t y1, + int16_t x2, + int16_t y2, + uint32_t fill, + uint8_t rop); -#define AO_ROP_CLEAR 0x0 -#define AO_ROP_COPY 0x3 -#define AO_ROP_SET 0xf +void +ao_text(const struct ao_bitmap *dst, + int16_t x, + int16_t y, + char *string, + uint32_t fill, + uint8_t rop); + +struct ao_font { + int width; + int height; + int ascent; + int descent; +}; + +extern const struct ao_font ao_font; #define AO_SHIFT 5 #define AO_UNIT (1 << AO_SHIFT) #define AO_MASK (AO_UNIT - 1) #define AO_ALLONES ((uint32_t) -1) -static inline uint32_t -ao_left(uint32_t bits, int16_t shift) { - return bits >> shift; -} - -static inline uint32_t -ao_right(uint32_t bits, int16_t shift) { - return bits << shift; -} - -static inline uint32_t -ao_right_mask(int16_t x) { - if ((AO_UNIT - x) & AO_MASK) - return ao_left(AO_ALLONES,(AO_UNIT - x) & AO_MASK); - else - return 0; -} - -static inline uint32_t -ao_left_mask(int16_t x) { - if (x & AO_MASK) - return ao_right(AO_ALLONES, x & AO_MASK); - else - return 0; -} - -static inline uint32_t -ao_bits_mask(int16_t x, int16_t w) { - return ao_right(AO_ALLONES, x & AO_MASK) & - ao_left(AO_ALLONES,(AO_UNIT - (x + w)) & AO_MASK); -} - -#define ao_mask_bits(x,w,l,n,r) { \ - n = (w); \ - r = ao_right_mask((x)+n); \ - l = ao_left_mask(x); \ - if (l) { \ - n -= AO_UNIT - ((x) & AO_MASK); \ - if (n < 0) { \ - n = 0; \ - l &= r; \ - r = 0; \ - } \ - } \ - n >>= AO_SHIFT; \ -} - -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); -} - -static inline uint32_t -ao_do_rrop(uint32_t dst, uint32_t and, uint32_t xor) { - return (dst & and) ^ xor; -} +/* + * dst + * 0 1 + * + * 0 a b + * src + * 1 c d + * + * ROP = abcd + */ #define AO_CLEAR 0x0 /* 0 */ #define AO_AND 0x1 /* src AND dst */ diff --git a/src/draw/ao_draw_int.h b/src/draw/ao_draw_int.h new file mode 100644 index 00000000..6980147b --- /dev/null +++ b/src/draw/ao_draw_int.h @@ -0,0 +1,128 @@ +/* + * Copyright © 2016 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. + */ + +#ifndef _AO_DRAW_INT_H_ +#define _AO_DRAW_INT_H_ + +static inline uint32_t +ao_expand(uint32_t bits) +{ + return ~((bits & 1)-1); +} + +static inline uint32_t +ao_xor(uint8_t rop, uint32_t fg) +{ + fg = ao_expand(fg); + + return (fg & ao_expand(rop >> 1)) | + (~fg & ao_expand(rop >> 3)); +} + +static inline uint32_t +ao_and(uint8_t rop, uint32_t fg) +{ + fg = ao_expand(fg); + + return (fg & ao_expand(rop ^ (rop >> 1))) | + (~fg & ao_expand((rop>>2) ^ (rop>>3))); +} + +static inline uint32_t +ao_left(uint32_t bits, int16_t shift) { + return bits >> shift; +} + +static inline uint32_t +ao_right(uint32_t bits, int16_t shift) { + return bits << shift; +} + +static inline uint32_t +ao_right_mask(int16_t x) { + if ((AO_UNIT - x) & AO_MASK) + return ao_left(AO_ALLONES,(AO_UNIT - x) & AO_MASK); + else + return 0; +} + +static inline uint32_t +ao_left_mask(int16_t x) { + if (x & AO_MASK) + return ao_right(AO_ALLONES, x & AO_MASK); + else + return 0; +} + +static inline uint32_t +ao_bits_mask(int16_t x, int16_t w) { + return ao_right(AO_ALLONES, x & AO_MASK) & + ao_left(AO_ALLONES,(AO_UNIT - (x + w)) & AO_MASK); +} + +#define ao_mask_bits(x,w,l,n,r) { \ + n = (w); \ + r = ao_right_mask((x)+n); \ + l = ao_left_mask(x); \ + if (l) { \ + n -= AO_UNIT - ((x) & AO_MASK); \ + if (n < 0) { \ + n = 0; \ + l &= r; \ + r = 0; \ + } \ + } \ + n >>= AO_SHIFT; \ +} + +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); +} + +static inline uint32_t +ao_do_rrop(uint32_t dst, uint32_t and, uint32_t xor) { + return (dst & and) ^ xor; +} + +void +ao_blt(uint32_t *src_line, + int16_t src_stride, + int16_t src_x, + uint32_t *dst_line, + int16_t dst_stride, + int16_t dst_x, + int16_t width, + int16_t height, + uint8_t rop, + uint8_t reverse, + uint8_t upsidedown); + +void +ao_solid(uint32_t and, + uint32_t xor, + uint32_t *dst, + int16_t dst_stride, + int16_t dst_x, + int16_t width, + int16_t height); + +int16_t +ao_glyph(const struct ao_bitmap *dst, + int16_t x, + int16_t y, + uint8_t c, + uint8_t rop); + +#endif /* _AO_DRAW_INT_H_ */ diff --git a/src/draw/ao_font.h b/src/draw/ao_font.h deleted file mode 100644 index ac424ef9..00000000 --- a/src/draw/ao_font.h +++ /dev/null @@ -1,138 +0,0 @@ -static uint8_t glyph_bytes[] = { - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x04, 0x0e, 0x1f, 0x0e, 0x04, 0x00, 0x0a, 0x05, - 0x0a, 0x05, 0x0a, 0x05, 0x00, 0x05, 0x07, 0x05, 0x05, 0x0e, 0x04, 0x04, 0x03, 0x01, 0x03, 0x0d, - 0x04, 0x0c, 0x04, 0x03, 0x01, 0x03, 0x06, 0x0a, 0x06, 0x0a, 0x01, 0x01, 0x03, 0x0c, 0x04, 0x0c, - 0x04, 0x04, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0e, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x09, - 0x0b, 0x0d, 0x09, 0x04, 0x04, 0x0c, 0x05, 0x05, 0x05, 0x02, 0x0e, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x1c, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x1c, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x1f, 0x04, 0x04, 0x04, - 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x1f, 0x00, 0x04, 0x04, 0x04, 0x1c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x04, 0x02, 0x04, 0x08, 0x0e, 0x00, 0x02, 0x04, 0x08, - 0x04, 0x02, 0x0e, 0x00, 0x00, 0x00, 0x0e, 0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x08, 0x0e, 0x04, 0x0e, - 0x02, 0x00, 0x00, 0x0c, 0x02, 0x07, 0x02, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x00, 0x04, 0x00, 0x0a, 0x0a, - 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x1f, 0x0a, 0x1f, 0x0a, 0x00, 0x00, 0x0e, 0x05, 0x0e, - 0x14, 0x0e, 0x00, 0x01, 0x09, 0x04, 0x02, 0x09, 0x08, 0x00, 0x00, 0x02, 0x05, 0x02, 0x05, 0x0a, - 0x00, 0x06, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x04, 0x00, 0x02, - 0x04, 0x04, 0x04, 0x04, 0x02, 0x00, 0x00, 0x05, 0x02, 0x07, 0x02, 0x05, 0x00, 0x00, 0x04, 0x04, - 0x1f, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x02, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x08, 0x04, 0x02, 0x01, 0x00, 0x00, - 0x02, 0x05, 0x05, 0x05, 0x05, 0x02, 0x00, 0x02, 0x03, 0x02, 0x02, 0x02, 0x07, 0x00, 0x06, 0x09, - 0x08, 0x04, 0x02, 0x0f, 0x00, 0x0f, 0x08, 0x06, 0x08, 0x09, 0x06, 0x00, 0x04, 0x06, 0x05, 0x0f, - 0x04, 0x04, 0x00, 0x0f, 0x01, 0x07, 0x08, 0x09, 0x06, 0x00, 0x06, 0x01, 0x07, 0x09, 0x09, 0x06, - 0x00, 0x0f, 0x08, 0x04, 0x04, 0x02, 0x02, 0x00, 0x06, 0x09, 0x06, 0x09, 0x09, 0x06, 0x00, 0x06, - 0x09, 0x09, 0x0e, 0x08, 0x06, 0x00, 0x00, 0x06, 0x06, 0x00, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, - 0x00, 0x06, 0x02, 0x01, 0x00, 0x04, 0x02, 0x01, 0x02, 0x04, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0f, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x02, 0x01, 0x00, 0x02, 0x05, 0x04, 0x02, 0x00, 0x02, 0x00, - 0x06, 0x09, 0x0d, 0x0d, 0x01, 0x06, 0x00, 0x06, 0x09, 0x09, 0x0f, 0x09, 0x09, 0x00, 0x07, 0x09, - 0x07, 0x09, 0x09, 0x07, 0x00, 0x06, 0x09, 0x01, 0x01, 0x09, 0x06, 0x00, 0x07, 0x09, 0x09, 0x09, - 0x09, 0x07, 0x00, 0x0f, 0x01, 0x07, 0x01, 0x01, 0x0f, 0x00, 0x0f, 0x01, 0x07, 0x01, 0x01, 0x01, - 0x00, 0x06, 0x09, 0x01, 0x0d, 0x09, 0x0e, 0x00, 0x09, 0x09, 0x0f, 0x09, 0x09, 0x09, 0x00, 0x07, - 0x02, 0x02, 0x02, 0x02, 0x07, 0x00, 0x08, 0x08, 0x08, 0x08, 0x09, 0x06, 0x00, 0x09, 0x05, 0x03, - 0x03, 0x05, 0x09, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0f, 0x00, 0x09, 0x0f, 0x0f, 0x09, 0x09, - 0x09, 0x00, 0x09, 0x0b, 0x0b, 0x0d, 0x0d, 0x09, 0x00, 0x06, 0x09, 0x09, 0x09, 0x09, 0x06, 0x00, - 0x07, 0x09, 0x09, 0x07, 0x01, 0x01, 0x00, 0x06, 0x09, 0x09, 0x09, 0x0b, 0x06, 0x08, 0x07, 0x09, - 0x09, 0x07, 0x05, 0x09, 0x00, 0x06, 0x09, 0x02, 0x04, 0x09, 0x06, 0x00, 0x07, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x06, 0x00, 0x09, 0x09, 0x09, 0x09, 0x06, 0x06, - 0x00, 0x09, 0x09, 0x09, 0x0f, 0x0f, 0x09, 0x00, 0x09, 0x09, 0x06, 0x06, 0x09, 0x09, 0x00, 0x05, - 0x05, 0x05, 0x02, 0x02, 0x02, 0x00, 0x0f, 0x08, 0x04, 0x02, 0x01, 0x0f, 0x00, 0x07, 0x01, 0x01, - 0x01, 0x01, 0x07, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x04, - 0x07, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, - 0x03, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x09, 0x0d, 0x0a, 0x00, 0x01, 0x01, - 0x07, 0x09, 0x09, 0x07, 0x00, 0x00, 0x00, 0x06, 0x01, 0x01, 0x06, 0x00, 0x08, 0x08, 0x0e, 0x09, - 0x09, 0x0e, 0x00, 0x00, 0x00, 0x06, 0x0d, 0x03, 0x06, 0x00, 0x04, 0x0a, 0x02, 0x07, 0x02, 0x02, - 0x00, 0x00, 0x00, 0x0e, 0x09, 0x06, 0x01, 0x0e, 0x01, 0x01, 0x07, 0x09, 0x09, 0x09, 0x00, 0x02, - 0x00, 0x03, 0x02, 0x02, 0x07, 0x00, 0x04, 0x00, 0x04, 0x04, 0x04, 0x05, 0x02, 0x01, 0x01, 0x05, - 0x03, 0x05, 0x09, 0x00, 0x03, 0x02, 0x02, 0x02, 0x02, 0x07, 0x00, 0x00, 0x00, 0x05, 0x0f, 0x09, - 0x09, 0x00, 0x00, 0x00, 0x07, 0x09, 0x09, 0x09, 0x00, 0x00, 0x00, 0x06, 0x09, 0x09, 0x06, 0x00, - 0x00, 0x00, 0x07, 0x09, 0x09, 0x07, 0x01, 0x00, 0x00, 0x0e, 0x09, 0x09, 0x0e, 0x08, 0x00, 0x00, - 0x07, 0x09, 0x01, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x03, 0x0c, 0x07, 0x00, 0x02, 0x02, 0x07, 0x02, - 0x02, 0x0c, 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x0e, 0x00, 0x00, 0x00, 0x05, 0x05, 0x05, 0x02, - 0x00, 0x00, 0x00, 0x09, 0x09, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x09, 0x06, 0x06, 0x09, 0x00, 0x00, - 0x00, 0x09, 0x09, 0x0a, 0x04, 0x02, 0x00, 0x00, 0x0f, 0x04, 0x02, 0x0f, 0x00, 0x04, 0x02, 0x03, - 0x02, 0x02, 0x04, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x06, 0x02, 0x02, - 0x01, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x04, - 0x0e, 0x05, 0x05, 0x0e, 0x04, 0x00, 0x0c, 0x02, 0x07, 0x02, 0x0d, 0x00, 0x00, 0x11, 0x0e, 0x0a, - 0x0e, 0x11, 0x00, 0x05, 0x05, 0x02, 0x07, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x04, 0x04, - 0x00, 0x0c, 0x02, 0x06, 0x0a, 0x0c, 0x08, 0x06, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, - 0x11, 0x15, 0x13, 0x15, 0x11, 0x0e, 0x06, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, - 0x09, 0x12, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, - 0x00, 0x00, 0x0e, 0x11, 0x17, 0x13, 0x13, 0x11, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x1f, 0x04, 0x04, 0x1f, 0x00, 0x06, 0x04, - 0x02, 0x06, 0x00, 0x00, 0x00, 0x06, 0x06, 0x04, 0x06, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x07, 0x01, 0x0e, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, - 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x04, - 0x06, 0x04, 0x0e, 0x00, 0x00, 0x00, 0x02, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - 0x12, 0x09, 0x00, 0x00, 0x01, 0x01, 0x01, 0x09, 0x0c, 0x0e, 0x08, 0x01, 0x01, 0x01, 0x0d, 0x08, - 0x04, 0x0c, 0x03, 0x03, 0x02, 0x0b, 0x0c, 0x0e, 0x08, 0x02, 0x00, 0x02, 0x01, 0x05, 0x02, 0x00, - 0x06, 0x09, 0x09, 0x0f, 0x09, 0x09, 0x00, 0x06, 0x09, 0x09, 0x0f, 0x09, 0x09, 0x00, 0x06, 0x09, - 0x09, 0x0f, 0x09, 0x09, 0x00, 0x06, 0x09, 0x09, 0x0f, 0x09, 0x09, 0x00, 0x06, 0x09, 0x09, 0x0f, - 0x09, 0x09, 0x00, 0x06, 0x09, 0x09, 0x0f, 0x09, 0x09, 0x00, 0x0e, 0x05, 0x0d, 0x07, 0x05, 0x0d, - 0x00, 0x06, 0x09, 0x01, 0x01, 0x09, 0x06, 0x02, 0x0f, 0x01, 0x07, 0x01, 0x01, 0x0f, 0x00, 0x0f, - 0x01, 0x07, 0x01, 0x01, 0x0f, 0x00, 0x0f, 0x01, 0x07, 0x01, 0x01, 0x0f, 0x00, 0x0f, 0x01, 0x07, - 0x01, 0x01, 0x0f, 0x00, 0x07, 0x02, 0x02, 0x02, 0x02, 0x07, 0x00, 0x07, 0x02, 0x02, 0x02, 0x02, - 0x07, 0x00, 0x07, 0x02, 0x02, 0x02, 0x02, 0x07, 0x00, 0x07, 0x02, 0x02, 0x02, 0x02, 0x07, 0x00, - 0x07, 0x0a, 0x0b, 0x0a, 0x0a, 0x07, 0x00, 0x0d, 0x09, 0x0b, 0x0d, 0x0d, 0x09, 0x00, 0x06, 0x09, - 0x09, 0x09, 0x09, 0x06, 0x00, 0x06, 0x09, 0x09, 0x09, 0x09, 0x06, 0x00, 0x06, 0x09, 0x09, 0x09, - 0x09, 0x06, 0x00, 0x06, 0x09, 0x09, 0x09, 0x09, 0x06, 0x00, 0x06, 0x09, 0x09, 0x09, 0x09, 0x06, - 0x00, 0x00, 0x00, 0x09, 0x06, 0x06, 0x09, 0x00, 0x0e, 0x0d, 0x0d, 0x0b, 0x0b, 0x07, 0x00, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x06, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x06, 0x00, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x06, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x06, 0x00, 0x05, 0x05, 0x05, 0x02, 0x02, - 0x02, 0x00, 0x01, 0x07, 0x09, 0x07, 0x01, 0x01, 0x00, 0x06, 0x09, 0x07, 0x09, 0x0b, 0x05, 0x01, - 0x02, 0x04, 0x0e, 0x09, 0x0d, 0x0a, 0x00, 0x04, 0x02, 0x0e, 0x09, 0x0d, 0x0a, 0x00, 0x04, 0x0a, - 0x0e, 0x09, 0x0d, 0x0a, 0x00, 0x0a, 0x05, 0x0e, 0x09, 0x0d, 0x0a, 0x00, 0x0a, 0x00, 0x0e, 0x09, - 0x0d, 0x0a, 0x00, 0x06, 0x06, 0x0e, 0x09, 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x0e, 0x0d, 0x05, 0x0e, - 0x00, 0x00, 0x00, 0x06, 0x01, 0x01, 0x06, 0x02, 0x02, 0x04, 0x06, 0x0d, 0x03, 0x06, 0x00, 0x04, - 0x02, 0x06, 0x0d, 0x03, 0x06, 0x00, 0x02, 0x05, 0x06, 0x0d, 0x03, 0x06, 0x00, 0x05, 0x00, 0x06, - 0x0d, 0x03, 0x06, 0x00, 0x01, 0x02, 0x03, 0x02, 0x02, 0x07, 0x00, 0x02, 0x01, 0x03, 0x02, 0x02, - 0x07, 0x00, 0x02, 0x05, 0x03, 0x02, 0x02, 0x07, 0x00, 0x05, 0x00, 0x03, 0x02, 0x02, 0x07, 0x00, - 0x02, 0x0c, 0x06, 0x09, 0x09, 0x06, 0x00, 0x0a, 0x05, 0x07, 0x09, 0x09, 0x09, 0x00, 0x02, 0x04, - 0x06, 0x09, 0x09, 0x06, 0x00, 0x04, 0x02, 0x06, 0x09, 0x09, 0x06, 0x00, 0x06, 0x00, 0x06, 0x09, - 0x09, 0x06, 0x00, 0x0a, 0x05, 0x06, 0x09, 0x09, 0x06, 0x00, 0x05, 0x00, 0x06, 0x09, 0x09, 0x06, - 0x00, 0x00, 0x06, 0x00, 0x0f, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0e, 0x0d, 0x0b, 0x07, 0x00, 0x02, - 0x04, 0x09, 0x09, 0x09, 0x0e, 0x00, 0x04, 0x02, 0x09, 0x09, 0x09, 0x0e, 0x00, 0x06, 0x00, 0x09, - 0x09, 0x09, 0x0e, 0x00, 0x0a, 0x00, 0x09, 0x09, 0x09, 0x0e, 0x00, 0x04, 0x02, 0x09, 0x09, 0x0a, - 0x04, 0x02, 0x00, 0x01, 0x07, 0x09, 0x09, 0x07, 0x01, 0x0a, 0x00, 0x09, 0x09, 0x0a, 0x04, 0x02, -}; - -static uint16_t glyph_pos[] = { - 0, 7, 14, 21, 28, 35, 42, 49, - 56, 63, 70, 77, 84, 91, 98, 105, - 112, 119, 126, 133, 140, 147, 154, 161, - 168, 175, 182, 189, 196, 203, 210, 217, - 224, 231, 238, 245, 252, 259, 266, 273, - 280, 287, 294, 301, 308, 315, 322, 329, - 336, 343, 350, 357, 364, 371, 378, 385, - 392, 399, 406, 413, 420, 427, 434, 441, - 448, 455, 462, 469, 476, 483, 490, 497, - 504, 511, 518, 525, 532, 539, 546, 553, - 560, 567, 574, 581, 588, 595, 602, 609, - 616, 623, 630, 637, 644, 651, 658, 665, - 672, 679, 686, 693, 700, 707, 714, 721, - 728, 735, 742, 749, 756, 763, 770, 777, - 784, 791, 798, 805, 812, 819, 826, 833, - 840, 847, 854, 861, 868, 875, 882, 889, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 896, 903, 910, 917, 924, 931, 938, 945, - 952, 959, 966, 973, 980, 987, 994, 1001, - 1008, 1015, 1022, 1029, 1036, 1043, 1050, 1057, - 1064, 1071, 1078, 1085, 1092, 1099, 1106, 1113, - 1120, 1127, 1134, 1141, 1148, 1155, 1162, 1169, - 1176, 1183, 1190, 1197, 1204, 1211, 1218, 1225, - 1232, 1239, 1246, 1253, 1260, 1267, 1274, 1281, - 1288, 1295, 1302, 1309, 1316, 1323, 1330, 1337, - 1344, 1351, 1358, 1365, 1372, 1379, 1386, 1393, - 1400, 1407, 1414, 1421, 1428, 1435, 1442, 1449, - 1456, 1463, 1470, 1477, 1484, 1491, 1498, 1505, - 1512, 1519, 1526, 1533, 1540, 1547, 1554, 1561, -}; - -#define GLYPH_WIDTH 5 -#define GLYPH_HEIGHT 7 diff --git a/src/draw/ao_line.c b/src/draw/ao_line.c new file mode 100644 index 00000000..b427892b --- /dev/null +++ b/src/draw/ao_line.c @@ -0,0 +1,164 @@ +/* + * Copyright © 2016 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. + */ + +#include "ao.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)) + + +/* out of clip region codes */ +#define OUT_LEFT 0x08 +#define OUT_RIGHT 0x04 +#define OUT_ABOVE 0x02 +#define OUT_BELOW 0x01 + +/* major axis for bresenham's line */ +#define X_AXIS 0 +#define Y_AXIS 1 + +static void +ao_bres(const struct ao_bitmap *dst_bitmap, + int16_t signdx, + int16_t signdy, + int16_t axis, + int16_t x1, + int16_t y1, + int16_t e, + int16_t e1, + int16_t e3, + int16_t len, + uint32_t and, + uint32_t xor) +{ + int16_t stride = dst_bitmap->stride; + uint32_t *dst = dst_bitmap->base; + uint32_t mask0, mask; + + mask0 = 1; + if (signdx < 0) + mask0 = ao_right(1, AO_UNIT - 1); + + if (signdy < 0) + stride = -stride; + + dst = dst + y1 * stride + (x1 >> AO_SHIFT); + mask = ao_right(1, x1 & AO_MASK); + + while (len--) { + /* clip each point */ + + if (0 <= x1 && x1 < dst_bitmap->width && + 0 <= y1 && y1 < dst_bitmap->height) + *dst = ao_do_mask_rrop(*dst, and, xor, mask); + + if (axis == X_AXIS) { + if (signdx < 0) + mask = ao_left(mask, 1); + else + mask = ao_right(mask, 1); + if (!mask) { + dst += signdx; + mask = mask0; + } + x1 += signdx; + e += e1; + if (e >= 0) { + dst += stride; + e += e3; + y1 += signdy; + } + } else { + dst += stride; + e += e1; + y1 += signdy; + if (e >= 0) { + if (signdx < 0) + mask = ao_left(mask, 1); + else + mask = ao_right(mask, 1); + if (!mask) { + dst += signdx; + mask = mask0; + } + e += e3; + x1 += signdx; + } + } + } +} + + +#define bound(val,max) do { \ + if (val < 0) { \ + val = 0; \ + } \ + if (val > max) { \ + val = max; \ + } \ + } while (0) + +void +ao_line(const struct ao_bitmap *dst, + int16_t x1, + int16_t y1, + int16_t x2, + int16_t y2, + uint32_t fill, + uint8_t rop) +{ + int16_t adx, ady; + int16_t e, e1, e2, e3; + int16_t signdx = 1, signdy = 1; + int16_t axis; + int16_t len; + + if ((adx = x2 - x1) < 0) { + adx = -adx; + signdx = -1; + } + if ((ady = y2 - y1) < 0) { + ady = -ady; + signdy = -1; + } + + if (adx > ady) { + axis = X_AXIS; + e1 = ady << 1; + e2 = e1 - (adx << 1); + e = e1 - adx; + len = adx; + } else { + axis = Y_AXIS; + e1 = adx << 1; + e2 = e1 - (ady << 1); + e = e1 - ady; + len = ady; + } + + e3 = e2 - e1; + e = e - e1; + + ao_bres(dst, + signdx, + signdy, + axis, + x1, + y1, + e, e1, e3, len, + ao_and(rop, fill), + ao_xor(rop, fill)); +} diff --git a/src/draw/ao_rect.c b/src/draw/ao_rect.c new file mode 100644 index 00000000..fee7bbd5 --- /dev/null +++ b/src/draw/ao_rect.c @@ -0,0 +1,55 @@ +/* + * Copyright © 2016 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. + */ + +#include "ao.h" +#include "ao_draw.h" +#include "ao_draw_int.h" + +#define bound(val,max) do { \ + if (val < 0) { \ + val = 0; \ + } \ + if (val > max) { \ + val = max; \ + } \ + } while (0) + +void +ao_rect(const struct ao_bitmap *dst, + int16_t x, + int16_t y, + int16_t width, + int16_t height, + uint32_t fill, + uint8_t rop) +{ + int16_t x2 = x + width; + int16_t y2 = y + height; + + bound(x, dst->width); + bound(x2, dst->width); + bound(y, dst->height); + bound(y2, dst->height); + + if (x < x2 && y < y2) { + ao_solid(ao_and(rop, fill), + ao_xor(rop, fill), + dst->base + y * dst->stride, + dst->stride, + x, + x2 - x, + y2 - y); + } +} + diff --git a/src/draw/ao_text.c b/src/draw/ao_text.c index 68d6c2cf..18e3924d 100644 --- a/src/draw/ao_text.c +++ b/src/draw/ao_text.c @@ -14,31 +14,52 @@ #include "ao.h" #include "ao_draw.h" +#include "ao_draw_int.h" #include "ao_font.h" +const struct ao_font ao_font = { + .width = GLYPH_WIDTH, + .height = GLYPH_HEIGHT, + .ascent = GLYPH_ASCENT, + .descent = GLYPH_HEIGHT - GLYPH_ASCENT, +}; + void -ao_text(char *string, - uint32_t *dst_line, - int16_t dst_stride, - int16_t dst_x) +ao_text(const struct ao_bitmap *dst, + int16_t x, + int16_t y, + char *string, + uint32_t fill, + uint8_t rop) { - char c; uint32_t src[GLYPH_HEIGHT]; + char c; + int h; + + struct ao_bitmap src_bitmap = { + .base = src, + .stride = 1, + .width = GLYPH_WIDTH, + .height = GLYPH_HEIGHT + }; + + y -= GLYPH_ASCENT; + + rop = (rop & 3) | 0x4; + + if ((fill&1) == 0) + rop ^= 3; while ((c = *string++)) { - uint8_t *bytes = &glyph_bytes[glyph_pos[(uint8_t) c]]; - int h; + uint8_t *bytes = &glyph_bytes[glyph_pos[(uint8_t) c]]; for (h = 0; h < GLYPH_HEIGHT; h++) src[h] = bytes[h]; - ao_blt(src, 1, 0, - dst_line, dst_stride, - dst_x, - GLYPH_WIDTH, - GLYPH_HEIGHT, - AO_AND_INVERTED, - 0, 0); - dst_x += GLYPH_WIDTH; + ao_copy(dst, + x, y, GLYPH_WIDTH, GLYPH_HEIGHT, + &src_bitmap, + 0, 0, rop); + x += GLYPH_WIDTH; } } diff --git a/src/draw/font-convert b/src/draw/font-convert index 2446592b..80297cf9 100755 --- a/src/draw/font-convert +++ b/src/draw/font-convert @@ -11,6 +11,7 @@ typedef struct { typedef struct { glyph_t[...] glyphs; int default_char; + int ascent; } font_t; glyph_t @@ -29,8 +30,10 @@ read_glyph(file f) case "ENCODING": glyph.encoding = atoi(tokens[1]); break; - case "BBX": + case "DWIDTH": glyph.width = atoi(tokens[1]); + break; + case "BBX": glyph.height = atoi(tokens[2]); break; case "ENDCHAR": @@ -50,15 +53,23 @@ read_glyph(file f) font_t read_font(file f) { font_t font = { .glyphs = {}, .default_char = -1 }; + bool in_head = true; - while (!File::end(f)) { + while (in_head && !File::end(f)) { string l = File::fgets(f); string[*] tokens = String::split(l, " "); - if (tokens[0] == "DEFAULT_CHAR") + switch (tokens[0]) { + case "DEFAULT_CHAR": font.default_char = atoi(tokens[1]); - if (tokens[0] == "CHARS") break; + case "FONT_ASCENT": + font.ascent = atoi(tokens[1]); + break; + case "CHARS": + in_head = false; + break; + } } while (!File::end(f)) { glyph_t glyph = read_glyph(f); @@ -130,6 +141,7 @@ void print_font(font_t font) { printf("#define GLYPH_WIDTH %d\n", width); printf("#define GLYPH_HEIGHT %d\n", height); + printf("#define GLYPH_ASCENT %d\n", font.ascent); } twixt (file f = File::open(argv[1], "r"); File::close(f)) { |