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