X-Git-Url: https://repo.or.cz/w/wmaker-crm.git/blobdiff_plain/59fc927dc9f183802621138534fa6eaafe5593ba..688a56e8ab67b56550e2874d9d7423f0d435bfd9:/wrlib/gradient.c diff --git a/wrlib/gradient.c b/wrlib/gradient.c dissimilarity index 84% index 38f19df0..383ecf8a 100644 --- a/wrlib/gradient.c +++ b/wrlib/gradient.c @@ -1,578 +1,645 @@ -/* gradient.c - renders gradients - * - * Raster graphics library - * - * Copyright (c) 1997-2003 Alfredo K. Kojima - * Copyright (c) 1998-2003 Dan Pascu - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include - -#include -#include -#include - -#include - -#include "wraster.h" - - -static RImage *renderHGradient(unsigned width, unsigned height, - int r0, int g0, int b0, - int rf, int gf, int bf); -static RImage *renderVGradient(unsigned width, unsigned height, - int r0, int g0, int b0, - int rf, int gf, int bf); -static RImage *renderDGradient(unsigned width, unsigned height, - int r0, int g0, int b0, - int rf, int gf, int bf); - -static RImage *renderMHGradient(unsigned width, unsigned height, - RColor **colors, int count); -static RImage *renderMVGradient(unsigned width, unsigned height, - RColor **colors, int count); -static RImage *renderMDGradient(unsigned width, unsigned height, - RColor **colors, int count); - -RImage* -RRenderMultiGradient(unsigned width, unsigned height, RColor **colors, int style) -{ - int count; - - count = 0; - while (colors[count]!=NULL) count++; - - if (count > 2) { - switch (style) { - case RHorizontalGradient: - return renderMHGradient(width, height, colors, count); - case RVerticalGradient: - return renderMVGradient(width, height, colors, count); - case RDiagonalGradient: - return renderMDGradient(width, height, colors, count); - } - } else if (count > 1) { - return RRenderGradient(width, height, colors[0], colors[1], style); - } else if (count > 0) { - return RRenderGradient(width, height, colors[0], colors[0], style); - } - assert(0); - return NULL; -} - - - -RImage* -RRenderGradient(unsigned width, unsigned height, RColor *from, RColor *to, - int style) -{ - switch (style) { - case RHorizontalGradient: - return renderHGradient(width, height, from->red, from->green, - from->blue, to->red, to->green, to->blue); - case RVerticalGradient: - return renderVGradient(width, height, from->red, from->green, - from->blue, to->red, to->green, to->blue); - - case RDiagonalGradient: - return renderDGradient(width, height, from->red, from->green, - from->blue, to->red, to->green, to->blue); - } - assert(0); - return NULL; -} - - -/* - *---------------------------------------------------------------------- - * renderHGradient-- - * Renders a horizontal linear gradient of the specified size in the - * RImage format with a border of the specified type. - * - * Returns: - * A 24bit RImage with the gradient (no alpha channel). - * - * Side effects: - * None - *---------------------------------------------------------------------- - */ -static RImage* -renderHGradient(unsigned width, unsigned height, int r0, int g0, int b0, - int rf, int gf, int bf) -{ - int i; - long r, g, b, dr, dg, db; - unsigned lineSize = width*3; - RImage *image; - unsigned char *ptr; - - image = RCreateImage(width, height, False); - if (!image) { - return NULL; - } - ptr = image->data; - - r = r0 << 16; - g = g0 << 16; - b = b0 << 16; - - dr = ((rf-r0)<<16)/(int)width; - dg = ((gf-g0)<<16)/(int)width; - db = ((bf-b0)<<16)/(int)width; - /* render the first line */ - for (i=0; i>16); - *(ptr++) = (unsigned char)(g>>16); - *(ptr++) = (unsigned char)(b>>16); - r += dr; - g += dg; - b += db; - } - - /* copy the first line to the other lines */ - for (i=1; idata[i*lineSize]), image->data, lineSize); - } - return image; -} - - - -/* - *---------------------------------------------------------------------- - * renderVGradient-- - * Renders a vertical linear gradient of the specified size in the - * RImage format with a border of the specified type. - * - * Returns: - * A 24bit RImage with the gradient (no alpha channel). - * - * Side effects: - * None - *---------------------------------------------------------------------- - */ -static RImage* -renderVGradient(unsigned width, unsigned height, int r0, int g0, int b0, - int rf, int gf, int bf) -{ - int i, j; - long r, g, b, dr, dg, db; - RImage *image; - unsigned char *ptr; - unsigned char rr, gg, bb; - - image = RCreateImage(width, height, False); - if (!image) { - return NULL; - } - ptr = image->data; - - r = r0<<16; - g = g0<<16; - b = b0<<16; - - dr = ((rf-r0)<<16)/(int)height; - dg = ((gf-g0)<<16)/(int)height; - db = ((bf-b0)<<16)/(int)height; - - for (i=0; i>16; - gg = g>>16; - bb = b>>16; - for (j=0; jdata; - - a = ((float)(width - 1))/((float)(height - 1)); - width = width * 3; - - /* copy the first line to the other lines with corresponding offset */ - for (j=0, offset=0.0; jdata[j]), &ptr[3*(int)offset], width); - offset += a; - } - - RReleaseImage(tmp); - return image; -} - - -static RImage* -renderMHGradient(unsigned width, unsigned height, RColor **colors, int count) -{ - int i, j, k; - long r, g, b, dr, dg, db; - unsigned lineSize = width*3; - RImage *image; - unsigned char *ptr; - unsigned width2; - - - assert(count > 2); - - image = RCreateImage(width, height, False); - if (!image) { - return NULL; - } - ptr = image->data; - - if (count > width) - count = width; - - if (count > 1) - width2 = width/(count-1); - else - width2 = width; - - k = 0; - - r = colors[0]->red << 16; - g = colors[0]->green << 16; - b = colors[0]->blue << 16; - - /* render the first line */ - for (i=1; ired - colors[i-1]->red) <<16)/(int)width2; - dg = ((int)(colors[i]->green - colors[i-1]->green)<<16)/(int)width2; - db = ((int)(colors[i]->blue - colors[i-1]->blue) <<16)/(int)width2; - for (j=0; j>16); - *ptr++ = (unsigned char)(g>>16); - *ptr++ = (unsigned char)(b>>16); - r += dr; - g += dg; - b += db; - k++; - } - r = colors[i]->red << 16; - g = colors[i]->green << 16; - b = colors[i]->blue << 16; - } - for (j=k; j>16); - *ptr++ = (unsigned char)(g>>16); - *ptr++ = (unsigned char)(b>>16); - } - - /* copy the first line to the other lines */ - for (i=1; idata[i*lineSize]), image->data, lineSize); - } - return image; -} - - - - -static RImage* -renderMVGradient(unsigned width, unsigned height, RColor **colors, int count) -{ - int i, j, k; - long r, g, b, dr, dg, db; - unsigned lineSize = width*3; - RImage *image; - unsigned char *ptr, *tmp; - unsigned height2; - int x; - unsigned char rr, gg, bb; - - - assert(count > 2); - - image = RCreateImage(width, height, False); - if (!image) { - return NULL; - } - ptr = image->data; - - if (count > height) - count = height; - - if (count > 1) - height2 = height/(count-1); - else - height2 = height; - - k = 0; - - r = colors[0]->red << 16; - g = colors[0]->green << 16; - b = colors[0]->blue << 16; - - for (i=1; ired - colors[i-1]->red) <<16)/(int)height2; - dg = ((int)(colors[i]->green - colors[i-1]->green)<<16)/(int)height2; - db = ((int)(colors[i]->blue - colors[i-1]->blue) <<16)/(int)height2; - - for (j=0; j>16; - gg = g>>16; - bb = b>>16; - - for (x=0; xred << 16; - g = colors[i]->green << 16; - b = colors[i]->blue << 16; - } - - rr = r>>16; - gg = g>>16; - bb = b>>16; - - if (k 2); - - if (width == 1) - return renderMVGradient(width, height, colors, count); - else if (height == 1) - return renderMHGradient(width, height, colors, count); - - image = RCreateImage(width, height, False); - if (!image) { - return NULL; - } - - if (count > width) - count = width; - if (count > height) - count = height; - - if (count > 2) - tmp = renderMHGradient(2*width-1, 1, colors, count); - else - tmp = renderHGradient(2*width-1, 1, colors[0]->red<<8, - colors[0]->green<<8, colors[0]->blue<<8, - colors[1]->red<<8, colors[1]->green<<8, - colors[1]->blue<<8); - - if (!tmp) { - RReleaseImage(image); - return NULL; - } - ptr = tmp->data; - - a = ((float)(width - 1))/((float)(height - 1)); - width = width * 3; - - /* copy the first line to the other lines with corresponding offset */ - for (j=0, offset=0; jdata[j]), &ptr[3*(int)offset], width); - offset += a; - } - RReleaseImage(tmp); - return image; -} - - - - -RImage* -RRenderInterwovenGradient(unsigned width, unsigned height, - RColor colors1[2], int thickness1, - RColor colors2[2], int thickness2) -{ - int i, j, k, l, ll; - long r1, g1, b1, dr1, dg1, db1; - long r2, g2, b2, dr2, dg2, db2; - RImage *image; - unsigned char *ptr; - unsigned char rr, gg, bb; - - image = RCreateImage(width, height, False); - if (!image) { - return NULL; - } - ptr = image->data; - - r1 = colors1[0].red<<16; - g1 = colors1[0].green<<16; - b1 = colors1[0].blue<<16; - - r2 = colors2[0].red<<16; - g2 = colors2[0].green<<16; - b2 = colors2[0].blue<<16; - - dr1 = ((colors1[1].red-colors1[0].red)<<16)/(int)height; - dg1 = ((colors1[1].green-colors1[0].green)<<16)/(int)height; - db1 = ((colors1[1].blue-colors1[0].blue)<<16)/(int)height; - - dr2 = ((colors2[1].red-colors2[0].red)<<16)/(int)height; - dg2 = ((colors2[1].green-colors2[0].green)<<16)/(int)height; - db2 = ((colors2[1].blue-colors2[0].blue)<<16)/(int)height; - - for (i=0,k=0,l=0,ll=thickness1; i>16; - gg = g1>>16; - bb = b1>>16; - } else { - rr = r2>>16; - gg = g2>>16; - bb = b2>>16; - } - for (j=0; j + +#include +#include +#include + +#include + +#include "wraster.h" + +static RImage *renderHGradient(unsigned width, unsigned height, int r0, int g0, int b0, int rf, int gf, int bf); +static RImage *renderVGradient(unsigned width, unsigned height, int r0, int g0, int b0, int rf, int gf, int bf); +static RImage *renderDGradient(unsigned width, unsigned height, int r0, int g0, int b0, int rf, int gf, int bf); + +static RImage *renderMHGradient(unsigned width, unsigned height, RColor ** colors, int count); +static RImage *renderMVGradient(unsigned width, unsigned height, RColor ** colors, int count); +static RImage *renderMDGradient(unsigned width, unsigned height, RColor ** colors, int count); + +RImage *RRenderMultiGradient(unsigned width, unsigned height, RColor ** colors, int style) +{ + int count; + + count = 0; + while (colors[count] != NULL) + count++; + + if (count > 2) { + switch (style) { + case RHorizontalGradient: + return renderMHGradient(width, height, colors, count); + case RVerticalGradient: + return renderMVGradient(width, height, colors, count); + case RDiagonalGradient: + return renderMDGradient(width, height, colors, count); + } + } else if (count > 1) { + return RRenderGradient(width, height, colors[0], colors[1], style); + } else if (count > 0) { + return RRenderGradient(width, height, colors[0], colors[0], style); + } + assert(0); + return NULL; +} + +RImage *RRenderGradient(unsigned width, unsigned height, RColor * from, RColor * to, int style) +{ + switch (style) { + case RHorizontalGradient: + return renderHGradient(width, height, from->red, from->green, + from->blue, to->red, to->green, to->blue); + case RVerticalGradient: + return renderVGradient(width, height, from->red, from->green, + from->blue, to->red, to->green, to->blue); + + case RDiagonalGradient: + return renderDGradient(width, height, from->red, from->green, + from->blue, to->red, to->green, to->blue); + } + assert(0); + return NULL; +} + +/* + *---------------------------------------------------------------------- + * renderHGradient-- + * Renders a horizontal linear gradient of the specified size in the + * RImage format with a border of the specified type. + * + * Returns: + * A 24bit RImage with the gradient (no alpha channel). + * + * Side effects: + * None + *---------------------------------------------------------------------- + */ +static RImage *renderHGradient(unsigned width, unsigned height, int r0, int g0, int b0, int rf, int gf, int bf) +{ + int i; + long r, g, b, dr, dg, db; + unsigned lineSize = width * 3; + RImage *image; + unsigned char *ptr; + + image = RCreateImage(width, height, False); + if (!image) { + return NULL; + } + ptr = image->data; + + r = r0 << 16; + g = g0 << 16; + b = b0 << 16; + + dr = ((rf - r0) << 16) / (int)width; + dg = ((gf - g0) << 16) / (int)width; + db = ((bf - b0) << 16) / (int)width; + /* render the first line */ + for (i = 0; i < width; i++) { + *(ptr++) = (unsigned char)(r >> 16); + *(ptr++) = (unsigned char)(g >> 16); + *(ptr++) = (unsigned char)(b >> 16); + r += dr; + g += dg; + b += db; + } + + /* copy the first line to the other lines */ + for (i = 1; i < height; i++) { + memcpy(&(image->data[i * lineSize]), image->data, lineSize); + } + return image; +} + +/* + *---------------------------------------------------------------------- + * renderVGradient-- + * Renders a vertical linear gradient of the specified size in the + * RImage format with a border of the specified type. + * + * Returns: + * A 24bit RImage with the gradient (no alpha channel). + * + * Side effects: + * None + *---------------------------------------------------------------------- + */ +static RImage *renderVGradient(unsigned width, unsigned height, int r0, int g0, int b0, int rf, int gf, int bf) +{ + int i, j; + long r, g, b, dr, dg, db; + RImage *image; + unsigned char *ptr; + unsigned char rr, gg, bb; + + image = RCreateImage(width, height, False); + if (!image) { + return NULL; + } + ptr = image->data; + + r = r0 << 16; + g = g0 << 16; + b = b0 << 16; + + dr = ((rf - r0) << 16) / (int)height; + dg = ((gf - g0) << 16) / (int)height; + db = ((bf - b0) << 16) / (int)height; + + for (i = 0; i < height; i++) { + rr = r >> 16; + gg = g >> 16; + bb = b >> 16; + for (j = 0; j < width / 8; j++) { + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + } + switch (width % 8) { + case 7: + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + case 6: + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + case 5: + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + case 4: + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + case 3: + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + case 2: + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + case 1: + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + } + r += dr; + g += dg; + b += db; + } + return image; +} + +/* + *---------------------------------------------------------------------- + * renderDGradient-- + * Renders a diagonal linear gradient of the specified size in the + * RImage format with a border of the specified type. + * + * Returns: + * A 24bit RImage with the gradient (no alpha channel). + * + * Side effects: + * None + *---------------------------------------------------------------------- + */ + +static RImage *renderDGradient(unsigned width, unsigned height, int r0, int g0, int b0, int rf, int gf, int bf) +{ + RImage *image, *tmp; + int j; + float a, offset; + unsigned char *ptr; + + if (width == 1) + return renderVGradient(width, height, r0, g0, b0, rf, gf, bf); + else if (height == 1) + return renderHGradient(width, height, r0, g0, b0, rf, gf, bf); + + image = RCreateImage(width, height, False); + if (!image) { + return NULL; + } + + tmp = renderHGradient(2 * width - 1, 1, r0, g0, b0, rf, gf, bf); + if (!tmp) { + RReleaseImage(image); + return NULL; + } + + ptr = tmp->data; + + a = ((float)(width - 1)) / ((float)(height - 1)); + width = width * 3; + + /* copy the first line to the other lines with corresponding offset */ + for (j = 0, offset = 0.0; j < width * height; j += width) { + memcpy(&(image->data[j]), &ptr[3 * (int)offset], width); + offset += a; + } + + RReleaseImage(tmp); + return image; +} + +static RImage *renderMHGradient(unsigned width, unsigned height, RColor ** colors, int count) +{ + int i, j, k; + long r, g, b, dr, dg, db; + unsigned lineSize = width * 3; + RImage *image; + unsigned char *ptr; + unsigned width2; + + assert(count > 2); + + image = RCreateImage(width, height, False); + if (!image) { + return NULL; + } + ptr = image->data; + + if (count > width) + count = width; + + if (count > 1) + width2 = width / (count - 1); + else + width2 = width; + + k = 0; + + r = colors[0]->red << 16; + g = colors[0]->green << 16; + b = colors[0]->blue << 16; + + /* render the first line */ + for (i = 1; i < count; i++) { + dr = ((int)(colors[i]->red - colors[i - 1]->red) << 16) / (int)width2; + dg = ((int)(colors[i]->green - colors[i - 1]->green) << 16) / (int)width2; + db = ((int)(colors[i]->blue - colors[i - 1]->blue) << 16) / (int)width2; + for (j = 0; j < width2; j++) { + *ptr++ = (unsigned char)(r >> 16); + *ptr++ = (unsigned char)(g >> 16); + *ptr++ = (unsigned char)(b >> 16); + r += dr; + g += dg; + b += db; + k++; + } + r = colors[i]->red << 16; + g = colors[i]->green << 16; + b = colors[i]->blue << 16; + } + for (j = k; j < width; j++) { + *ptr++ = (unsigned char)(r >> 16); + *ptr++ = (unsigned char)(g >> 16); + *ptr++ = (unsigned char)(b >> 16); + } + + /* copy the first line to the other lines */ + for (i = 1; i < height; i++) { + memcpy(&(image->data[i * lineSize]), image->data, lineSize); + } + return image; +} + +static RImage *renderMVGradient(unsigned width, unsigned height, RColor ** colors, int count) +{ + int i, j, k; + long r, g, b, dr, dg, db; + unsigned lineSize = width * 3; + RImage *image; + unsigned char *ptr, *tmp; + unsigned height2; + int x; + unsigned char rr, gg, bb; + + assert(count > 2); + + image = RCreateImage(width, height, False); + if (!image) { + return NULL; + } + ptr = image->data; + + if (count > height) + count = height; + + if (count > 1) + height2 = height / (count - 1); + else + height2 = height; + + k = 0; + + r = colors[0]->red << 16; + g = colors[0]->green << 16; + b = colors[0]->blue << 16; + + for (i = 1; i < count; i++) { + dr = ((int)(colors[i]->red - colors[i - 1]->red) << 16) / (int)height2; + dg = ((int)(colors[i]->green - colors[i - 1]->green) << 16) / (int)height2; + db = ((int)(colors[i]->blue - colors[i - 1]->blue) << 16) / (int)height2; + + for (j = 0; j < height2; j++) { + rr = r >> 16; + gg = g >> 16; + bb = b >> 16; + + for (x = 0; x < width / 4; x++) { + *ptr++ = rr; + *ptr++ = gg; + *ptr++ = bb; + *ptr++ = rr; + *ptr++ = gg; + *ptr++ = bb; + *ptr++ = rr; + *ptr++ = gg; + *ptr++ = bb; + *ptr++ = rr; + *ptr++ = gg; + *ptr++ = bb; + } + switch (width % 4) { + case 3: + *ptr++ = rr; + *ptr++ = gg; + *ptr++ = bb; + case 2: + *ptr++ = rr; + *ptr++ = gg; + *ptr++ = bb; + case 1: + *ptr++ = rr; + *ptr++ = gg; + *ptr++ = bb; + } + r += dr; + g += dg; + b += db; + k++; + } + r = colors[i]->red << 16; + g = colors[i]->green << 16; + b = colors[i]->blue << 16; + } + + rr = r >> 16; + gg = g >> 16; + bb = b >> 16; + + if (k < height) { + tmp = ptr; + for (x = 0; x < width / 4; x++) { + *ptr++ = rr; + *ptr++ = gg; + *ptr++ = bb; + *ptr++ = rr; + *ptr++ = gg; + *ptr++ = bb; + *ptr++ = rr; + *ptr++ = gg; + *ptr++ = bb; + *ptr++ = rr; + *ptr++ = gg; + *ptr++ = bb; + } + switch (width % 4) { + case 3: + *ptr++ = rr; + *ptr++ = gg; + *ptr++ = bb; + case 2: + *ptr++ = rr; + *ptr++ = gg; + *ptr++ = bb; + case 1: + *ptr++ = rr; + *ptr++ = gg; + *ptr++ = bb; + default: + break; + } + + for (j = k + 1; j < height; j++) { + memcpy(ptr, tmp, lineSize); + ptr += lineSize; + } + } + + return image; +} + +static RImage *renderMDGradient(unsigned width, unsigned height, RColor ** colors, int count) +{ + RImage *image, *tmp; + float a, offset; + int j; + unsigned char *ptr; + + assert(count > 2); + + if (width == 1) + return renderMVGradient(width, height, colors, count); + else if (height == 1) + return renderMHGradient(width, height, colors, count); + + image = RCreateImage(width, height, False); + if (!image) { + return NULL; + } + + if (count > width) + count = width; + if (count > height) + count = height; + + if (count > 2) + tmp = renderMHGradient(2 * width - 1, 1, colors, count); + else + tmp = renderHGradient(2 * width - 1, 1, colors[0]->red << 8, + colors[0]->green << 8, colors[0]->blue << 8, + colors[1]->red << 8, colors[1]->green << 8, colors[1]->blue << 8); + + if (!tmp) { + RReleaseImage(image); + return NULL; + } + ptr = tmp->data; + + a = ((float)(width - 1)) / ((float)(height - 1)); + width = width * 3; + + /* copy the first line to the other lines with corresponding offset */ + for (j = 0, offset = 0; j < width * height; j += width) { + memcpy(&(image->data[j]), &ptr[3 * (int)offset], width); + offset += a; + } + RReleaseImage(tmp); + return image; +} + +RImage *RRenderInterwovenGradient(unsigned width, unsigned height, + RColor colors1[2], int thickness1, RColor colors2[2], int thickness2) +{ + int i, j, k, l, ll; + long r1, g1, b1, dr1, dg1, db1; + long r2, g2, b2, dr2, dg2, db2; + RImage *image; + unsigned char *ptr; + unsigned char rr, gg, bb; + + image = RCreateImage(width, height, False); + if (!image) { + return NULL; + } + ptr = image->data; + + r1 = colors1[0].red << 16; + g1 = colors1[0].green << 16; + b1 = colors1[0].blue << 16; + + r2 = colors2[0].red << 16; + g2 = colors2[0].green << 16; + b2 = colors2[0].blue << 16; + + dr1 = ((colors1[1].red - colors1[0].red) << 16) / (int)height; + dg1 = ((colors1[1].green - colors1[0].green) << 16) / (int)height; + db1 = ((colors1[1].blue - colors1[0].blue) << 16) / (int)height; + + dr2 = ((colors2[1].red - colors2[0].red) << 16) / (int)height; + dg2 = ((colors2[1].green - colors2[0].green) << 16) / (int)height; + db2 = ((colors2[1].blue - colors2[0].blue) << 16) / (int)height; + + for (i = 0, k = 0, l = 0, ll = thickness1; i < height; i++) { + if (k == 0) { + rr = r1 >> 16; + gg = g1 >> 16; + bb = b1 >> 16; + } else { + rr = r2 >> 16; + gg = g2 >> 16; + bb = b2 >> 16; + } + for (j = 0; j < width / 8; j++) { + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + } + switch (width % 8) { + case 7: + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + case 6: + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + case 5: + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + case 4: + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + case 3: + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + case 2: + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + case 1: + *(ptr++) = rr; + *(ptr++) = gg; + *(ptr++) = bb; + } + if (++l == ll) { + if (k == 0) { + k = 1; + ll = thickness2; + } else { + k = 0; + ll = thickness1; + } + l = 0; + } + r1 += dr1; + g1 += dg1; + b1 += db1; + + r2 += dr2; + g2 += dg2; + b2 += db2; + } + return image; +}