]> Dogcows Code - chaz/openbox/blob - render/image.c
rgba icon rendering
[chaz/openbox] / render / image.c
1 #include <glib.h>
2 #include "../kernel/geom.h"
3 #include "image.h"
4
5 void image_draw(pixel32 *target, TextureRGBA *rgba, Rect *position)
6 {
7 unsigned long *draw = rgba->data;
8 int c, sfw, sfh;
9 unsigned int i, e, bgi;
10 sfw = position->width;
11 sfh = position->height;
12
13 g_assert(rgba->data != NULL);
14
15 if ((rgba->width != sfw || rgba->height != sfh) &&
16 (rgba->width != rgba->cwidth || rgba->height != rgba->cheight)) {
17 double dx = rgba->width / (double)sfw;
18 double dy = rgba->height / (double)sfh;
19 double px = 0.0;
20 double py = 0.0;
21 int iy = 0;
22
23 /* scale it and cache it */
24 if (rgba->cache != NULL)
25 g_free(rgba->cache);
26 rgba->cache = g_new(unsigned long, sfw * sfh);
27 rgba->cwidth = sfw;
28 rgba->cheight = sfh;
29 for (i = 0, c = 0, e = sfw*sfh; i < e; ++i) {
30 rgba->cache[i] = rgba->data[(int)px + iy];
31 if (++c >= sfw) {
32 c = 0;
33 px = 0;
34 py += dy;
35 iy = (int)py * rgba->width;
36 } else
37 px += dx;
38 }
39
40 /* do we use the cache we may have just created, or the original? */
41 if (rgba->width != sfw || rgba->height != sfh)
42 draw = rgba->cache;
43
44 /* apply the alpha channel */
45 for (i = 0, c = 0, e = sfw*sfh; i < e; ++i, ++bgi) {
46 unsigned char alpha = draw[i] >> 24;
47 unsigned char r = draw[i] >> 16;
48 unsigned char g = draw[i] >> 8;
49 unsigned char b = draw[i];
50
51 /* background color */
52 unsigned char bgr = target[i] >> default_red_shift;
53 unsigned char bgg = target[i] >> default_green_shift;
54 unsigned char bgb = target[i] >> default_blue_shift;
55
56 r = bgr + (((r - bgr) * alpha) >> 8);
57 g = bgg + (((g - bgg) * alpha) >> 8);
58 b = bgb + (((b - bgb) * alpha) >> 8);
59
60 target[i] = (r << default_red_shift) | (g << default_green_shift) |
61 (b << default_blue_shift);
62 }
63 }
64 }
This page took 0.043556 seconds and 5 git commands to generate.