Usermode/AxWin3 - Fixed error with relative windows and input
[tpg/acess2.git] / Usermode / Applications / axwin3_src / WM / wm_render.c
1 /*
2  * Acess2 Window Manager v3
3  * - By John Hodge (thePowersGang)
4  *
5  * wm_render.c
6  * - Window rendering functions
7  */
8 #include <common.h>
9 #include <wm.h>
10 #include <wm_internals.h>
11 #include <stdlib.h>
12
13 // === CODE ===
14 void WM_Render_FillRect(tWindow *Window, int X, int Y, int W, int H, tColour Colour)
15 {
16         uint32_t        *dest;
17          int    i;
18
19         X += Window->BorderL;   
20         Y += Window->BorderT;
21
22         // Clip to window dimensions
23         if(X < 0) { W += X; X = 0; }
24         if(Y < 0) { H += Y; Y = 0; }
25         if(W <= 0 || H <= 0)    return;
26         if(X >= Window->RealW)  return;
27         if(Y >= Window->RealH)  return;
28         if(X + W > Window->RealW)       W = Window->RealW - X;
29         if(Y + H > Window->RealH)       H = Window->RealH - Y;
30
31         // TODO: Catch overflow into decorator area
32
33         if(!Window->RenderBuffer) {
34                 Window->RenderBuffer = malloc(Window->RealW*Window->RealH*4);
35         }
36
37         dest = (uint32_t*)Window->RenderBuffer + Y*Window->RealW + X;
38         while( H -- )
39         {
40                 for( i = W; i --; )
41                         *dest++ = Colour;
42                 dest += Window->RealW - W;
43         }
44 }
45
46 void WM_Render_DrawRect(tWindow *Window, int X, int Y, int W, int H, tColour Colour)
47 {       
48         WM_Render_FillRect(Window, X, Y, W, 1, Colour);
49         WM_Render_FillRect(Window, X, Y+H-1, W, 1, Colour);
50         WM_Render_FillRect(Window, X, Y, 1, H, Colour);
51         WM_Render_FillRect(Window, X+W-1, Y, 1, H, Colour);
52 }
53
54 /**
55  * \brief Draw an image to the screen
56  * \todo Maybe have support for an offset in the image
57  */
58 void WM_Render_DrawImage(tWindow *Window, int X, int Y, int W, int H, tImage *Image)
59 {
60          int    x, y;
61         uint32_t        *dest;
62         uint8_t *data;
63         
64         // Sanity please
65         if( !Image )    return ;
66
67         // Allocate
68         if(!Window->RenderBuffer) {
69                 Window->RenderBuffer = malloc(Window->W*Window->H*4);
70         }
71
72         // Apply offset
73         X += Window->BorderL;
74         Y += Window->BorderT;
75
76         // Bounds Check
77         if( X >= Window->RealW )        return ;
78         if( Y >= Window->RealH )        return ;
79         
80         // Wrap to image size
81         if( W > Image->Width )  W = Image->Width;
82         if( H > Image->Height ) H = Image->Height;
83         
84         // Wrap to screen size
85         if( X + W > Window->RealW )     W = Window->RealW - X;
86         if( Y + H > Window->RealH )     H = Window->RealH - Y;
87
88         // TODO: Catch overflow into decorator area
89         #if 0
90         if( !Window->bDrawingDecorations )
91         {
92                 if( X < Window->BorderL )       return ;
93                 if( Y < Window->BorderT )       return ;
94                 if( X + W > Window->BorderL + Window->W )       W = X - (Window->BorderL + Window->W);
95                 if( Y + H > Window->BorderT + Window->H )       H = Y - (Window->BorderT + Window->H);
96         }
97         #endif
98
99         dest = (uint32_t*)Window->RenderBuffer + Y * Window->RealW + X;
100         data = Image->Data;
101
102         // Do the render
103         switch( Image->Format )
104         {
105         case IMGFMT_BGRA:
106                 for( y = 0; y < H; y ++ )
107                 {
108                          int    r, g, b, a;     // New
109                          int    or, og, ob;     // Original
110                         for( x = 0; x < W; x ++ )
111                         {
112                                 b = data[x*4+0]; g = data[x*4+1]; r = data[x*4+2]; a = data[x*4+3];
113                                 if( a == 0 )    continue;       // 100% transparent
114                                 ob = dest[x]&0xFF; og = (dest[x] >> 8)&0xFF; or = (dest[x] >> 16)&0xFF;
115                                 // Handle Alpha
116                                 switch(a)
117                                 {
118                                 // Transparent: Handled above
119                                 // Solid
120                                 case 0xFF:      break;
121                                 // Half
122                                 case 0x80:
123                                         r = (or + r) / 2;
124                                         g = (og + g) / 2;
125                                         b = (ob + b) / 2;
126                                         break;
127                                 // General
128                                 default:
129                                         r = (or * (255-a) + r * a) / 255;
130                                         g = (og * (255-a) + g * a) / 255;
131                                         b = (ob * (255-a) + b * a) / 255;
132                                         break;
133                                 }
134                                 dest[x] = b | (g << 8) | (r << 16);
135                         }
136                         data += Image->Width * 4;
137                         dest += Window->RealW;
138                 }
139                 break;
140         
141         // RGB
142         case IMGFMT_RGB:
143                 for( y = 0; y < H; y ++ )
144                 {
145                         for( x = 0; x < W; x ++ )
146                         {
147                                 //        Blue           Green                Red
148                                 dest[x] = data[x*3+2] | (data[x*3+1] << 8) | (data[x*3+0] << 16);
149                         }
150                         data += W * 3;
151                         dest += Window->RealW;
152                 }
153                 break;
154         default:
155                 _SysDebug("ERROR: Unknown image format %i\n", Image->Format);
156                 break;
157         }
158 }
159
160 void WM_Render_SetTextCursor(tWindow *Window, int X, int Y, int W, int H, tColour Colour)
161 {
162         if( X < 0 || Y < 0 )    return ;
163         if( X >= Window->W )    return ;
164         if( Y >= Window->H )    return ;
165         if( X + W >= Window->W )        W = Window->W - X;
166         if( Y + H >= Window->H )        H = Window->H - Y;
167         
168         Window->CursorX = X;
169         Window->CursorY = Y;
170         Window->CursorW = W;
171         Window->CursorH = H;
172 }
173

UCC git Repository :: git.ucc.asn.au