all repos — openbox @ 58be655de321369ceec5819a3516003a05ead575

openbox fork - make it a bit more like ryudo

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);
        }
    }
}