diff options
author | Jay Sorg <jay.sorg@gmail.com> | 2015-08-02 03:31:32 +0300 |
---|---|---|
committer | Jay Sorg <jay.sorg@gmail.com> | 2015-08-02 03:31:32 +0300 |
commit | 38bdebef70381c58ac8b8ae906f17ecd08ad5804 (patch) | |
tree | 92f7c9114eaf9667b8659816fc74f2ede8712a61 | |
parent | 8e43175ebd018a6c53d7a5798d15237ebf04167f (diff) |
work on painter
-rw-r--r-- | include/painter.h | 12 | ||||
-rw-r--r-- | src/painter.c | 145 | ||||
-rw-r--r-- | src/painter_utils.c | 78 | ||||
-rw-r--r-- | src/painter_utils.h | 67 |
4 files changed, 260 insertions, 42 deletions
diff --git a/include/painter.h b/include/painter.h index 8cdf32a..e5e5933 100644 --- a/include/painter.h +++ b/include/painter.h @@ -30,6 +30,11 @@ #define PT_FORMAT_r3g3b2 \ ((8 << 24) | (2 << 16) | (0 << 12) | (3 << 8) | (3 << 4) | 2) +#define PT_FORMAT_c1 \ +((1 << 24) | (4 << 16) | (0 << 12) | (0 << 8) | (0 << 4) | 0) +#define PT_FORMAT_c8 \ +((8 << 24) | (4 << 16) | (0 << 12) | (0 << 8) | (0 << 4) | 0) + struct painter_bitmap { int format; @@ -43,12 +48,15 @@ struct painter_bitmap #define PT_ERROR_OUT_OF_MEM 1 #define PT_ERROR_PARAM 2 +#define PT_PATTERN_MODE_NORMAL 0 +#define PT_PATTERN_MODE_OPAQUE 1 + #define PT_LINE_FLAGS_NONE 0 /* reverse Windows X11 */ /* polish */ #define PT_ROP_0 0x00 /* 0 BLACKNESS GXclear */ -#define PT_ROP_DSon 0x11 /* Dson NOTSRCERASE GXnor */ +#define PT_ROP_DSon 0x11 /* DSon NOTSRCERASE GXnor */ #define PT_ROP_DSna 0x22 /* DSna GXandInverted */ #define PT_ROP_Sn 0x33 /* Sn NOTSRCCOPY GXcopyInverted */ #define PT_ROP_SDna 0x44 /* SDna SRCERASE GXandReverse */ @@ -75,7 +83,7 @@ painter_set_bgcolor(void *handle, int color); int painter_set_rop(void *handle, int rop); int -painter_set_fill_mode(void *handle, int mode); +painter_set_pattern_mode(void *handle, int mode); int painter_set_pattern_origin(void *handle, int x, int y); int diff --git a/src/painter.c b/src/painter.c index 21486a1..53ad9e8 100644 --- a/src/painter.c +++ b/src/painter.c @@ -93,12 +93,12 @@ painter_set_rop(void *handle, int rop) /*****************************************************************************/ int -painter_set_fill_mode(void *handle, int mode) +painter_set_pattern_mode(void *handle, int mode) { struct painter *pt; pt = (struct painter *) handle; - pt->fill_mode = mode; + pt->pattern_mode = mode; return PT_ERROR_NONE; } @@ -166,6 +166,36 @@ painter_fill_pattern(void *handle, struct painter_bitmap *dst, struct painter_bitmap *pat, int patx, int paty, int x, int y, int cx, int cy) { + int index; + int jndex; + int pixel; + int lx; + int ly; + struct painter *pt; + + pt = (struct painter *) handle; + for (jndex = 0; jndex < cy; jndex++) + { + for (index = 0; index < cx; index++) + { + lx = (patx + index + pt->origin_x) % pat->width; + ly = (paty + jndex + pt->origin_y) % pat->height; + pixel = bitmap_get_pixel(pat, lx, ly); + if (pixel != 0) + { + painter_set_pixel(pt, dst, x + index, y + jndex, + pt->fgcolor, dst->format); + } + else + { + if (pt->pattern_mode == PT_PATTERN_MODE_OPAQUE) + { + painter_set_pixel(pt, dst, x + index, y + jndex, + pt->bgcolor, dst->format); + } + } + } + } return PT_ERROR_NONE; } @@ -175,14 +205,125 @@ painter_copy(void *handle, struct painter_bitmap *dst, int x, int y, int cx, int cy, struct painter_bitmap *src, int srcx, int srcy) { + int index; + int jndex; + int pixel; + struct painter *pt; + + pt = (struct painter *) handle; + if ((srcy < y) || ((srcy == y) && (srcx < x))) /* straight right or down */ + { + for (jndex = cy - 1; jndex >= 0; jndex--) + { + for (index = cx - 1; index >= 0; index--) + { + pixel = painter_get_pixel(pt, src, srcx + index, + srcy + jndex); + painter_set_pixel(pt, dst, x + index, y + jndex, + pixel, src->format); + } + } + } + else + { + for (jndex = 0; jndex < cy; jndex++) + { + for (index = 0; index < cx; index++) + { + pixel = painter_get_pixel(pt, src, srcx + index, + srcy + jndex); + painter_set_pixel(pt, dst, x + index, y + jndex, + pixel, src->format); + } + } + } return PT_ERROR_NONE; } /*****************************************************************************/ +/* Bresenham's line drawing algorithm */ int painter_line(void *handle, struct painter_bitmap *dst, int x1, int y1, int x2, int y2, int width, int flags) { + int dx; + int dy; + int incx; + int incy; + int dpr; + int dpru; + int p; + struct painter *pt; + + pt = (struct painter *) handle; + if (x1 > x2) + { + dx = x1 - x2; + incx = -1; + } + else + { + dx = x2 - x1; + incx = 1; + } + if (y1 > y2) + { + dy = y1 - y2; + incy = -1; + } + else + { + dy = y2 - y1; + incy = 1; + } + if (dx >= dy) + { + dpr = dy << 1; + dpru = dpr - (dx << 1); + p = dpr - dx; + for (; dx >= 0; dx--) + { + if (x1 != x2 || y1 != y2) + { + painter_set_pixel(pt, dst, x1, y1, pt->fgcolor, dst->format); + } + if (p > 0) + { + x1 += incx; + y1 += incy; + p += dpru; + } + else + { + x1 += incx; + p += dpr; + } + } + } + else + { + dpr = dx << 1; + dpru = dpr - (dy << 1); + p = dpr - dy; + for (; dy >= 0; dy--) + { + if (x1 != x2 || y1 != y2) + { + painter_set_pixel(pt, dst, x1, y1, pt->fgcolor, dst->format); + } + if (p > 0) + { + x1 += incx; + y1 += incy; + p += dpru; + } + else + { + y1 += incy; + p += dpr; + } + } + } return PT_ERROR_NONE; } diff --git a/src/painter_utils.c b/src/painter_utils.c index 60d31b3..ebcbe23 100644 --- a/src/painter_utils.c +++ b/src/painter_utils.c @@ -55,14 +55,24 @@ char * bitmap_get_ptr(struct painter_bitmap *bitmap, int x, int y) { char *p; + int bpp; int Bpp; if ((x >= 0) && (x < bitmap->width) && (y >= 0) && (y < bitmap->height)) { - Bpp = ((bitmap->format >> 24) + 7) / 8; - p = bitmap->data + (y * bitmap->stride_bytes) + (x * Bpp); - return p; + bpp = bitmap->format >> 24; + if (bpp < 8) + { + p = bitmap->data + (y * bitmap->stride_bytes) + (x / 8); + return p; + } + else + { + Bpp = (bpp + 7) / 8; + p = bitmap->data + (y * bitmap->stride_bytes) + (x * Bpp); + return p; + } } else { @@ -71,12 +81,17 @@ bitmap_get_ptr(struct painter_bitmap *bitmap, int x, int y) } /*****************************************************************************/ -static int +int bitmap_get_pixel(struct painter_bitmap *bitmap, int x, int y) { char *ptr; + int rv; ptr = bitmap_get_ptr(bitmap, x, y); + if (ptr == NULL) + { + return 0; + } switch (bitmap->format) { case PT_FORMAT_a8b8g8r8: @@ -89,17 +104,27 @@ bitmap_get_pixel(struct painter_bitmap *bitmap, int x, int y) return *((unsigned short *) ptr); case PT_FORMAT_r3g3b2: return *((unsigned char *) ptr); + case PT_FORMAT_c1: + rv = *((unsigned char *) ptr); + rv = (rv & (0x80 >> (x % 8))) != 0; + return rv; + case PT_FORMAT_c8: + return *((unsigned char *) ptr); } return 0; } /*****************************************************************************/ -static int +int bitmap_set_pixel(struct painter_bitmap *bitmap, int x, int y, int pixel) { char *ptr; ptr = bitmap_get_ptr(bitmap, x, y); + if (ptr == NULL) + { + return 0; + } switch (bitmap->format) { case PT_FORMAT_a8b8g8r8: @@ -157,7 +182,7 @@ pixel_convert(int pixel, int src_format, int dst_format, int *palette) switch (dst_format) { case PT_FORMAT_a8r8g8b8: - rv = (a << 24) | (r << 16) | (g << 8) | b; + MAKE_a8r8g8b8(rv, a, r, g, b); break; } return rv; @@ -165,24 +190,53 @@ pixel_convert(int pixel, int src_format, int dst_format, int *palette) /*****************************************************************************/ int -painter_set_pixel(struct painter *painter, struct painter_bitmap *dst, +painter_get_pixel(struct painter *painter, struct painter_bitmap *bitmap, + int x, int y) +{ + int rv; + + rv = 0; + if ((x >= 0) && (x < bitmap->width) && + (y >= 0) && (y < bitmap->height)) + { + switch (bitmap->format) + { + case PT_FORMAT_c1: + rv = bitmap_get_pixel(bitmap, x, y); + rv = rv ? painter->fgcolor : painter->bgcolor; + break; + case PT_FORMAT_c8: + rv = bitmap_get_pixel(bitmap, x, y); + rv = painter->palette[rv & 0xff]; + break; + default: + rv = bitmap_get_pixel(bitmap, x, y); + break; + } + } + return rv; +} + +/*****************************************************************************/ +int +painter_set_pixel(struct painter *painter, struct painter_bitmap *bitmap, int x, int y, int pixel, int pixel_format) { if ((painter->clip_valid == 0) || ((x >= painter->clip.x1) && (x < painter->clip.x2) && (y >= painter->clip.y1) && (y < painter->clip.y2))) { - if ((x >= 0) && (x < dst->width) && - (y >= 0) && (y < dst->height)) + if ((x >= 0) && (x < bitmap->width) && + (y >= 0) && (y < bitmap->height)) { - pixel = pixel_convert(pixel, pixel_format, dst->format, + pixel = pixel_convert(pixel, pixel_format, bitmap->format, painter->palette); if (painter->rop != PT_ROP_S) { pixel = do_rop(painter->rop, pixel, - bitmap_get_pixel(dst, x, y)); + bitmap_get_pixel(bitmap, x, y)); } - bitmap_set_pixel(dst, x, y, pixel); + bitmap_set_pixel(bitmap, x, y, pixel); } } return 0; diff --git a/src/painter_utils.h b/src/painter_utils.h index aefc9e2..56f1bd7 100644 --- a/src/painter_utils.h +++ b/src/painter_utils.h @@ -19,44 +19,52 @@ #if !defined(__PAINTER_UTILS_H) #define __PAINTER_UTILS_H -#define SPLIT_a8r8g8b8(c, a, r, g, b) \ +#define SPLIT_a8r8g8b8(_c, _a, _r, _g, _b) \ do { \ - a = (c & 0xff000000) >> 24; \ - r = (c & 0x00ff0000) >> 16; \ - g = (c & 0x0000ff00) >> 8; \ - b = (c & 0x000000ff) >> 0; \ + _a = ((_c) & 0xff000000) >> 24; \ + _r = ((_c) & 0x00ff0000) >> 16; \ + _g = ((_c) & 0x0000ff00) >> 8; \ + _b = ((_c) & 0x000000ff) >> 0; \ } while (0) -#define SPLIT_a8b8g8r8(c, a, r, g, b) \ +#define SPLIT_a8b8g8r8(_c, _a, _r, _g, _b) \ do { \ - a = (c & 0xff000000) >> 24; \ - b = (c & 0x00ff0000) >> 16; \ - g = (c & 0x0000ff00) >> 8; \ - r = (c & 0x000000ff) >> 0; \ + _a = ((_c) & 0xff000000) >> 24; \ + _b = ((_c) & 0x00ff0000) >> 16; \ + _g = ((_c) & 0x0000ff00) >> 8; \ + _r = ((_c) & 0x000000ff) >> 0; \ } while (0) -#define SPLIT_a1r5g5b5(c, a, r, g, b) \ +#define SPLIT_a1r5g5b5(_c, _a, _r, _g, _b) \ do { \ - a = (c & 0x8000) ? 0xff : 0; \ - r = ((c >> 7) & 0xf8) | ((c >> 12) & 0x7); \ - g = ((c >> 2) & 0xf8) | ((c >> 8) & 0x7); \ - b = ((c << 3) & 0xf8) | ((c >> 2) & 0x7); \ + _a = (((_c) >> 15) & 1) * 0xff; \ + _r = (((_c) >> 7) & 0xf8) | (((_c) >> 12) & 0x7); \ + _g = (((_c) >> 2) & 0xf8) | (((_c) >> 8) & 0x7); \ + _b = (((_c) << 3) & 0xf8) | (((_c) >> 2) & 0x7); \ } while (0) -#define SPLIT_r5g6b5(c, a, r, g, b) \ +#define SPLIT_r5g6b5(_c, _a, _r, _g, _b) \ do { \ - a = 0xff; \ - r = ((c >> 8) & 0xf8) | ((c >> 13) & 0x7); \ - g = ((c >> 3) & 0xfc) | ((c >> 9) & 0x3); \ - b = ((c << 3) & 0xf8) | ((c >> 2) & 0x7); \ + _a = 0xff; \ + _r = (((_c) >> 8) & 0xf8) | (((_c) >> 13) & 0x7); \ + _g = (((_c) >> 3) & 0xfc) | (((_c) >> 9) & 0x3); \ + _b = (((_c) << 3) & 0xf8) | (((_c) >> 2) & 0x7); \ } while (0) -#define SPLIT_r3g3b2(c, a, r, g, b) \ +#define SPLIT_r3g3b2(_c, _a, _r, _g, _b) \ do { \ - a = 0xff; \ - r = 0; \ - g = 0; \ - b = 0; \ + _a = 0xff; \ + _r = 0; \ + _g = 0; \ + _b = 0; \ +} while (0) + +#define MAKE_a8r8g8b8(_c, _a, _r, _g, _b) \ +do { \ + _c = ((_a) & 0xff) << 24 | \ + ((_r) & 0xff) << 16 | \ + ((_g) & 0xff) << 8 | \ + ((_b) & 0xff) << 0; \ } while (0) struct painter_rect @@ -72,7 +80,7 @@ struct painter int rop; int fgcolor; int bgcolor; - int fill_mode; + int pattern_mode; int clip_valid; struct painter_rect clip; int origin_x; @@ -83,7 +91,14 @@ struct painter int painter_rop(int rop, int src, int dst); int +painter_get_pixel(struct painter *painter, struct painter_bitmap *bitmap, + int x, int y); +int painter_set_pixel(struct painter *painter, struct painter_bitmap *dst, int x, int y, int pixel, int pixel_format); +int +bitmap_get_pixel(struct painter_bitmap *bitmap, int x, int y); +int +bitmap_set_pixel(struct painter_bitmap *bitmap, int x, int y, int pixel); #endif |