- break;
- case RenderTexture::Sunken:
- switch (texture.bevel()) {
- case RenderTexture::Bevel1:
- XDrawLine(**display, sf.pixmap(), texture.bevelLightColor().gc(),
- left, bottom, right, bottom);
- XDrawLine(**display, sf.pixmap(), texture.bevelLightColor().gc(),
- right, bottom, right, top);
-
- XDrawLine(**display, sf.pixmap(), texture.bevelDarkColor().gc(),
- left, top, right, top);
- XDrawLine(**display, sf.pixmap(), texture.bevelDarkColor().gc(),
- left, bottom, left, top);
- break;
- case RenderTexture::Bevel2:
- XDrawLine(**display, sf.pixmap(), texture.bevelLightColor().gc(),
- left + 1, bottom - 2, right - 2, bottom - 2);
- XDrawLine(**display, sf.pixmap(), texture.bevelLightColor().gc(),
- right - 2, bottom - 2, right - 2, top + 1);
-
- XDrawLine(**display, sf.pixmap(), texture.bevelDarkColor().gc(),
- left + 1, top + 1, right - 2, top + 1);
- XDrawLine(**display, sf.pixmap(), texture.bevelDarkColor().gc(),
- left + 1, bottom - 2, left + 1, top + 1);
-
- break;
- default:
- assert(false); // unhandled RenderTexture::BevelType
+ *datav = COLOR(x);
+ ++datav;
+
+ /* copy the first row to the rest in O(logn) copies */
+ datac = (gchar*)datav;
+ cpbytes = 1 * w * sizeof(RrPixel32);
+ for (y = (h - 1) * w * sizeof(RrPixel32); y > 0;) {
+ memcpy(datac, data, cpbytes);
+ y -= cpbytes;
+ datac += cpbytes;
+ cpbytes <<= 1;
+ if (cpbytes > y)
+ cpbytes = y;
+ }
+}
+
+static void gradient_mirrorhorizontal(RrSurface *sf, gint w, gint h)
+{
+ gint x, y, half1, half2, cpbytes;
+ RrPixel32 *data = sf->pixel_data, *datav;
+ gchar *datac;
+
+ VARS(x);
+
+ half1 = (w + 1) / 2;
+ half2 = w / 2;
+
+ /* set the color values for the first row */
+
+ SETUP(x, sf->primary, sf->secondary, half1);
+ datav = data;
+ for (x = half1 - 1; x > 0; --x) { /* 0 -> half1 - 1 */
+ *datav = COLOR(x);
+ ++datav;
+ NEXT(x);
+ }
+ *datav = COLOR(x);
+ ++datav;
+
+ if (half2 > 0) {
+ SETUP(x, sf->secondary, sf->primary, half2);
+ for (x = half2 - 1; x > 0; --x) { /* 0 -> half2 - 1 */
+ *datav = COLOR(x);
+ ++datav;
+ NEXT(x);
+ }
+ *datav = COLOR(x);
+ ++datav;
+ }
+
+ /* copy the first row to the rest in O(logn) copies */
+ datac = (gchar*)datav;
+ cpbytes = 1 * w * sizeof(RrPixel32);
+ for (y = (h - 1) * w * sizeof(RrPixel32); y > 0;) {
+ memcpy(datac, data, cpbytes);
+ y -= cpbytes;
+ datac += cpbytes;
+ cpbytes <<= 1;
+ if (cpbytes > y)
+ cpbytes = y;
+ }
+}
+
+static void gradient_vertical(RrSurface *sf, gint w, gint h)
+{
+ gint y;
+ RrPixel32 *data;
+
+ VARS(y);
+ SETUP(y, sf->primary, sf->secondary, h);
+
+ /* find the color for the first pixel of each row first */
+ data = sf->pixel_data;
+
+ for (y = h - 1; y > 0; --y) { /* 0 -> h-1 */
+ *data = COLOR(y);
+ data += w;
+ NEXT(y);
+ }
+ *data = COLOR(y);
+
+ /* copy the first pixels into the whole rows */
+ data = sf->pixel_data;
+ for (y = h; y > 0; --y) {
+ repeat_pixel(data, w);
+ data += w;
+ }
+}
+
+
+static void gradient_diagonal(RrSurface *sf, gint w, gint h)
+{
+ gint x, y;
+ RrPixel32 *data = sf->pixel_data;
+ RrColor left, right;
+ RrColor extracorner;
+
+ VARS(lefty);
+ VARS(righty);
+ VARS(x);
+
+ extracorner.r = (sf->primary->r + sf->secondary->r) / 2;
+ extracorner.g = (sf->primary->g + sf->secondary->g) / 2;
+ extracorner.b = (sf->primary->b + sf->secondary->b) / 2;
+
+ SETUP(lefty, sf->primary, (&extracorner), h);
+ SETUP(righty, (&extracorner), sf->secondary, h);
+
+ for (y = h - 1; y > 0; --y) { /* 0 -> h-1 */
+ COLOR_RR(lefty, (&left));
+ COLOR_RR(righty, (&right));
+
+ SETUP(x, (&left), (&right), w);
+
+ for (x = w - 1; x > 0; --x) { /* 0 -> w-1 */
+ *(data++) = COLOR(x);
+
+ NEXT(x);
+ }
+ *(data++) = COLOR(x);
+
+ NEXT(lefty);
+ NEXT(righty);
+ }
+ COLOR_RR(lefty, (&left));
+ COLOR_RR(righty, (&right));
+
+ SETUP(x, (&left), (&right), w);
+
+ for (x = w - 1; x > 0; --x) { /* 0 -> w-1 */
+ *(data++) = COLOR(x);
+
+ NEXT(x);
+ }
+ *data = COLOR(x);
+}
+
+static void gradient_crossdiagonal(RrSurface *sf, gint w, gint h)
+{
+ gint x, y;
+ RrPixel32 *data = sf->pixel_data;
+ RrColor left, right;
+ RrColor extracorner;
+
+ VARS(lefty);
+ VARS(righty);
+ VARS(x);
+
+ extracorner.r = (sf->primary->r + sf->secondary->r) / 2;
+ extracorner.g = (sf->primary->g + sf->secondary->g) / 2;
+ extracorner.b = (sf->primary->b + sf->secondary->b) / 2;
+
+ SETUP(lefty, (&extracorner), sf->secondary, h);
+ SETUP(righty, sf->primary, (&extracorner), h);
+
+ for (y = h - 1; y > 0; --y) { /* 0 -> h-1 */
+ COLOR_RR(lefty, (&left));
+ COLOR_RR(righty, (&right));
+
+ SETUP(x, (&left), (&right), w);
+
+ for (x = w - 1; x > 0; --x) { /* 0 -> w-1 */
+ *(data++) = COLOR(x);
+
+ NEXT(x);
+ }
+ *(data++) = COLOR(x);
+
+ NEXT(lefty);
+ NEXT(righty);
+ }
+ COLOR_RR(lefty, (&left));
+ COLOR_RR(righty, (&right));
+
+ SETUP(x, (&left), (&right), w);
+
+ for (x = w - 1; x > 0; --x) { /* 0 -> w-1 */
+ *(data++) = COLOR(x);
+
+ NEXT(x);
+ }
+ *data = COLOR(x);
+}
+
+static void gradient_pyramid(RrSurface *sf, gint w, gint h)
+{
+ RrPixel32 *ldata, *rdata;
+ RrPixel32 *cp;
+ RrColor left, right;
+ RrColor extracorner;
+ gint x, y, halfw, halfh, midx, midy;
+
+ VARS(lefty);
+ VARS(righty);
+ VARS(x);
+
+ extracorner.r = (sf->primary->r + sf->secondary->r) / 2;
+ extracorner.g = (sf->primary->g + sf->secondary->g) / 2;
+ extracorner.b = (sf->primary->b + sf->secondary->b) / 2;
+
+ halfw = w >> 1;
+ halfh = h >> 1;
+ midx = w - halfw - halfw; /* 0 or 1, depending if w is even or odd */
+ midy = h - halfh - halfh; /* 0 or 1, depending if h is even or odd */
+
+ SETUP(lefty, sf->primary, (&extracorner), halfh + midy);
+ SETUP(righty, (&extracorner), sf->secondary, halfh + midy);
+
+ /* draw the top half
+
+ it is faster to draw both top quarters together than to draw one and
+ then copy it over to the other side.
+ */
+
+ ldata = sf->pixel_data;
+ rdata = ldata + w - 1;
+ for (y = halfh + midy; y > 0; --y) { /* 0 -> (h+1)/2 */
+ RrPixel32 c;
+
+ COLOR_RR(lefty, (&left));
+ COLOR_RR(righty, (&right));
+
+ SETUP(x, (&left), (&right), halfw + midx);
+
+ for (x = halfw + midx - 1; x > 0; --x) { /* 0 -> (w+1)/2 */
+ c = COLOR(x);
+ *(ldata++) = *(rdata--) = c;
+
+ NEXT(x);
+ }
+ c = COLOR(x);
+ *ldata = *rdata = c;
+ ldata += halfw + 1;
+ rdata += halfw - 1 + midx + w;
+
+ NEXT(lefty);
+ NEXT(righty);
+ }
+
+ /* copy the top half into the bottom half, mirroring it, so we can only
+ copy one row at a time
+
+ it is faster, to move the writing pointer forward, and the reading
+ pointer backward
+
+ this is the current code, moving the write pointer forward and read
+ pointer backward
+ 41.78 4.26 1.78 504 3.53 3.53 gradient_pyramid2
+ this is the opposite, moving the read pointer forward and the write
+ pointer backward
+ 42.27 4.40 1.86 504 3.69 3.69 gradient_pyramid2
+
+ */
+ ldata = sf->pixel_data + (halfh - 1) * w;
+ cp = ldata + (midy + 1) * w;
+ for (y = halfh; y > 0; --y) {
+ memcpy(cp, ldata, w * sizeof(RrPixel32));
+ ldata -= w;
+ cp += w;