Converted colorwheel gadget to use %build_module and genmodule.
[AROS.git] / workbench / classes / gadgets / colorwheel / support.c
blob88001e951a70cadb6c2976170ce2097c1339b498
1 /*
2 Copyright © 1995-2005, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Support functions for the colorwheel class
6 Lang: English
7 */
9 #include <exec/memory.h>
10 #include <graphics/gfxmacros.h>
11 #include <intuition/classes.h>
12 #include <intuition/cghooks.h>
13 #include <intuition/gadgetclass.h>
14 #include <intuition/imageclass.h>
15 #include <intuition/screens.h>
16 #include <intuition/intuition.h>
17 #include <proto/exec.h>
18 #include <proto/graphics.h>
19 #include <proto/intuition.h>
20 #include <proto/colorwheel.h>
21 #include <proto/cybergraphics.h>
22 #ifdef __AROS__
23 #include <cybergraphx/cybergraphics.h>
24 #else
25 #include <cybergraphics/cybergraphics.h>
26 #endif
28 #include <gadgets/colorwheel.h>
30 #include "colorwheel_intern.h"
32 #ifndef __AROS__
33 #include "bmbmrp.h"
34 #endif
36 #if FIXED_MATH
37 #include "fixmath.h"
38 #else
39 #include <math.h>
40 #endif
42 /***************************************************************************************************/
44 #ifdef __AROS__
45 #define SDEBUG 0
46 #define DEBUG 0
47 #include <aros/debug.h>
48 #endif
50 #if FIXED_MATH
51 #define SQR(x) FixMul( (x), (x) )
52 #else
53 #define SQR(x) ((x) * (x))
54 #endif
56 #define CW_PI 3.14159265358979
58 #define USE_WRITEPIXELARRAY 1
59 #define USE_SYMMETRIC_SPEEDUP 1
61 #define MAKE_RGB_BE(r,g,b) ( (((r) >> 8) & 0x00FF0000) | \
62 (((g) >> 16) & 0x0000FF00) | \
63 (((b) >> 24) & 0x000000FF) )
65 #define MAKE_RGB_LE(r,g,b) ( (((r) >> 16) & 0x0000FF00) | \
66 (((g) >> 8) & 0x00FF0000) | \
67 (((b) >> 0) & 0xFF000000) )
69 #ifdef __AROS__
70 #if !AROS_BIG_ENDIAN
71 # define MAKE_RGB(r,g,b) MAKE_RGB_LE(r,g,b)
72 #else
73 # define MAKE_RGB(r,g,b) MAKE_RGB_BE(r,g,b)
74 #endif
75 #else
76 # define MAKE_RGB(r,g,b) MAKE_RGB_BE(r,g,b)
77 #endif
79 /****************************************************************************/
81 UBYTE Bayer16[16][16] =
83 { 1,235, 59,219, 15,231, 55,215, 2,232, 56,216, 12,228, 52,212},
84 { 129, 65,187,123,143, 79,183,119,130, 66,184,120,140, 76,180,116},
85 { 33,193, 17,251, 47,207, 31,247, 34,194, 18,248, 44,204, 28,244},
86 { 161, 97,145, 81,175,111,159, 95,162, 98,146, 82,172,108,156, 92},
87 { 9,225, 49,209, 5,239, 63,223, 10,226, 50,210, 6,236, 60,220},
88 { 137, 73,177,113,133, 69,191,127,138, 74,178,114,134, 70,188,124},
89 { 41,201, 25,241, 37,197, 21,255, 42,202, 26,242, 38,198, 22,252 },
90 { 169,105,153, 89,165,101,149, 85,170,106,154, 90,166,102,150, 86},
91 { 3,233, 57,217, 13,229, 53,213, 0,234, 58,218, 14,230, 54,214},
92 { 131, 67,185,121,141, 77,181,117,128, 64,186,122,142, 78,182,118},
93 { 35,195, 19,249, 45,205, 29,245, 32,192, 16,250, 46,206, 30,246},
94 { 163, 99,147, 83,173,109,157, 93,160, 96,144, 80,174,110,158, 94},
95 { 11,227, 51,211, 7,237, 61,221, 8,224, 48,208, 4,238, 62,222},
96 { 139, 75,179,115,135, 71,189,125,136, 72,176,112,132, 68,190,126},
97 { 43,203, 27,243, 39,199, 23,253, 40,200, 24,240, 36,196, 20,255 },
98 { 171,107,155, 91,167,103,151, 87,168,104,152, 88,164,100,148, 84}
101 #ifndef __AROS__
102 extern void ConvertHSBToRGB( REG(a0, struct ColorWheelHSB *hsb), REG(a1, struct ColorWheelRGB *rgb) );
103 #endif
105 #ifndef __AROS__
106 #undef SysBase
107 void kprintf( STRPTR FormatStr, ... )
109 TEXT PutChData[64];
110 STRPTR p = PutChData;
111 struct Library *SysBase = (*(struct Library **)4L);
112 RawDoFmt(FormatStr, ((STRPTR)(&FormatStr))+4, (void (*)())"\x16\xc0\x4e\x75", PutChData);
114 do RawPutChar( *p );
115 while( *p++ );
117 #define SysBase CWB(ColorWheelBase)->sysbase
118 #endif
120 /***************************************************************************************************/
122 #if FIXED_MATH
123 BOOL CalcWheelColor(LONG x, LONG y, LONG cx, LONG cy, ULONG *hue, ULONG *sat)
125 Fixed32 r, l, h, s, sinus;
126 LONG rx, ry;
128 rx = cx - x;
129 ry = ( y - cy ) * cx / cy;
131 r = FixSqrti( (rx*rx) + (ry*ry) );
133 h = (r != 0) ? FixAtan2( FixDiv( INT_TO_FIXED(rx), r ), FixDiv( INT_TO_FIXED(ry), r ) ) : 0;
135 l = FixSqrti( FIXED_TO_INT( (FixSqr( cx * FixSinCos( h + (FIXED_PI/2), &sinus ) ) +
136 FixSqr( cx * sinus )) ) );
138 s = FixDiv( r, l );
140 h = FixMul( h + FIXED_PI, 10430 ); // == FixDiv( h + FIXED_PI, FIXED_2PI );
142 if (s == 0) s = 1;
143 else if (s >= FIXED_ONE)
144 s = FIXED_ONE-1;
146 h &= 0xffff;
148 *hue = ( h << 16 ) | h;
149 *sat = ( s << 16 ) | s;
151 return (r <= INT_TO_FIXED(cx));
153 #else
154 BOOL CalcWheelColor(LONG x, LONG y, double cx, double cy, ULONG *hue, ULONG *sat)
156 double d, r, rx, ry, l, h, s;
158 #if 1
159 /* Should also work with not perfect (cy == cy) circle */
161 rx = (double) cx - x;
162 ry = ((double) y - cy) * cx / cy;
164 /* d = (SQR(cx) * SQR(rx) + SQR(cx) * SQR(ry) - SQR(cx) * SQR(cx)); */
166 r = sqrt (SQR(rx) + SQR(ry));
167 if (r > cx) d = 1.0; else d = 0.0;
169 if (r != 0.0)
170 h = atan2 (rx / r, ry / r);
171 else
172 h = 0.0;
174 l = sqrt (SQR((cx * cos (h + 0.5 * CW_PI))) + SQR((cx * sin (h + 0.5 * CW_PI))));
175 /* ^^ ^^ */
176 /* no bug! */
178 #else
179 /* Does not work well if cx != cy (elliptical shape) */
181 rx = (double) cx - x;
182 ry = (double) y - cy;
184 d = (SQR(cy) * SQR(rx) + SQR(cx) * SQR(ry) - SQR(cx) * SQR(cy));
186 r = sqrt (SQR(rx) + SQR(ry));
188 if (r != 0.0)
189 h = atan2 (rx / r, ry / r);
190 else
191 h = 0.0;
193 l = sqrt (SQR((cx * cos (h + 0.5 * CW_PI))) + SQR((cy * sin (h + 0.5 * CW_PI))));
194 #endif
196 s = r / l;
197 h = (h + CW_PI) / (2.0 * CW_PI);
199 if (s == 0.0)
200 s = 0.00001;
201 else if (s > 1.0)
202 s = 1.0;
204 *hue = (ULONG)rint (h * 0xFFFFFFFF);
205 *sat = (ULONG)rint (s * 0xFFFFFFFF);
207 return (d > 0.0) ? FALSE : TRUE;
209 #endif
211 /***************************************************************************************************/
213 STATIC VOID CalcKnobPos(struct ColorWheelData *data, WORD *x, WORD *y)
215 #if FIXED_MATH
216 Fixed32 alpha, sat, sinus;
218 alpha = data->hsb.cw_Hue >> 16;
219 alpha = FixMul( FIXED_2PI, alpha ) - (FIXED_PI/2);
221 sat = data->hsb.cw_Saturation >> 16;
223 *x = data->wheelcx + (WORD) FIXED_TO_INT( FixMul( ( (LONG) data->wheelrx ) * sat, FixSinCos(alpha,&sinus) ) );
224 *y = data->wheelcy + (WORD) FIXED_TO_INT( FixMul( ( (LONG) data->wheelry ) * sat, sinus ) );
225 #else
226 double alpha, sat;
228 alpha = (double)data->hsb.cw_Hue / (double) 0xFFFFFFFF;
229 alpha *= CW_PI * 2.0;
230 alpha -= CW_PI / 2.0;
232 sat = (double)data->hsb.cw_Saturation / (double) 0xFFFFFFFF;
234 *x = data->wheelcx + (WORD) ((double)data->wheelrx * sat * cos(alpha));
235 *y = data->wheelcy + (WORD) ((double)data->wheelry * sat * sin(alpha));
236 #endif
239 /***************************************************************************************************/
241 STATIC VOID TrueWheel(struct ColorWheelData *data, struct RastPort *rp, struct IBox *box,
242 struct Library *ColorWheelBase
245 struct ColorWheelHSB hsb;
246 struct ColorWheelRGB rgb;
247 ULONG col;
248 WORD x, y, left, top, width, height;
249 #if FIXED_MATH
250 LONG cx, cy;
251 #else
252 double cx, cy;
253 #endif
255 left = box->Left;
256 top = box->Top;
257 width = box->Width;
258 height = box->Height;
259 #if FIXED_MATH
260 cx = width / 2;
261 cy = height / 2;
262 #else
263 cx = (double)width / 2.0;
264 cy = (double)height / 2.0;
265 #endif
267 hsb.cw_Brightness = 0xFFFFFFFF;
269 #if USE_WRITEPIXELARRAY
270 if (!data->rgblinebuffer || data->rgblinebuffer_size < width)
272 if (data->rgblinebuffer) FreeVec(data->rgblinebuffer);
274 data->rgblinebuffer = AllocVec(width * sizeof(LONG), MEMF_ANY);
275 data->rgblinebuffer_size = width;
277 #endif
279 if (data->rgblinebuffer)
281 ULONG backrgb[3];
282 ULONG backcol;
284 GetRGB32(data->scr->ViewPort.ColorMap, 0, 1, backrgb);
286 backcol = ((backrgb[0] >> 8) & 0xFF0000) |
287 ((backrgb[1] >> 16) & 0x00FF00) |
288 ((backrgb[2] >> 24) & 0x0000FF);
290 for(y = 0; y < height; y++)
292 UWORD startX = 0, w = width;
293 ULONG *p = data->rgblinebuffer;
294 #if USE_SYMMETRIC_SPEEDUP
295 ULONG *p2 = &p[width];
296 for(x = 0; x < width / 2; x++)
298 #else
299 for(x = 0; x < width; x++)
300 #endif
302 if (CalcWheelColor(x, y, cx, cy, &hsb.cw_Hue, &hsb.cw_Saturation))
304 ConvertHSBToRGB(&hsb, &rgb);
306 col = MAKE_RGB(rgb.cw_Red, rgb.cw_Green, rgb.cw_Blue);
308 *p++ = col;
309 #if USE_SYMMETRIC_SPEEDUP
310 col = MAKE_RGB(rgb.cw_Red, rgb.cw_Blue, rgb.cw_Green);
311 *--p2 = col;
312 #endif
313 } else {
314 p++;
315 w--; startX++;
316 #if USE_SYMMETRIC_SPEEDUP
317 w--; --p2;
318 #endif
321 } /* for(x = 0; x < width; x++) */
323 if (w) WritePixelArray(&data->rgblinebuffer[startX],
326 0, //width * sizeof(LONG),
328 startX+left,
329 top + y,
332 RECTFMT_ARGB);
334 } /* for(y = 0; y < height; y++) */
336 } /* if (data->rgblinebuffer) */
337 else
339 for(y = 0; y < height; y++)
341 #if USE_SYMMETRIC_SPEEDUP
342 for(x = 0; x < width / 2; x++)
343 #else
344 for(x = 0; x < width; x++)
345 #endif
347 if (CalcWheelColor(x, y, cx, cy, &hsb.cw_Hue, &hsb.cw_Saturation))
349 ConvertHSBToRGB(&hsb, &rgb);
351 col = MAKE_RGB_BE(rgb.cw_Red, rgb.cw_Green, rgb.cw_Blue);
353 WriteRGBPixel(rp, left + x, top + y, col);
355 #if USE_SYMMETRIC_SPEEDUP
356 col = MAKE_RGB_BE(rgb.cw_Red, rgb.cw_Blue, rgb.cw_Green);
358 WriteRGBPixel(rp, left + width - 1 - x, top + y , col);
359 #endif
362 } /* for(x = 0; x < width; x++) */
364 } /* for(y = 0; y < height; y++) */
366 } /* data->rgbinebuffer == NULL */
369 /****************************************************************************/
371 STATIC VOID ClutWheel(struct ColorWheelData *data, struct RastPort *rp, struct IBox *box,
372 struct Library *ColorWheelBase
375 struct ColorWheelHSB hsb;
376 struct ColorWheelRGB rgb;
377 struct RastPort *tRP = &data->trp;
378 struct BitMap *tBM;
379 // ULONG col;
380 WORD x, y, left, top, width, height;
381 #if FIXED_MATH
382 LONG cx, cy;
383 #else
384 double cx, cy;
385 #endif
386 UBYTE *buf;
388 left = box->Left;
389 top = box->Top;
390 width = box->Width;
391 height = box->Height;
393 if( data->gotpens != TRUE )
395 STRPTR abbrv = data->abbrv;
396 PLANEPTR ras;
397 UWORD cx = data->wheelcx,
398 cy = data->wheelcy,
399 rx = data->wheelrx - 4,
400 ry = data->wheelry - 4,
401 depth = GetBitMapAttr( rp->BitMap, BMA_DEPTH );
402 ULONG rasSize;
404 rasSize = RASSIZE( width*depth, height );
406 #ifndef USE_ALLOCRASTER
407 if( ( ras = AllocVec( rasSize, MEMF_CHIP ) ) )
408 #else
409 if( ( ras = AllocRaster( width*depth, height ) ) )
410 #endif
412 struct AreaInfo ai;
413 struct TmpRas tr;
414 ULONG pattern = 0xaaaa5555;
415 UWORD black = FindColor( data->scr->ViewPort.ColorMap, 0,0,0, -1 ),
416 white = FindColor( data->scr->ViewPort.ColorMap, ~0,~0,~0, -1 ),
417 buf[10] = {};
418 WORD endx, endy, TxOffset;
420 InitArea( &ai, buf, sizeof( buf ) / 5 );
421 rp->AreaInfo = &ai;
422 rp->TmpRas = &tr;
423 InitTmpRas( &tr, ras, rasSize );
425 SetAPen( rp, black );
427 AreaEllipse( rp, cx, cy, rx, ry );
428 AreaEnd( rp );
430 SetAPen( rp, white );
431 SetFont( rp, data->dri->dri_Font );
433 TxOffset = rp->TxHeight-rp->TxBaseline;
435 endx = 500*rx/2000, // 30°
436 endy = -865*ry/2000;
438 Move( rp, cx + rx/2, cy );
439 Draw( rp, cx + rx, cy );
441 Move( rp, cx - rx/2, cy );
442 Draw( rp, cx - rx, cy );
444 Move( rp, cx + endx, cy + endy );
445 Draw( rp, cx + 2*endx, cy + 2*endy );
447 Move( rp, cx + endx, cy - endy );
448 Draw( rp, cx + 2*endx, cy - 2*endy );
450 Move( rp, cx - endx, cy + endy );
451 Draw( rp, cx - 2*endx, cy + 2*endy );
453 Move( rp, cx - endx, cy - endy );
454 Draw( rp, cx - 2*endx, cy - 2*endy );
456 endx = 866*rx/1500; // 60°
457 endy = -499*ry/1500;
459 Move( rp, cx + endx + ( TextLength( rp, abbrv, 1L ) / 2 ), cy - (endy - TxOffset) );
460 Text( rp, abbrv++, 1L ); // G
462 Move( rp, cx - ( TextLength( rp, abbrv, 1L ) / 2 ), cy + (ry - ry/4) + TxOffset );
463 Text( rp, abbrv++, 1L ); // C
465 Move( rp, cx - endx - ( TextLength( rp, abbrv, 1L ) ), cy - (endy - TxOffset) );
466 Text( rp, abbrv++, 1L ); // B
468 Move( rp, cx - endx - ( TextLength( rp, abbrv, 1L ) ), cy + (endy - TxOffset) );
469 Text( rp, abbrv++, 1L ); // M
471 Move( rp, cx - ( TextLength( rp, abbrv, 1L ) / 2 ), cy - (ry - ry/4) + TxOffset );
472 Text( rp, abbrv++, 1L ); // R
474 Move( rp, cx + endx + ( TextLength( rp, abbrv, 1L ) / 2 ), cy + (endy + TxOffset) );
475 Text( rp, abbrv++, 1L ); // Y
477 SetAfPt( rp, (UWORD *)&pattern, 1L );
479 AreaEllipse( rp, cx, cy, rx/2, ry/2 );
480 AreaEnd( rp );
482 SetAfPt( rp, NULL, 0L );
484 AreaEllipse( rp, cx, cy, rx/5, ry/5 );
485 AreaEnd( rp );
487 WaitBlit();
488 #ifndef USE_ALLOCRASTER
489 FreeVec( ras );
490 #else
491 FreeRaster( ras, width*depth,height );
492 #endif
494 rp->AreaInfo = NULL;
495 rp->TmpRas = NULL;
498 return;
501 #if FIXED_MATH
502 cx = width / 2;
503 cy = height / 2;
504 #else
505 cx = (double)width / 2.0;
506 cy = (double)height / 2.0;
507 #endif
509 hsb.cw_Brightness = 0xFFFFFFFF;
511 if( ( tBM = AllocBitMap( width,1, GetBitMapAttr( rp->BitMap, BMA_DEPTH ), 0L, NULL ) ) )
513 tRP->BitMap = tBM;
515 if( ( buf = AllocVec( (((width+15)>>4)<<4), MEMF_ANY ) ) )
517 LONG range = data->range,
518 levels = data->levels;
520 for(y = 0; y < height; y++)
522 UWORD startX = 0, w = width;
523 UBYTE *p = buf;
524 #if USE_SYMMETRIC_SPEEDUP
525 UBYTE *p2 = &p[width];
526 for(x = 0; x < width / 2; x++)
527 #else
528 for(x = 0; x < width; x++)
529 #endif
531 if (CalcWheelColor(x, y, cx, cy, &hsb.cw_Hue, &hsb.cw_Saturation))
533 LONG t,v, r,g,b, base;
535 ConvertHSBToRGB(&hsb, &rgb);
537 t = Bayer16[y & 15][x & 15];
539 t = (t * range) / 255;
541 v = ( rgb.cw_Red >> 24 );
542 base = (v / range) * range;
543 r = (v - base > t) ? base + range : base;
545 v = ( rgb.cw_Green >> 24 );
546 base = (v / range) * range;
547 g = (v - base > t) ? base + range : base;
549 v = ( rgb.cw_Blue >> 24 );
550 base = (v / range) * range;
551 b = (v - base > t) ? base + range : base;
553 r /= range;if (r >= levels) r = levels - 1;
554 g /= range;if (g >= levels) g = levels - 1;
555 b /= range;if (b >= levels) b = levels - 1;
557 r *= levels*levels;
559 base = r + (g*levels) + b;
560 *p++ = data->pens[ base ];
562 #if USE_SYMMETRIC_SPEEDUP
563 base = r + (b*levels) + g;
564 *--p2 = data->pens[ base ];
565 #endif
567 else
569 startX++;
570 w--; p++;
571 #if USE_SYMMETRIC_SPEEDUP
572 w--; --p2;
573 #endif
576 } /* for(x = 0; x < width; x++) */
578 if (w)
579 WritePixelLine8( rp, startX+left,top+y, w, &buf[startX], tRP );
581 } /* for(y = 0; y < height; y++) */
583 FreeVec( buf );
586 WaitBlit();
587 FreeBitMap( tBM );
591 /***************************************************************************************************/
593 VOID RenderWheel(struct ColorWheelData *data, struct RastPort *rp, struct IBox *box,
594 struct Library *ColorWheelBase
597 struct IBox wbox;
598 struct RastPort temprp;
599 WORD cx, cy, rx, ry;
601 cx = data->frame ? BORDERWHEELSPACINGX * 4 : BORDERWHEELSPACINGX * 2;
602 cy = data->frame ? BORDERWHEELSPACINGY * 4 : BORDERWHEELSPACINGY * 2;
604 data->wheeldrawn = FALSE;
606 if ( (box->Width < cx) || (box->Height < cy) ) return;
608 if (!data->bm || (box->Width != data->bmwidth) || (box->Height != data->bmheight))
610 if (data->bm)
612 WaitBlit();
614 if (data->mask)
616 #ifdef USE_ALLOCRASTER
617 FreeRaster( data->mask,
618 GetBitMapAttr( data->bm, BMA_WIDTH ),
619 GetBitMapAttr( data->bm, BMA_HEIGHT ) );
620 #else
621 FreeVec( data->mask );
622 #endif
624 data->mask = NULL;
627 FreeBitMap(data->bm);
630 data->bm = AllocBitMap(box->Width,
631 box->Height,
632 GetBitMapAttr(rp->BitMap, BMA_DEPTH),
633 BMF_MINPLANES,
634 rp->BitMap);
636 if (data->bm)
638 data->bmwidth = box->Width;
639 data->bmheight = box->Height;
641 wbox.Left = data->frame ? BORDERWHEELSPACINGX : 2;
642 wbox.Top = data->frame ? BORDERWHEELSPACINGY : 2;
643 wbox.Width = (box->Width - (data->frame ? BORDERWHEELSPACINGX * 2 : 4)) & ~1;
644 wbox.Height = (box->Height - (data->frame ? BORDERWHEELSPACINGY * 2 : 4)) & ~1;
645 #if FIXED_MATH
646 if( wbox.Width > 440 )
648 wbox.Left += (wbox.Width-440)/2;
649 wbox.Width = 440;
652 if( wbox.Height > 440 )
654 wbox.Top += (wbox.Height-440)/2;
655 wbox.Height = 440;
657 #endif
658 InitRastPort(&temprp);
659 temprp.BitMap = data->bm;
661 SetDrMd(&temprp, JAM1);
662 SetRast( &temprp, data->dri->dri_Pens[ BACKGROUNDPEN ] );
664 rx = wbox.Width / 2;
665 ry = wbox.Height / 2;
667 cx = wbox.Left + rx;
668 cy = wbox.Top + ry;
670 data->wheelcx = cx;
671 data->wheelcy = cy;
672 data->wheelrx = rx;
673 data->wheelry = ry;
675 if (data->frame)
677 struct TagItem fitags[] =
679 {IA_Width , box->Width },
680 {IA_Height , box->Height },
681 {TAG_DONE }
684 SetAttrsA(data->frame, fitags);
685 DrawImageState(&temprp, (struct Image *)data->frame, 0, 0, IDS_NORMAL, data->dri);
687 else
689 struct BitMap maskBM;
690 ULONG bmWidth, bmHeight, rasSize;
691 PLANEPTR ras;
693 bmWidth = GetBitMapAttr( data->bm, BMA_WIDTH );
694 bmHeight = GetBitMapAttr( data->bm, BMA_HEIGHT );
695 InitBitMap( &maskBM, 1L, bmWidth, bmHeight );
697 rasSize = RASSIZE( bmWidth, bmHeight );
699 #ifdef USE_ALLOCRASTER
700 if( ( ras = AllocRaster( bmWidth, bmHeight ) ) )
701 #else
702 if( ( ras = AllocVec( rasSize, MEMF_CHIP ) ) )
703 #endif
705 #ifdef USE_ALLOCRASTER
706 if( ( data->mask = AllocRaster( bmWidth, bmHeight ) ) )
707 #else
708 if( ( data->mask = AllocVec( rasSize, MEMF_CHIP ) ) )
709 #endif
711 struct AreaInfo ai;
712 struct TmpRas tr;
713 struct RastPort *maskRP = &data->trp;
714 UWORD buf[10] = {};
716 maskRP->BitMap = &maskBM;
717 maskBM.Planes[0] = data->mask;
718 InitArea( &ai, buf, sizeof( buf ) / 5 );
719 maskRP->AreaInfo = &ai;
720 maskRP->TmpRas = &tr;
721 InitTmpRas( &tr, ras, rasSize );
723 SetRast( maskRP, 0L );
724 SetAPen( maskRP, 1L );
725 AreaEllipse( maskRP, cx,cy, rx,ry );
726 AreaEnd( maskRP );
727 WaitBlit();
729 if (!data->savebm)
731 data->savebm = AllocBitMap(
732 KNOBWIDTH, KNOBHEIGHT,
733 GetBitMapAttr(rp->BitMap, BMA_DEPTH),
734 BMF_MINPLANES, rp->BitMap );
737 maskRP->AreaInfo = NULL;
738 maskRP->TmpRas = NULL;
741 #ifndef USE_ALLOCRASTER
742 FreeVec( ras );
743 #else
744 FreeRaster( ras, bmWidth, bmHeight );
745 #endif
750 if (CyberGfxBase && (GetBitMapAttr(data->bm, BMA_DEPTH) >= 15))
752 TrueWheel(data, &temprp, &wbox, ColorWheelBase);
753 } else {
754 ClutWheel(data, &temprp, &wbox, ColorWheelBase);
757 SetAPen(&temprp, data->dri->dri_Pens[SHADOWPEN]);
758 DrawEllipse(&temprp, cx, cy, rx, ry);
759 DrawEllipse(&temprp, cx, cy, rx - 1, ry);
760 DrawEllipse(&temprp, cx, cy, rx, ry - 1);
761 DrawEllipse(&temprp, cx, cy, rx - 1, ry - 1);
763 DeinitRastPort(&temprp);
765 } /* if (data->bm) */
767 } /* if (!data->bm || (box->Width != data->bmwidth) || (box->Height != data->bmheight)) */
769 if (data->bm)
771 if(data->mask)
773 EraseRect( rp, box->Left,box->Top, box->Left+box->Width-1, box->Top+box->Height-1 );
774 #ifdef __AROS__
775 BltMaskBitMapRastPort(
776 data->bm, 0, 0,
777 rp, box->Left, box->Top, box->Width, box->Height,
778 0xe0, data->mask);
779 #else
780 NewBltMaskBitMapRastPort(
781 data->bm, 0, 0,
782 rp, box->Left, box->Top, box->Width, box->Height,
783 0xe0, data->mask, (struct Library *)GfxBase, LayersBase );
784 #endif
786 else BltBitMapRastPort(data->bm, 0, 0, rp, box->Left, box->Top, box->Width, box->Height, 0xC0);
788 data->wheeldrawn = TRUE;
793 /***************************************************************************************************/
795 VOID RenderKnob(struct ColorWheelData *data, struct RastPort *rp,
796 struct IBox *gbox, BOOL update
799 WORD x, y;
801 if (!data->wheeldrawn) return;
803 if (update)
805 /* Restore */
807 if (data->savebm)
808 BltBitMapRastPort(data->savebm,
809 0,0,
811 data->knobsavex + gbox->Left,
812 data->knobsavey + gbox->Top,
813 KNOBWIDTH,
814 KNOBHEIGHT,
815 0xC0);
816 else
817 BltBitMapRastPort(data->bm,
818 data->knobsavex,data->knobsavey,
820 data->knobsavex + gbox->Left,
821 data->knobsavey + gbox->Top,
822 KNOBWIDTH,
823 KNOBHEIGHT,
824 0xC0);
827 CalcKnobPos(data, &x, &y);
829 if (x < KNOBCX) x = KNOBCX; else if (x > gbox->Width - 1 - KNOBCX) x = gbox->Width - 1 - KNOBCX;
830 if (y < KNOBCY) y = KNOBCY; else if (y > gbox->Height - 1 - KNOBCY) y = gbox->Height - 1 - KNOBCY;
832 /* Backup */
834 data->knobsavex = x - KNOBCX;
835 data->knobsavey = y - KNOBCY;
837 /* Render */
839 x += gbox->Left;
840 y += gbox->Top;
842 if (data->savebm)
844 data->trp.BitMap = data->savebm;
845 ClipBlit(rp, x-KNOBCX,y-KNOBCY, &data->trp, 0,0, KNOBWIDTH,KNOBHEIGHT, 0xc0 );
848 SetDrMd(rp, JAM1);
850 SetAPen(rp, data->dri->dri_Pens[SHADOWPEN]);
852 RectFill(rp, x - 3, y - 1, x - 3, y + 1);
853 RectFill(rp, x - 2, y - 2, x - 2, y + 2);
854 RectFill(rp, x - 1, y - 3, x + 1, y + 3);
855 RectFill(rp, x + 2, y - 2, x + 2, y + 2);
856 RectFill(rp, x + 3, y - 1, x + 3, y + 1);
858 SetAPen(rp, data->dri->dri_Pens[SHINEPEN]);
860 RectFill(rp, x - 1, y, x + 1, y);
861 RectFill(rp, x, y - 1, x, y + 1);
864 /***************************************************************************************************/
866 VOID GetGadgetIBox(Object *o, struct GadgetInfo *gi, struct IBox *ibox)
868 ibox->Left = EG(o)->LeftEdge;
869 ibox->Top = EG(o)->TopEdge;
870 ibox->Width = EG(o)->Width;
871 ibox->Height = EG(o)->Height;
873 if (gi)
875 if (EG(o)->Flags & GFLG_RELRIGHT)
876 ibox->Left += gi->gi_Domain.Width - 1;
878 if (EG(o)->Flags & GFLG_RELBOTTOM)
879 ibox->Top += gi->gi_Domain.Height - 1;
881 if (EG(o)->Flags & GFLG_RELWIDTH)
882 ibox->Width += gi->gi_Domain.Width;
884 if (EG(o)->Flags & GFLG_RELHEIGHT)
885 ibox->Height += gi->gi_Domain.Height;
890 /***************************************************************************************************/
892 void DrawDisabledPattern(struct ColorWheelData *data, struct RastPort *rport,
893 struct IBox *gadbox
896 ULONG pattern = 0x88882222;
898 EnterFunc(bug("DrawDisabledPattern(rp=%p, gadbox=%p, pen=%d)\n",
899 rport, gadbox, pen));
901 SetDrMd( rport, JAM1 );
902 SetAPen( rport, data->dri->dri_Pens[SHADOWPEN] );
903 SetAfPt( rport, (UWORD *)&pattern, 1);
905 if( ! data->frame )
907 PLANEPTR ras;
908 ULONG rasSize;
909 UWORD rx = data->wheelrx,
910 ry = data->wheelry,
911 d = GetBitMapAttr( data->bm, BMA_DEPTH );
913 if( d > 8 ) d = 8;
915 rasSize = RASSIZE( rx*2*d, ry*2 );
916 #ifdef USE_ALLOCRASTER
917 if( ( ras = AllocRaster( rx*2*d, ry*2 ) ) )
918 #else
919 if( ( ras = AllocVec( rasSize, MEMF_CHIP ) ) )
920 #endif
922 struct AreaInfo ai;
923 struct TmpRas tr;
924 UWORD buf[10] = {};
926 InitArea( &ai, buf, sizeof( buf ) / 5 );
927 rport->AreaInfo = &ai;
928 InitTmpRas( &tr, ras, rasSize );
929 rport->TmpRas = &tr;
931 AreaEllipse( rport,
932 gadbox->Left+data->wheelcx,
933 gadbox->Top+data->wheelcy, rx,ry );
935 AreaEnd( rport );
936 WaitBlit();
938 rport->AreaInfo = NULL;
939 rport->TmpRas = NULL;
941 SetAfPt ( rport, NULL, 0);
942 #ifdef USE_ALLOCRASTER
943 FreeRaster( ras, rx*2*d, ry*2 );
944 #else
945 FreeVec( ras );
946 #endif
947 ReturnVoid("DrawDisabledPattern");
951 /* render disable pattern */
952 RectFill( rport, gadbox->Left,
953 gadbox->Top,
954 gadbox->Left + gadbox->Width - 1,
955 gadbox->Top + gadbox->Height - 1);
957 SetAfPt ( rport, NULL, 0);
959 ReturnVoid("DrawDisabledPattern");
962 /***************************************************************************************************/
964 BOOL getPens( struct ColorWheelData *data )
966 struct ColorMap *cm = data->scr->ViewPort.ColorMap;
967 LONG r,g,b, levels = data->levels, range = data->range, i;
968 WORD *p, *donation = data->donation;
970 for(p = data->pens, i = levels-1, r = 0 ; r < levels ; r++)
972 for(g = 0 ; g < levels ; g++)
974 for(b = 0 ; b < levels ; b++)
976 if( r == i || g == i || b == i )
978 if( donation && *donation != -1 )
980 ULONG tab[] =
982 ( 1 << 16 ) | ( *donation ),
983 (r*range)*0x01010101,
984 (g*range)*0x01010101,
985 (b*range)*0x01010101,
989 LoadRGB32( &data->scr->ViewPort, tab );
990 *p++ = *donation++;
992 else
994 static struct TagItem tags[] =
996 {OBP_Precision, PRECISION_EXACT},
997 {OBP_FailIfBad, TRUE},
998 {TAG_DONE}
1001 if( ( *p++ = ObtainBestPenA( cm,
1002 (r*range)*0x01010101,
1003 (g*range)*0x01010101,
1004 (b*range)*0x01010101, tags ) ) == -1L )
1006 WORD *p2 = data->pens;
1008 while( p2 != p )
1010 if( ( donation = data->donation ) )
1014 if( *donation == *p2 )
1016 *p2 = -1;
1017 break;
1020 while( *donation++ != -1 );
1023 ReleasePen( cm, *p2++ );
1026 return FALSE;
1030 else *p++ = -1;
1035 return data->gotpens = TRUE;
1038 /***************************************************************************************************/
1040 void allocPens( struct ColorWheelData *data )
1042 LONG depth = GetBitMapAttr( data->scr->RastPort.BitMap, BMA_DEPTH );
1044 if( ! ( CyberGfxBase && depth >= 15 ) )
1046 LONG donated = 0L, levels;
1048 if( data->donation )
1049 for( donated = 0L; data->donation[donated] != 0xffff; donated++ );
1051 for( levels = 6; levels >= 2; levels-- )
1053 LONG i;
1055 i = levels-1;
1056 i = levels*levels*levels-i*i*i;
1058 if( ( i > (donated+data->maxpens) ) || ( i > (1L<<depth) ) )
1059 continue;
1061 data->range = 255 / (levels-1);
1062 data->levels = levels;
1064 if( getPens( data ) ) break;
1070 /****************************************************************************/
1072 void freePens( struct ColorWheelData *data )
1074 if( data->gotpens )
1076 struct ColorMap *cm = data->scr->ViewPort.ColorMap;
1077 LONG i = data->levels;
1079 for( i = (i*i*i)-1; i; i-- )
1081 if( data->pens[i] != -1 )
1083 WORD *donation;
1085 if( ( donation = data->donation ) )
1089 if( data->pens[i] == *donation )
1091 data->pens[i] = -1;
1092 break;
1095 while( *donation++ != -1 );
1098 ReleasePen( cm, data->pens[i] );
1105 /****************************************************************************/