1 | ␊ |
2 | /* Graphic utility functions and data types␊ |
3 | * Prashant Vaibhav (C) 12/12/2008␊ |
4 | * Chameleon␊ |
5 | */␊ |
6 | #include "boot.h"␊ |
7 | #include "graphic_utils.h"␊ |
8 | #include "gui.h"␊ |
9 | ␊ |
10 | void blend( const pixmap_t *blendThis,␉␉// Source image␊ |
11 | ␉␉pixmap_t *blendInto,␉␉// Dest image␊ |
12 | ␉␉const position_t position)␉// Where to place the source image␊ |
13 | {␊ |
14 | uint16_t sx, sy, dx, dy;␊ |
15 | uint32_t dstrb, dstag, srcrb, srcag, drb, dag, rb, ag, alpha;␊ |
16 | ␉␊ |
17 | ␉uint16_t width = (blendThis->width + position.x < blendInto->width) ? blendThis->width: blendInto->width-position.x;␊ |
18 | ␉uint16_t height = (blendThis->height + position.y < blendInto->height) ? blendThis->height: blendInto->height-position.y;␊ |
19 | ␉␊ |
20 | ␉for (dy = position.y, sy = 0; sy < height; dy++, sy++) {␊ |
21 | ␉␉for (dx = position.x, sx = 0; sx < width; dx++, sx++) {␊ |
22 | ␉␉␉alpha = (pixel(blendThis, sx, sy).ch.a);␊ |
23 | ␊ |
24 | ␉␉␉/* Skip blending for fully transparent pixel */␊ |
25 | ␉␉␉if (alpha == 0) {␊ |
26 | ␉␉␉␉continue;␊ |
27 | ␉␉␉}␊ |
28 | ␊ |
29 | ␉␉␉/* For fully opaque pixel, there is no need to interpolate */␊ |
30 | ␉␉␉if (alpha == 255) {␊ |
31 | ␉␉␉␉pixel(blendInto, dx, dy).value = pixel(blendThis, sx, sy).value;␊ |
32 | ␉␉␉␉continue;␊ |
33 | ␉␉␉}␊ |
34 | ␊ |
35 | ␉␉␉/* For semi-transparent pixels, do a full blend */␊ |
36 | ␉␉␉//alpha++␊ |
37 | ␉␉␉/* This is needed to spread the alpha over [0..256] instead of [0..255]␊ |
38 | ␉␉␉Boundary conditions were handled above */␊ |
39 | ␉␉␉dstrb = pixel(blendInto, dx, dy).value & 0xFF00FF;␊ |
40 | ␉␉␉dstag = (pixel(blendInto, dx, dy).value >> 8) & 0xFF00FF;␊ |
41 | ␉␉␉srcrb = pixel(blendThis, sx, sy).value & 0xFF00FF;␊ |
42 | ␉␉␉srcag = (pixel(blendThis, sx, sy).value >> 8) & 0xFF00FF;␊ |
43 | ␉␉␉drb = srcrb - dstrb;␊ |
44 | ␉␉␉dag = srcag - dstag;␊ |
45 | ␉␉␉drb *= alpha; dag *= alpha;␊ |
46 | ␉␉␉drb >>= 8; dag >>= 8;␊ |
47 | ␉␉␉rb = (drb + dstrb) & 0x00FF00FF;␊ |
48 | ␉␉␉ag = ((dag + dstag) << 8) & 0xFF00FF00;␊ |
49 | ␉␉␉pixel(blendInto, dx, dy).value = (rb | ag);␊ |
50 | ␉␉}␊ |
51 | ␉}␊ |
52 | }␊ |
53 | ␊ |
54 | position_t centeredIn( const pixmap_t *background, const pixmap_t *toCenter ) {␊ |
55 | ␉position_t centered;␊ |
56 | ␉centered.x = ( background->width - toCenter->width ) / 2;␊ |
57 | ␉centered.y = ( background->height - toCenter->height ) / 2;␊ |
58 | ␉return centered;␊ |
59 | }␊ |
60 | ␊ |
61 | position_t centeredAt( const pixmap_t *pixmap, const position_t center ) {␊ |
62 | ␉position_t topleft;␊ |
63 | ␉topleft.x = center.x - (pixmap->width / 2);␊ |
64 | ␉topleft.y = center.y - (pixmap->height / 2);␊ |
65 | ␉return topleft;␊ |
66 | }␊ |
67 | ␊ |
68 | position_t pos(const uint16_t x, const uint16_t y) { position_t p; p.x = x; p.y = y; return p; }␊ |
69 | ␊ |
70 | void flipRB(pixmap_t *p)␊ |
71 | {␊ |
72 | ␉//if(testForQemu()) return;␊ |
73 | ␉␊ |
74 | ␉uint32_t x;␊ |
75 | ␉register uint8_t tempB;␊ |
76 | ␉for (x = 0; x < (p->height) * (p->width) ; x++) {␊ |
77 | ␉␉tempB = (p->pixels[x]).ch.b;␊ |
78 | ␉␉(p->pixels[x]).ch.b = (p->pixels[x]).ch.r;␊ |
79 | ␉␉(p->pixels[x]).ch.r = tempB;␊ |
80 | ␉}␊ |
81 | }␊ |
82 | |