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 *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 *RRenderGradient(unsigned width, unsigned height, const RColor *from, const RColor *to, RGradientStyle 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; }