all repos — openbox @ 60065663ba9dc448dcf90fd200cd459bcdb9ef9c

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
#include <glib.h>
#include "../kernel/geom.h"
#include "image.h"

void image_draw(pixel32 *target, TextureRGBA *rgba, Rect *position,
                Rect *surarea)
{
  unsigned long *draw = rgba->data;
  int c, sfw, sfh;
  unsigned int i, e;
  sfw = position->width;
  sfh = position->height;

  /* it would be nice if this worked, but this function is well broken in these
     cercumstances. */
  g_assert(position->width == surarea->width &&
           position->height == surarea->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(unsigned long, 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, e = sfw*sfh; i < e; ++i) {
      unsigned char alpha = draw[i] >> 24;
      unsigned char r = draw[i] >> 16;
      unsigned char g = draw[i] >> 8;
      unsigned char b = draw[i];

      /* background color */
      unsigned char bgr = target[i] >> default_red_shift;
      unsigned char bgg = target[i] >> default_green_shift;
      unsigned char bgb = target[i] >> default_blue_shift;

      r = bgr + (((r - bgr) * alpha) >> 8);
      g = bgg + (((g - bgg) * alpha) >> 8);
      b = bgb + (((b - bgb) * alpha) >> 8);

      target[i] = (r << default_red_shift) | (g << default_green_shift) |
        (b << default_blue_shift);
    }
  }
}