locale.library: correctly return the position of remaining datastream
[AROS.git] / workbench / libs / popupmenu / pmdrawshadow.c
blobed7168c86583fc8ffdb69ed498a23fd6c3206c7d
1 //
2 // pmdrawshadow.c - Renders shadows, uses CyberGfx if available.
3 //
4 // Copyright (C) 1996 - 2002 Henrik Isaksson
5 // All Rights Reserved.
6 //
8 #include <cybergraphx/cybergraphics.h>
9 #include <proto/cybergraphics.h>
10 #include "pmpriv.h"
12 // Macros that extract colour information
14 #define PC16BIT1(x) ((x&0x1f00)>>8)
15 #define PC16BIT2(x) ((x&0x00F8)>>3)
16 #define PC16BIT3(x) (((x&0xE000)>>13)|((x&0x0007)<<3))
18 #define PC15BIT1(x) ((x&0x1f00)>>8)
19 #define PC15BIT2(x) ((x&0x007C)>>2)
20 #define PC15BIT3(x) (((x&0xE000)>>13)|((x&0x0003)<<3))
22 #define M16RED(x) ((x&0xF800)>>11)
23 #define M16GREEN(x) ((x&0x07E0)>>5)
24 #define M16BLUE(x) (x&0x001F)
26 #define M15RED(x) ((x&0x7C00)>>10)
27 #define M15GREEN(x) ((x&0x03E0)>>5)
28 #define M15BLUE(x) (x&0x001F)
30 // Clamping macro, make sure that x stays within l <= x <= u
32 #define CLAMP(x, l, u) x=x>u?x=u:x;x=x<l?x=l:x;
34 struct CGFXHookMsg {
35 APTR memptr;
36 ULONG ox, oy;
37 ULONG xs, ys;
38 UWORD bytesperrow, bytesperpix;
39 UWORD colormodel;
42 struct ShRect {
43 UWORD xa, ya;
44 UWORD xb, yb;
45 BYTE r, g, b;
48 // shadefunc - CGFX hook that processes a ShRect structure passed in
49 // hook->h_Data.
50 ULONG shadefunc(struct Hook *hook, struct RastPort *rp, struct CGFXHookMsg *m)
52 UBYTE *ptr=(UBYTE *)m->memptr;
53 UWORD *wrow;
54 struct ShRect *rect = (struct ShRect *)hook->h_Data;
55 register WORD tr, tg, tb;
56 register UWORD tmpw;
57 BYTE r, g, b;
58 UBYTE *row;
59 int y, z = m->bytesperrow;
60 int x;
62 r = rect->r;
63 g = rect->g;
64 b = rect->b;
66 switch(m->colormodel) {
67 case PIXFMT_ARGB32:
68 for(y=rect->ya;y<rect->yb;y++) {
69 row=&ptr[y*z];
70 for(x=rect->xa*4;x<4*rect->xb;x+=4) {
71 tr=row[x+1];
72 tr=tr+r;
73 CLAMP(tr, 0, 255);
74 row[x+1]=tr;
76 tg=row[x+2];
77 tg=tg+g;
78 CLAMP(tg, 0, 255);
79 row[x+2]=tg;
81 tb=row[x+3];
82 tb=tb+b;
83 CLAMP(tb, 0, 255);
84 row[x+3]=tb;
87 break;
88 case PIXFMT_BGRA32:
89 for(y=rect->ya;y<rect->yb;y++) {
90 row=&ptr[y*z];
91 for(x=rect->xa*4;x<4*rect->xb;x+=4) {
92 tb=row[x];
93 tb=tb+b;
94 CLAMP(tb, 0, 255);
95 row[x]=tb;
97 tg=row[x+1];
98 tg=tg+g;
99 CLAMP(tg, 0, 255);
100 row[x+1]=tg;
102 tr=row[x+2];
103 tr=tr+r;
104 CLAMP(tr, 0, 255);
105 row[x+2]=tr;
108 break;
109 case PIXFMT_RGBA32:
110 for(y=rect->ya;y<rect->yb;y++) {
111 row=&ptr[y*z];
112 for(x=rect->xa*4;x<4*rect->xb;x+=4) {
113 tr=row[x];
114 tr=tr+r;
115 CLAMP(tr, 0, 255);
116 row[x]=tr;
118 tg=row[x+1];
119 tg=tg+g;
120 CLAMP(tg, 0, 255);
121 row[x+1]=tg;
123 tb=row[x+2];
124 tb=tb+b;
125 CLAMP(tb, 0, 255);
126 row[x+2]=tb;
129 break;
131 case PIXFMT_RGB24:
132 for(y=rect->ya;y<rect->yb;y++) {
133 row=&ptr[y*z];
134 for(x=rect->xa*3;x<3*rect->xb;x+=3) {
135 tr=row[x];
136 tr=tr+r;
137 CLAMP(tr, 0, 255);
138 row[x]=tr;
140 tg=row[x+1];
141 tg=tg+g;
142 CLAMP(tg, 0, 255);
143 row[x+1]=tg;
145 tb=row[x+2];
146 tb=tb+b;
147 CLAMP(tb, 0, 255);
148 row[x+2]=tb;
151 break;
152 case PIXFMT_BGR24:
153 //kprintf("bgr24\n");
154 for(y=rect->ya;y<rect->yb;y++) {
155 row=&ptr[y*z];
156 for(x=rect->xa*3;x<3*rect->xb;x+=3) {
157 tb=row[x];
158 tb=tb+b;
159 CLAMP(tb, 0, 255);
160 row[x]=tb;
162 tg=row[x+1];
163 tg=tg+g;
164 CLAMP(tg, 0, 255);
165 row[x+1]=tg;
167 tr=row[x+2];
168 tr=tr+r;
169 CLAMP(tr, 0, 255);
170 row[x+2]=tr;
173 break;
175 case PIXFMT_RGB16:
176 r>>=3;
177 b>>=3;
178 g>>=2;
179 for(y=rect->ya;y<rect->yb;y++) {
180 wrow=(UWORD *)&ptr[y*z];
181 for(x=rect->xa;x<rect->xb;x++) {
182 tmpw=wrow[x];
183 tr=M16RED(tmpw);
184 tr=tr+r;
185 CLAMP(tr, 0, 31);
186 tb=M16BLUE(tmpw);
187 tb=tb+b;
188 CLAMP(tb, 0, 31);
189 tg=M16GREEN(tmpw);
190 tg=tg+g;
191 CLAMP(tg, 0, 63);
192 wrow[x]=(tr<<11)|(tb)|(tg<<5);
195 break;
196 case PIXFMT_BGR16:
197 r>>=3;
198 b>>=3;
199 g>>=2;
200 for(y=rect->ya;y<rect->yb;y++) {
201 wrow=(UWORD *)&ptr[y*z];
202 for(x=rect->xa;x<rect->xb;x++) {
203 tmpw=wrow[x];
204 tr=M16BLUE(tmpw);
205 tr=tr+r;
206 CLAMP(tr, 0, 31);
207 tb=M16RED(tmpw);
208 tb=tb+b;
209 CLAMP(tb, 0, 31);
210 tg=M16GREEN(tmpw);
211 tg=tg+g;
212 CLAMP(tg, 0, 63);
213 wrow[x]=(tr<<11)|(tb)|(tg<<5);
216 break;
217 case PIXFMT_BGR16PC:
218 r>>=3;
219 b>>=3;
220 g>>=2;
221 for(y=rect->ya;y<rect->yb;y++) {
222 wrow=(UWORD *)&ptr[y*z];
223 for(x=rect->xa;x<rect->xb;x++) {
224 tmpw=wrow[x];
225 tr=PC16BIT1(tmpw);
226 tr=tr+r;
227 CLAMP(tr, 0, 31);
228 tb=PC16BIT2(tmpw);
229 tb=tb+b;
230 CLAMP(tb, 0, 31);
231 tg=PC16BIT3(tmpw);
232 tg=tg+g;
233 CLAMP(tg, 0, 63);
234 wrow[x]=(tr<<8)|(tb<<3)|((tg&0x38)>>3)|((tg&0x7)<<13);
237 break;
238 case PIXFMT_RGB16PC:
239 r>>=3;
240 b>>=3;
241 g>>=2;
242 for(y=rect->ya;y<rect->yb;y++) {
243 wrow=(UWORD *)&ptr[y*z];
244 for(x=rect->xa;x<rect->xb;x++) {
245 tmpw=wrow[x];
246 tb=PC16BIT1(tmpw);
247 tb=tb+b;
248 CLAMP(tb, 0, 31);
249 tr=PC16BIT2(tmpw);
250 tr=tr+r;
251 CLAMP(tr, 0, 31);
252 tg=PC16BIT3(tmpw);
253 tg=tg+g;
254 CLAMP(tg, 0, 63);
255 wrow[x]=(tb<<8)|(tr<<3)|((tg&0x38)>>3)|((tg&0x7)<<13);
258 break;
259 case PIXFMT_RGB15:
260 r>>=3;
261 b>>=3;
262 g>>=3;
263 for(y=rect->ya;y<rect->yb;y++) {
264 wrow=(UWORD *)&ptr[y*z];
265 for(x=rect->xa;x<rect->xb;x++) {
266 tmpw=wrow[x];
267 tr=M15RED(tmpw);
268 tr=tr+r;
269 CLAMP(tr, 0, 31);
270 tb=M15BLUE(tmpw);
271 tb=tb+b;
272 CLAMP(tb, 0, 31);
273 tg=M15GREEN(tmpw);
274 tg=tg+g;
275 CLAMP(tg, 0, 31);
276 wrow[x]=(tr<<10)|(tb)|(tg<<5);
279 break;
280 case PIXFMT_BGR15:
281 r>>=3;
282 b>>=3;
283 g>>=3;
284 for(y=rect->ya;y<rect->yb;y++) {
285 wrow=(UWORD *)&ptr[y*z];
286 for(x=rect->xa;x<rect->xb;x++) {
287 tmpw=wrow[x];
288 tr=M15BLUE(tmpw);
289 tr=tr+r;
290 CLAMP(tr, 0, 31);
291 tb=M15RED(tmpw);
292 tb=tb+b;
293 CLAMP(tb, 0, 31);
294 tg=M15GREEN(tmpw);
295 tg=tg+g;
296 CLAMP(tg, 0, 31);
297 wrow[x]=(tr<<10)|(tb)|(tg<<5);
300 break;
301 case PIXFMT_BGR15PC:
302 r>>=3;
303 b>>=3;
304 g>>=3;
305 for(y=rect->ya;y<rect->yb;y++) {
306 wrow=(UWORD *)&ptr[y*z];
307 for(x=rect->xa;x<rect->xb;x++) {
308 tmpw=wrow[x];
309 tr=PC15BIT1(tmpw);
310 tr=tr+r;
311 CLAMP(tr, 0, 31);
312 tb=PC15BIT2(tmpw);
313 tb=tb+b;
314 CLAMP(tb, 0, 31);
315 tg=PC15BIT3(tmpw);
316 tg=tg+g;
317 CLAMP(tg, 0, 31);
318 wrow[x]=(tr<<8)|(tb<<2)|((tg)>>3)|((tg&0x7)<<13);
321 break;
322 case PIXFMT_RGB15PC:
323 r>>=3;
324 b>>=3;
325 g>>=3;
326 for(y=rect->ya;y<rect->yb;y++) {
327 wrow=(UWORD *)&ptr[y*z];
328 for(x=rect->xa;x<rect->xb;x++) {
329 tmpw=wrow[x];
330 tb=PC15BIT1(tmpw);
331 tb=tb+b;
332 CLAMP(tb, 0, 31);
333 tr=PC15BIT2(tmpw);
334 tr=tr+r;
335 CLAMP(tr, 0, 31);
336 tg=PC15BIT3(tmpw);
337 tg=tg+g;
338 CLAMP(tg, 0, 31);
339 wrow[x]=(tb<<8)|(tr<<2)|((tg)>>3)|((tg&0x7)<<13);
342 break;
345 return 0;
348 // PM_DrawShadow - This function draws a shadow in a PM_Window. The shadow
349 // will be a rectangle defined by x, y - xb, yb (left, top - right, bottom)
351 void PM_DrawShadow(struct PM_Window *w, int x, int y, int xb, int yb)
353 static UWORD pat[] = { 0xaaaa, 0x5555 };
354 #ifndef __AROS__
355 struct Hook shadehook;
356 struct ShRect rect;
357 ULONG depth = 0, iscgfx = FALSE;
358 // BOOL realshadow = PM_Prefs->RealShadows;
359 BOOL realshadow = TRUE;
361 // Shall we draw a real CGFX shadow?
362 if(CyberGfx && realshadow) {
363 iscgfx=GetCyberMapAttr(w->RPort->BitMap, CYBRMATTR_ISCYBERGFX);
364 if(iscgfx) depth=GetCyberMapAttr(w->RPort->BitMap, CYBRMATTR_DEPTH);
365 if(iscgfx && depth>8) {
366 rect.xa = x + w->Wnd->LeftEdge;
367 rect.xb = xb + 1 + w->Wnd->LeftEdge;
368 rect.ya = y + w->Wnd->TopEdge;
369 rect.yb = yb + 1 + w->Wnd->TopEdge;
371 rect.r = PM_Prefs->pmp_ShadowR;
372 rect.g = PM_Prefs->pmp_ShadowG;
373 rect.b = PM_Prefs->pmp_ShadowB;
375 shadehook.h_Data = &rect;
376 shadehook.h_Entry = HookEntry;
377 shadehook.h_SubEntry = (HOOKFUNC)shadefunc;
379 DoCDrawMethodTagList(&shadehook, w->RPort, NULL);
381 } else realshadow = FALSE;
382 } else realshadow = FALSE;
384 if(!realshadow)
385 #endif
388 // A "real" shadow could not be drawn, or it was not desired.
390 SetAPen(w->RPort, 1); // Should use DRIPen
391 SetAfPt(w->RPort, pat, 1);
392 PM_RectFill(w, x, y, xb, yb);
393 SetAfPt(w->RPort, NULL, 0);