Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/neutrinolabs/libpainter.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Sorg <jay.sorg@gmail.com>2015-08-02 03:31:32 +0300
committerJay Sorg <jay.sorg@gmail.com>2015-08-02 03:31:32 +0300
commit38bdebef70381c58ac8b8ae906f17ecd08ad5804 (patch)
tree92f7c9114eaf9667b8659816fc74f2ede8712a61
parent8e43175ebd018a6c53d7a5798d15237ebf04167f (diff)
work on painter
-rw-r--r--include/painter.h12
-rw-r--r--src/painter.c145
-rw-r--r--src/painter_utils.c78
-rw-r--r--src/painter_utils.h67
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