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 | ␉{␊ |
22 | ␉␉for (dx = position.x, sx = 0; sx < width; dx++, sx++)␊ |
23 | ␉␉{␊ |
24 | ␉␉␉alpha = (pixel(blendThis, sx, sy).ch.a);␊ |
25 | ␊ |
26 | ␉␉␉/* Skip blending for fully transparent pixel */␊ |
27 | ␉␉␉if (alpha == 0)␊ |
28 | ␉␉␉{␊ |
29 | ␉␉␉␉continue;␊ |
30 | ␉␉␉}␊ |
31 | ␊ |
32 | ␉␉␉/* For fully opaque pixel, there is no need to interpolate */␊ |
33 | ␉␉␉if (alpha == 255)␊ |
34 | ␉␉␉{␊ |
35 | ␉␉␉␉pixel(blendInto, dx, dy).value = pixel(blendThis, sx, sy).value;␊ |
36 | ␉␉␉␉continue;␊ |
37 | ␉␉␉}␊ |
38 | ␊ |
39 | ␉␉␉/* For semi-transparent pixels, do a full blend */␊ |
40 | ␉␉␉//alpha++␊ |
41 | ␉␉␉/* This is needed to spread the alpha over [0..256] instead of [0..255]␊ |
42 | ␉␉␉Boundary conditions were handled above */␊ |
43 | ␉␉␉dstrb = pixel(blendInto, dx, dy).value & 0xFF00FF;␊ |
44 | ␉␉␉dstag = (pixel(blendInto, dx, dy).value >> 8) & 0xFF00FF;␊ |
45 | ␉␉␉srcrb = pixel(blendThis, sx, sy).value & 0xFF00FF;␊ |
46 | ␉␉␉srcag = (pixel(blendThis, sx, sy).value >> 8) & 0xFF00FF;␊ |
47 | ␉␉␉drb = srcrb - dstrb;␊ |
48 | ␉␉␉dag = srcag - dstag;␊ |
49 | ␉␉␉drb *= alpha; dag *= alpha;␊ |
50 | ␉␉␉drb >>= 8; dag >>= 8;␊ |
51 | ␉␉␉rb = (drb + dstrb) & 0x00FF00FF;␊ |
52 | ␉␉␉ag = ((dag + dstag) << 8) & 0xFF00FF00;␊ |
53 | ␉␉␉pixel(blendInto, dx, dy).value = (rb | ag);␊ |
54 | ␉␉}␊ |
55 | ␉}␊ |
56 | }␊ |
57 | ␊ |
58 | position_t centeredIn( const pixmap_t *background, const pixmap_t *toCenter )␊ |
59 | {␊ |
60 | ␉position_t centered;␊ |
61 | ␉centered.x = ( background->width - toCenter->width ) / 2;␊ |
62 | ␉centered.y = ( background->height - toCenter->height ) / 2;␊ |
63 | ␉return centered;␊ |
64 | }␊ |
65 | ␊ |
66 | position_t centeredAt( const pixmap_t *pixmap, const position_t center ) {␊ |
67 | ␉position_t topleft;␊ |
68 | ␉topleft.x = center.x - (pixmap->width / 2);␊ |
69 | ␉topleft.y = center.y - (pixmap->height / 2);␊ |
70 | ␉return topleft;␊ |
71 | }␊ |
72 | ␊ |
73 | position_t pos(const uint16_t x, const uint16_t y) { position_t p; p.x = x; p.y = y; return p; }␊ |
74 | ␊ |
75 | void flipRB(pixmap_t *p)␊ |
76 | {␊ |
77 | ␉//if(testForQemu()) return;␊ |
78 | ␉␊ |
79 | ␉uint32_t x;␊ |
80 | ␉register uint8_t tempB;␊ |
81 | ␉for (x = 0; x < (p->height) * (p->width) ; x++)␊ |
82 | ␉{␊ |
83 | ␉␉tempB = (p->pixels[x]).ch.b;␊ |
84 | ␉␉(p->pixels[x]).ch.b = (p->pixels[x]).ch.r;␊ |
85 | ␉␉(p->pixels[x]).ch.r = tempB;␊ |
86 | ␉}␊ |
87 | }␊ |
88 | |