render/image.c (raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
#include "geom.h" #include "image.h" #include "color.h" #include <glib.h> void RrImageDraw(RrPixel32 *target, RrTextureRGBA *rgba, RrRect *area) { RrPixel32 *draw = rgba->data; gint c, i, e, t, sfw, sfh; sfw = area->width; sfh = area->height; g_assert(rgba->data != NULL); if ((rgba->width != sfw || rgba->height != sfh) && (rgba->width != rgba->cwidth || rgba->height != rgba->cheight)) { double dx = rgba->width / (double)sfw; double dy = rgba->height / (double)sfh; double px = 0.0; double py = 0.0; int iy = 0; /* scale it and cache it */ if (rgba->cache != NULL) g_free(rgba->cache); rgba->cache = g_new(RrPixel32, sfw * sfh); rgba->cwidth = sfw; rgba->cheight = sfh; for (i = 0, c = 0, e = sfw*sfh; i < e; ++i) { rgba->cache[i] = rgba->data[(int)px + iy]; if (++c >= sfw) { c = 0; px = 0; py += dy; iy = (int)py * rgba->width; } else px += dx; } /* do we use the cache we may have just created, or the original? */ if (rgba->width != sfw || rgba->height != sfh) draw = rgba->cache; /* apply the alpha channel */ for (i = 0, c = 0, t = area->x, e = sfw*sfh; i < e; ++i, ++t) { guchar alpha, r, g, b, bgr, bgg, bgb; alpha = draw[i] >> RrDefaultAlphaOffset; r = draw[i] >> RrDefaultRedOffset; g = draw[i] >> RrDefaultGreenOffset; b = draw[i] >> RrDefaultBlueOffset; if (c >= sfw) { c = 0; t += area->width - sfw; } /* background color */ bgr = target[t] >> RrDefaultRedOffset; bgg = target[t] >> RrDefaultGreenOffset; bgb = target[t] >> RrDefaultBlueOffset; r = bgr + (((r - bgr) * alpha) >> 8); g = bgg + (((g - bgg) * alpha) >> 8); b = bgb + (((b - bgb) * alpha) >> 8); target[t] = (r << RrDefaultRedOffset) | (g << RrDefaultGreenOffset) | (b << RrDefaultBlueOffset); } } } |