Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/filter/grlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/filter/grlib.c')
-rw-r--r--src/filter/grlib.c995
1 files changed, 995 insertions, 0 deletions
diff --git a/src/filter/grlib.c b/src/filter/grlib.c
new file mode 100644
index 0000000..74692d4
--- /dev/null
+++ b/src/filter/grlib.c
@@ -0,0 +1,995 @@
+#include <config.h>
+#ifdef _plan9_
+#include <u.h>
+#include <libc.h>
+#else
+#include <stdlib.h>
+#include <string.h>
+#endif
+#ifdef HAVE_GETTEXT
+#include <iconv.h>
+#endif
+#include <archaccel.h>
+
+#include <fconfig.h>
+#include <filter.h>
+#include <fractal.h>
+#include <ui_helper.h>
+#include <grlib.h>
+
+#define WIDTH(ch) (currentfont->width)
+#define RWIDTH(ch) (currentfont->realwidth)
+#define HEIGHT (currentfont->height)
+#define DATA currentfont->data
+
+extern CONST unsigned char xfont8[];
+extern CONST unsigned char xfont16[];
+extern CONST unsigned char xfont32[];
+extern CONST unsigned char xfont48[];
+extern CONST unsigned char xfont14[];
+extern CONST unsigned char xfont8il1[];
+extern CONST unsigned char xfont16il1[];
+extern CONST unsigned char xfont14il1[];
+unsigned char *aa_chardata;
+unsigned char *aa_colordata;
+int aa_cursorx, aa_cursory;
+static CONST struct xfont *currentfont;
+CONST struct xfont xaafont = {
+ NULL,
+ 2, 1, 2, 2
+};
+
+CONST struct xfont xsmallfont = {
+ xfont14,
+ 8, 14, 8, 2
+};
+
+CONST struct xfont xbigfont = {
+ xfont16,
+ 9, 16, 8, 2
+};
+
+CONST struct xfont xbigfont2 = {
+ xfont32,
+ 18, 32, 16, 2
+};
+
+CONST struct xfont xbigfont3 = {
+ xfont48,
+ 18, 48, 16, 2
+};
+
+CONST struct xfont xsmallfontil1 = {
+ xfont8il1,
+ 8, 8, 8, 1
+};
+
+CONST struct xfont xmedfontil1 = {
+ xfont14il1,
+ 8, 14, 8, 1
+};
+
+CONST struct xfont xbigfontil1 = {
+ xfont16il1,
+ 9, 16, 8, 1
+};
+
+#include <c256.h>
+#define drawchar drawchar8
+#define hline hline8
+#define vline vline8
+#define rectangle rectangle8
+#define savevline savevline8
+#define restorevline restorevline8
+#define line line8
+#define saveline saveline8
+#define restoreline restoreline8
+#include "grlibd.c"
+#include <hicolor.h>
+#define drawchar drawchar16
+#define hline hline16
+#define vline vline16
+#define rectangle rectangle16
+#define savevline savevline16
+#define restorevline restorevline16
+#define line line16
+#define saveline saveline16
+#define restoreline restoreline16
+#include "grlibd.c"
+#include <true24.h>
+#define drawchar drawchar24
+#define hline hline24
+#define vline vline24
+#define rectangle rectangle24
+#define savevline savevline24
+#define restorevline restorevline24
+#define line line24
+#define saveline saveline24
+#define restoreline restoreline24
+#include "grlibd.c"
+#include <truecolor.h>
+#define drawchar drawchar32
+#define hline hline32
+#define vline vline32
+#define rectangle rectangle32
+#define savevline savevline32
+#define restorevline restorevline32
+#define line line32
+#define saveline saveline32
+#define restoreline restoreline32
+#include "grlibd.c"
+#ifdef SBITMAPS
+static inline void
+drawchar1(struct image *img, int x, int y, int fgcolor,
+ unsigned char letter)
+{
+ int fontwidth = (RWIDTH(letter) + 7) / 8;
+ CONST unsigned char *bitmap = &DATA[letter * HEIGHT * fontwidth];
+ unsigned char *current;
+ int yend = y + HEIGHT;
+ if (y < 0)
+ bitmap -= y, y = 0;
+ if (yend > img->height)
+ yend = img->height;
+ for (; y < yend; y++) {
+ unsigned int b = *(bitmap++);
+ if (fontwidth == 2) {
+ b <<= 8;
+ b |= *bitmap++;
+ }
+ current = img->currlines[y] + x / 8;
+ b = b << (8 - ((x) & 7));
+#ifdef SLBITMAPS
+ if (img->palette->type & (LBITMAP | LIBITMAP)) {
+ /*Reverse order... */
+ b = ((b >> 1) & 0x5555) | ((b << 1) & 0xaaaa);
+ b = ((b >> 2) & 0x3333) | ((b << 2) & 0xcccc);
+ b = ((b >> 4) & 0x0f0f) | ((b << 4) & 0xf0f0);
+ }
+#endif
+ if (fgcolor) {
+ if (x & 7) {
+ current[1] |= b;
+ current[0] |= b >> 8;
+ } else
+ current[0] |= b >> 8;
+ } else {
+ if (x & 7) {
+ current[1] &= ~b;
+ current[0] &= ~(b >> 8);
+ } else
+ *current &= ~(b >> 8);
+ }
+ }
+}
+
+static void hline1(struct image *img, int x, int y, int l, int color)
+{
+ int x2 = x + l;
+ int c1 = 255;
+ int c2 = 255;
+ unsigned char *current = img->currlines[y] + x / 8;
+ unsigned char *currend = img->currlines[y] + x2 / 8;
+ if (img->palette->type & (LBITMAP | LIBITMAP)) {
+ c2 >>= x2 & 7;
+ c1 <<= 8 - (x & 7);
+ } else {
+ c1 >>= x & 7;
+ c2 <<= 8 - (x2 & 7);
+ }
+ if (current == currend) {
+ if (color)
+ *current |= c1 & c2;
+ else
+ *current &= ~(c1 & c2);
+ } else {
+ if (color) {
+ *current |= c1;
+ *currend |= c2;
+ memset(current + 1, (char) 255, currend - current - 1);
+ } else {
+ *current &= ~c1;
+ *currend &= ~c2;
+ memset(current + 1, 0, currend - current - 1);
+ }
+ }
+}
+
+static void vline1(struct image *img, int x, int y, int l, int color)
+{
+ unsigned char c = 128 >> (x & 7);
+ l += y;
+ x /= 8;
+ if (img->palette->type & (LBITMAP | LIBITMAP)) {
+ c = ((c >> 1) & 0x55) | ((c << 1) & 0xaa);
+ c = ((c >> 2) & 0x33) | ((c << 2) & 0xcc);
+ c = ((c >> 4) & 0x0f) | ((c << 4) & 0xf0);
+ }
+ if (color)
+ while (y <= l) {
+ unsigned char *current = img->currlines[y] + x;
+ *current |= c;
+ y++;
+ } else {
+ c = ~c;
+ while (y <= l) {
+ unsigned char *current = img->currlines[y] + x;
+ *current &= c;
+ y++;
+ }
+ }
+}
+
+static inline void
+rectangle1(struct image *img, int x, int y, int width, int height,
+ int fgcolor)
+{
+ height += y;
+ while (y < height)
+ hline1(img, x, y, width - 1, fgcolor), y++;
+}
+
+static inline void
+line1(struct image *img, int x, int y, int x2, int y2, int color)
+{
+ int dx = x2 - x;
+ int dy = y2 - y;
+ int ady = abs(dy);
+#ifdef SLBITMAPS
+ int type = img->palette->type;
+#endif
+ if (dx < ady) {
+ int plus = (dx << 16) / ady;
+ if (dy < 0) {
+ int dy = (x << 16) | (65536 / 2);
+ ady = y;
+#ifdef SLBITMAPS
+ if (type & (LBITMAP | LIBITMAP))
+ if (!color)
+ while (ady >= y2) {
+ unsigned char *current =
+ img->currlines[ady] + (dy >> 19);
+ *current &= ~(1 << ((dy >> 16) & 7));
+ dy += plus;
+ ady--;
+ } else
+ while (ady >= y2) {
+ unsigned char *current =
+ img->currlines[ady] + (dy >> 19);
+ *current |= (1 << ((dy >> 16) & 7));
+ dy += plus;
+ ady--;
+ } else
+#endif
+ if (!color)
+ while (ady >= y2) {
+ unsigned char *current =
+ img->currlines[ady] + (dy >> 19);
+ *current &= ~(128 >> ((dy >> 16) & 7));
+ dy += plus;
+ ady--;
+ } else
+ while (ady >= y2) {
+ unsigned char *current =
+ img->currlines[ady] + (dy >> 19);
+ *current |= (128 >> ((dy >> 16) & 7));
+ dy += plus;
+ ady--;
+ }
+ } else {
+ int dy = (x << 16) | (65536 / 2);
+ ady = y;
+#ifdef SLBITMAPS
+ if (type & (LBITMAP | LIBITMAP))
+ if (!color)
+ while (ady <= y2) {
+ unsigned char *current =
+ img->currlines[ady] + (dy >> 19);
+ *current &= ~(1 << ((dy >> 16) & 7));
+ dy += plus;
+ ady++;
+ } else
+ while (ady <= y2) {
+ unsigned char *current =
+ img->currlines[ady] + (dy >> 19);
+ *current |= (1 << ((dy >> 16) & 7));
+ dy += plus;
+ ady++;
+ } else
+#endif
+ if (!color)
+ while (ady <= y2) {
+ unsigned char *current =
+ img->currlines[ady] + (dy >> 19);
+ *current &= ~(128 >> ((dy >> 16) & 7));
+ dy += plus;
+ ady++;
+ } else
+ while (ady <= y2) {
+ unsigned char *current =
+ img->currlines[ady] + (dy >> 19);
+ *current |= (128 >> ((dy >> 16) & 7));
+ dy += plus;
+ ady++;
+ }
+ }
+ } else {
+ int plus = (dy << 16) / dx;
+ ady = x;
+ dy = (y << 16) | (65536 / 2);
+#ifdef SLBITMAPS
+ if (type & (LBITMAP | LIBITMAP))
+ if (!color)
+ while (ady <= x2) {
+ unsigned char *current =
+ img->currlines[dy >> 16] + (ady >> 3);
+ *current &= ~(1 << (ady & 7));
+ dy += plus;
+ ady++;
+ } else
+ while (ady <= x2) {
+ unsigned char *current =
+ img->currlines[dy >> 16] + (ady >> 3);
+ *current |= (1 << (ady & 7));
+ dy += plus;
+ ady++;
+ } else
+#endif
+ if (!color)
+ while (ady <= x2) {
+ unsigned char *current =
+ img->currlines[dy >> 16] + (ady >> 3);
+ *current &= ~(128 >> (ady & 7));
+ dy += plus;
+ ady++;
+ } else
+ while (ady <= x2) {
+ unsigned char *current =
+ img->currlines[dy >> 16] + (ady >> 3);
+ *current |= (128 >> (ady & 7));
+ dy += plus;
+ ady++;
+ }
+ }
+ return;
+}
+#endif
+
+static int skip(CONST char *text)
+{
+ int i = 0;
+ while (*text && *text != '\n')
+ i++, text++;
+ return (i);
+}
+
+#ifdef HAVE_GETTEXT
+int
+xiconv(int encoding, char *out, int *outlen, const char *in, int *inlen)
+{
+ /*
+ * Since the built-in text system only supports Latin-1 and Lqtin-2
+ * encodings, we must convert strings from the user's native encoding to
+ * either Latin-1 or Latin-2 encoding as appropriate for the selected
+ * language before passing them into the built-in text system. This
+ * function wraps the gnu iconv library for this purpose.
+ */
+
+ iconv_t cd;
+ char tocode[16];
+ size_t icv_inlen = *inlen, icv_outlen = *outlen;
+ const char *icv_in = (const char *) in;
+ char *icv_out = (char *) out;
+ int ret;
+
+ sprintf(tocode, "ISO-8859-%d", encoding);
+ cd = iconv_open(tocode, "UTF-8");
+ if (cd == (iconv_t) (-1))
+ return -1;
+
+ ret = iconv(cd, &icv_in, &icv_inlen, &icv_out, &icv_outlen);
+
+ if (in != NULL) {
+ *inlen -= icv_inlen;
+ *outlen -= icv_outlen;
+ out[*outlen] = '\0';
+ } else {
+ *inlen = 0;
+ *outlen = 0;
+ }
+
+ if (icv_inlen != 0 || ret == (size_t) - 1)
+ return -1;
+
+ ret = iconv_close(cd);
+
+ if (ret == -1)
+ return -1;
+
+ return 0;
+}
+#endif
+
+#ifndef PLATFORM_TEXT_RENDERING
+
+int
+xprint(struct image *image, CONST struct xfont *current, int x, int y,
+ CONST char *text, int fgcolor, int bgcolor, int mode)
+{
+ int i = 0;
+ int aacolor = 0;
+ char intext[BUFSIZ];
+ int inlen = strlen(text);
+ char outtext[BUFSIZ];
+ int outlen = BUFSIZ;
+ strncpy(intext, text, BUFSIZ);
+
+#ifdef HAVE_GETTEXT
+ if (current->encoding
+ && xiconv(current->encoding, outtext, &outlen, intext, &inlen) == 0)
+ text = outtext;
+#endif
+ if (!text[0])
+ return 0;
+ /*Do some clipping */
+ currentfont = current;
+ if (x + WIDTH(*text) > image->width)
+ return skip(text);
+ if (y + HEIGHT <= 0)
+ return skip(text);
+ if (y >= image->height)
+ return skip(text);
+ while (x < 0 && *text && *text != '\n')
+ text++, x += WIDTH(*text), i++;
+ if (x < 0)
+ return (skip(text) + i);
+
+ if (image->flags & AAIMAGE) {
+ aacolor = 0; /*normal */
+ if ((unsigned int) fgcolor == image->palette->index[2])
+ aacolor = 2;
+ if ((unsigned int) fgcolor == image->palette->index[0])
+ aacolor = 5; /*special */
+ }
+ /*Draw text visible letters */
+ while (x + WIDTH(*text) < image->width && *text && *text != '\n') {
+ if (image->flags & AAIMAGE) {
+ aa_colordata[x / 2 + y / 2 * (image->width / 2)] = aacolor;
+ aa_chardata[x / 2 + y / 2 * (image->width / 2)] = *text;
+ } else
+ switch (image->bytesperpixel) {
+#ifdef SBITMAPS
+ case 0:
+ if (mode == TEXT_PRESSED) {
+ drawchar1(image, x + 1, y + 1, fgcolor, *text);
+ } else {
+ drawchar1(image, x + 1, y + 1, bgcolor, *text);
+ drawchar1(image, x, y, fgcolor, *text);
+ }
+ break;
+#endif
+ case 1:
+ if (mode == TEXT_PRESSED) {
+ drawchar8(image, x + 1, y + 1, fgcolor, *text);
+ } else {
+ drawchar8(image, x + 1, y + 1, bgcolor, *text);
+ drawchar8(image, x, y, fgcolor, *text);
+ }
+ break;
+#ifdef SUPPORT16
+ case 2:
+ if (mode == TEXT_PRESSED) {
+ drawchar16(image, x + 1, y + 1, fgcolor, *text);
+ } else {
+ drawchar16(image, x + 1, y + 1, bgcolor, *text);
+ drawchar16(image, x, y, fgcolor, *text);
+ }
+ break;
+#endif
+#ifdef STRUECOLOR24
+ case 3:
+ if (mode == TEXT_PRESSED) {
+ drawchar24(image, x + 1, y + 1, fgcolor, *text);
+ } else {
+ drawchar24(image, x + 1, y + 1, bgcolor, *text);
+ drawchar24(image, x, y, fgcolor, *text);
+ }
+ break;
+#endif
+ case 4:
+ if (mode == TEXT_PRESSED) {
+ drawchar32(image, x + 1, y + 1, fgcolor, *text);
+ } else {
+ drawchar32(image, x + 1, y + 1, bgcolor, *text);
+ drawchar32(image, x, y, fgcolor, *text);
+ }
+ break;
+ }
+ x += WIDTH(*text);
+ text++;
+ i++;
+ }
+ /*
+ * We need to return the number of bytes used from the string that is
+ * passed into the function; not the number of characters displayed. The
+ * number of bytes and the number of characters is not always the same in
+ * UTF-8 encoding. So I changed this to count the number of bytes to
+ * the next newline or nul in the original string that was passed in.
+ */
+ /* return i + skip(text); */
+ return skip(intext);
+}
+
+int xtextwidth(CONST struct xfont *font, CONST char *text)
+{
+ int i;
+#ifdef HAVE_GETTEXT
+ char intext[BUFSIZ];
+ int inlen = strlen(text);
+ char outtext[BUFSIZ];
+ int outlen = BUFSIZ;
+
+ strncpy(intext, text, BUFSIZ);
+ if (font->encoding
+ && xiconv(font->encoding, outtext, &outlen, intext, &inlen) == 0)
+ text = outtext;
+#endif
+ for (i = 0; text[i] && text[i] != '\n'; i++);
+ if (font->width == 2)
+ return (i * font->width);
+ return (i * font->width + 1);
+}
+
+int xtextheight(CONST struct xfont *font)
+{
+ return font->height+1;
+}
+
+int xtextcharw(CONST struct xfont *font, CONST char c)
+{
+ return font->width;
+}
+
+#endif
+
+void xhline(struct image *image, int x, int y, int width, int fgcolor)
+{
+ /*Do some clipping */
+ if (x + width < 0 || y < 0 || y >= image->height || x >= image->width)
+ return;
+ if (x + width >= image->width - 1)
+ width = image->width - x - 2;
+ if (x < 0)
+ width += x, x = 0;
+ if (width < 0)
+ return;
+ switch (image->bytesperpixel) {
+#ifdef SBITMAPS
+ case 0:
+ hline1(image, x, y, width, fgcolor);
+ break;
+#endif
+ case 1:
+ hline8(image, x, y, width, fgcolor);
+ break;
+#ifdef SUPPORT16
+ case 2:
+ hline16(image, x, y, width, fgcolor);
+ break;
+#endif
+#ifdef STRUECOLOR24
+ case 3:
+ hline24(image, x, y, width, fgcolor);
+ break;
+#endif
+ case 4:
+ hline32(image, x, y, width, fgcolor);
+ break;
+ }
+}
+
+void xvline(struct image *image, int x, int y, int height, int fgcolor)
+{
+ /*Do some clipping */
+ if (x < 0 || y + height < 0 || y >= image->height || x >= image->width)
+ return;
+ if (y + height >= image->height - 1)
+ height = image->height - y - 2;
+ if (y < 0)
+ height += y, y = 0;
+ if (height < 0)
+ return;
+ switch (image->bytesperpixel) {
+#ifdef SBITMAPS
+ case 0:
+ vline1(image, x, y, height, fgcolor);
+ break;
+#endif
+ case 1:
+ vline8(image, x, y, height, fgcolor);
+ break;
+#ifdef SUPPORT16
+ case 2:
+ vline16(image, x, y, height, fgcolor);
+ break;
+#endif
+#ifdef STRUECOLOR24
+ case 3:
+ vline24(image, x, y, height, fgcolor);
+ break;
+#endif
+ case 4:
+ vline32(image, x, y, height, fgcolor);
+ break;
+ }
+}
+
+void
+xrectangle(struct image *image, int x, int y, int width, int height,
+ int fgcolor)
+{
+ /*Do some clipping */
+ if (x + width < 0 || y + height < 0 || y >= image->height
+ || x >= image->width)
+ return;
+ if (x + width >= image->width)
+ width = image->width - x;
+ if (x < 0)
+ width += x, x = 0;
+ if (width < 0)
+ return;
+ if (y + height >= image->height)
+ height = image->height - y;
+ if (y < 0)
+ height += y, y = 0;
+ if (height < 0)
+ return;
+ if (image->flags & AAIMAGE) {
+ int x1, y1;
+ for (x1 = x / 2; x1 < (x + width) / 2; x1++)
+ for (y1 = y / 2; y1 < (y + height) / 2; y1++)
+ aa_colordata[x1 + y1 * image->width / 2] = 255;
+ }
+ switch (image->bytesperpixel) {
+#ifdef SBITMAPS
+ case 0:
+ rectangle1(image, x, y, width, height, fgcolor);
+ break;
+#endif
+ case 1:
+ rectangle8(image, x, y, width, height, fgcolor);
+ break;
+#ifdef SUPPORT16
+ case 2:
+ rectangle16(image, x, y, width, height, fgcolor);
+ break;
+#endif
+#ifdef STRUECOLOR24
+ case 3:
+ rectangle24(image, x, y, width, height, fgcolor);
+ break;
+#endif
+ case 4:
+ rectangle32(image, x, y, width, height, fgcolor);
+ break;
+ }
+}
+
+static inline char *savehline(struct image *i, int x1, int y, int x2)
+{
+ int start, end;
+ char *c;
+ if (!i->bytesperpixel)
+ start = (x1) / 8, end = (x2 + 1 + 7) / 8;
+ else
+ start = x1 * i->bytesperpixel, end = (x2 + 1) * i->bytesperpixel;
+ c = (char *) malloc(end - start);
+ if (c == NULL)
+ return NULL;
+ memcpy(c, i->currlines[y] + start, end - start);
+ return c;
+}
+
+static inline void
+restorehline(struct image *i, char *c, int x1, int y, int x2)
+{
+ int start, end;
+ if (!i->bytesperpixel)
+ start = (x1) / 8, end = (x2 + 1 + 7) / 8;
+ else
+ start = x1 * i->bytesperpixel, end = (x2 + 1) * i->bytesperpixel;
+ memcpy(i->currlines[y] + start, c, end - start);
+}
+
+#define __clipx1 0
+#define __clipy1 0
+#define __clipx2 (img->width-2)
+#define __clipy2 (img->height-2)
+static inline int regioncode(struct image *img, const int x, const int y)
+{
+ int dx1, dx2, dy1, dy2;
+ int result;
+ result = 0;
+ dy2 = __clipy2 - y;
+ if (dy2 < 0)
+ result++;
+ result <<= 1;
+ dy1 = y - __clipy1;
+ if (dy1 < 0)
+ result++;
+ result <<= 1;
+ dx2 = __clipx2 - x;
+ if (dx2 < 0)
+ result++;
+ result <<= 1;
+ dx1 = x - __clipx1;
+ if (dx1 < 0)
+ result++;
+ return result;
+}
+
+#define swap(x, y) { int temp = x; x = y; y = temp; }
+#define doclip(ret) \
+ for (;;) \
+ { \
+ int r1 = regioncode (img, x1, y1); \
+ int r2 = regioncode (img, x2, y2); \
+ if (!(r1 | r2)) \
+ break; /* completely inside */ \
+ if (r1 & r2) \
+ ret; /* completely outside */ \
+ if (r1 == 0) \
+ { \
+ swap (x1, x2); /* make sure first */ \
+ swap (y1, y2); /* point is outside */ \
+ r1 = r2; \
+ } \
+ if (r1 & 1) \
+ { /* left */ \
+ y1 += (long) (__clipx1 - x1) * (long) (y2 - y1) / (long) (x2 - x1); \
+ x1 = __clipx1; \
+ } \
+ else if (r1 & 2) \
+ { /* right */ \
+ y1 += (long) (__clipx2 - x1) * (long) (y2 - y1) / (long) (x2 - x1); \
+ x1 = __clipx2; \
+ } \
+ else if (r1 & 4) \
+ { /* top */ \
+ x1 += (long) (__clipy1 - y1) * (long) (x2 - x1) / (long) (y2 - y1); \
+ y1 = __clipy1; \
+ } \
+ else if (r1 & 8) \
+ { /* bottom */ \
+ x1 += (long) (__clipy2 - y1) * (long) (x2 - x1) / (long) (y2 - y1); \
+ y1 = __clipy2; \
+ } \
+ } \
+ if(x2<x1) { \
+ swap(x1,x2); \
+ swap(y1,y2); \
+ }
+
+void xline(struct image *img, int x1, int y1, int x2, int y2, int color)
+{
+ doclip(return);
+ if (x1 == x2) {
+ if (y2 < y1) {
+ swap(y1, y2);
+ }
+ switch (img->bytesperpixel) {
+#ifdef SBITMAPS
+ case 0:
+ vline1(img, x1, y1, y2 - y1, color);
+ break;
+#endif
+ case 1:
+ vline8(img, x1, y1, y2 - y1, color);
+ break;
+#ifdef SUPPORT16
+ case 2:
+ vline16(img, x1, y1, y2 - y1, color);
+ break;
+#endif
+#ifdef STRUECOLOR24
+ case 3:
+ vline24(img, x1, y1, y2 - y1, color);
+ break;
+#endif
+ case 4:
+ vline32(img, x1, y1, y2 - y1, color);
+ break;
+ }
+ } else if (y1 == y2) {
+ switch (img->bytesperpixel) {
+#ifdef SBITMAPS
+ case 0:
+ hline1(img, x1, y1, x2 - x1, color);
+ break;
+#endif
+ case 1:
+ hline8(img, x1, y1, x2 - x1, color);
+ break;
+#ifdef SUPPORT16
+ case 2:
+ hline16(img, x1, y1, x2 - x1, color);
+ break;
+#endif
+#ifdef STRUECOLOR24
+ case 3:
+ hline24(img, x1, y1, x2 - x1, color);
+ break;
+#endif
+ case 4:
+ hline32(img, x1, y1, x2 - x1, color);
+ break;
+ }
+ } else {
+ switch (img->bytesperpixel) {
+#ifdef SBITMAPS
+ case 0:
+ line1(img, x1, y1, x2, y2, color);
+ break;
+#endif
+ case 1:
+ line8(img, x1, y1, x2, y2, color);
+ break;
+#ifdef SUPPORT16
+ case 2:
+ line16(img, x1, y1, x2, y2, color);
+ break;
+#endif
+#ifdef STRUECOLOR24
+ case 3:
+ line24(img, x1, y1, x2, y2, color);
+ break;
+#endif
+ case 4:
+ line32(img, x1, y1, x2, y2, color);
+ break;
+ }
+ }
+}
+
+char *xsaveline(struct image *img, int x1, int y1, int x2, int y2)
+{
+ doclip(return (NULL));
+ if (y1 == y2) {
+ return (savehline(img, x1, y1, x2));
+ } else if (x1 == x2) {
+ if (y2 < y1) {
+ swap(y1, y2);
+ }
+ switch (img->bytesperpixel) {
+#ifdef SBITMAPS
+ case 0:
+ return (savevline8(img, x1 / 8, y1, y2 - y1));
+#endif
+ case 1:
+ return (savevline8(img, x1, y1, y2 - y1));
+#ifdef SUPPORT16
+ case 2:
+ return (savevline16(img, x1, y1, y2 - y1));
+#endif
+#ifdef STRUECOLOR24
+ case 3:
+ return (savevline24(img, x1, y1, y2 - y1));
+#endif
+ case 4:
+ return (savevline32(img, x1, y1, y2 - y1));
+ }
+ } else {
+ switch (img->bytesperpixel) {
+#ifdef SBITMAPS
+ case 0:
+ if (x2 > img->height - 15)
+ x2 = img->height - 15;
+ if (x1 > img->height - 15)
+ x1 = img->height - 15;
+ return (saveline8(img, (x1 / 8), y1, (x2 / 8), y2));
+#endif
+ case 1:
+ return (saveline8(img, x1, y1, x2, y2));
+#ifdef SUPPORT16
+ case 2:
+ return (saveline16(img, x1, y1, x2, y2));
+#endif
+#ifdef STRUECOLOR24
+ case 3:
+ return (saveline24(img, x1, y1, x2, y2));
+#endif
+ case 4:
+ return (saveline32(img, x1, y1, x2, y2));
+ }
+ }
+ return NULL;
+}
+
+void xprepareimage(struct image *img)
+{
+ if (img->flags & AAIMAGE) {
+ memset(aa_colordata, (char) 255, img->width * img->height / 4);
+ }
+ aa_cursorx = -1;
+ aa_cursory = -1;
+}
+
+void xdrawcursor(struct image *img, int x, int y, int color, int height)
+{
+ if (img->flags & AAIMAGE) {
+ aa_cursorx = x / 2;
+ aa_cursory = y / 2;
+ } else {
+ xvline(img, x, y, height, color);
+ xhline(img, x - 1, y - 1, 1, color);
+ xhline(img, x + 1, y - 1, 1, color);
+ xhline(img, x - 1, y + height, 1, color);
+ xhline(img, x + 1, y + height, 1, color);
+ }
+}
+
+void
+xrestoreline(struct image *img, char *data, int x1, int y1, int x2, int y2)
+{
+ doclip(return);
+ if (y1 == y2) {
+ restorehline(img, data, x1, y1, x2);
+ return;
+ } else if (x1 == x2) {
+ if (y2 < y1) {
+ swap(y1, y2);
+ }
+ switch (img->bytesperpixel) {
+#ifdef SBITMAPS
+ case 0:
+ restorevline8(img, data, x1 / 8, y1, y2 - y1);
+ break;
+#endif
+ case 1:
+ restorevline8(img, data, x1, y1, y2 - y1);
+ break;
+#ifdef SUPPORT16
+ case 2:
+ restorevline16(img, data, x1, y1, y2 - y1);
+ break;
+#endif
+#ifdef STRUECOLOR24
+ case 3:
+ restorevline24(img, data, x1, y1, y2 - y1);
+ break;
+#endif
+ case 4:
+ restorevline32(img, data, x1, y1, y2 - y1);
+ break;
+ }
+ } else {
+ switch (img->bytesperpixel) {
+#ifdef SBITMAPS
+ case 0:
+ if (x2 > img->height - 15)
+ x2 = img->height - 15;
+ if (x1 > img->height - 15)
+ x1 = img->height - 15;
+ restoreline8(img, data, x1 / 8, y1, x2 / 8, y2);
+ break;
+#endif
+ case 1:
+ restoreline8(img, data, x1, y1, x2, y2);
+ break;
+#ifdef SUPPORT16
+ case 2:
+ restoreline16(img, data, x1, y1, x2, y2);
+ break;
+#endif
+#ifdef STRUECOLOR24
+ case 3:
+ restoreline24(img, data, x1, y1, x2, y2);
+ break;
+#endif
+ case 4:
+ restoreline32(img, data, x1, y1, x2, y2);
+ break;
+ }
+ }
+ return;
+}