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 *RRenderMultiGradient(unsigned width, unsigned height, RColor **colors, RGradientStyle 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; }