revert between 56095 -> 55830 in arch
[AROS.git] / workbench / classes / gadgets / gradientslider / support.c
blob594e7ac9ed6ba0f75454e92521d66adbb2a8046b
1 /*
2 Copyright © 1995-2005, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Support functions for the gradientslider class
6 Lang: English
7 */
9 #include <graphics/gfxmacros.h>
10 #include <intuition/classes.h>
11 #include <intuition/cghooks.h>
12 #include <intuition/gadgetclass.h>
13 #include <intuition/imageclass.h>
14 #include <intuition/screens.h>
15 #include <intuition/intuition.h>
16 #include <cybergraphx/cybergraphics.h>
17 #include <proto/exec.h>
18 #include <proto/graphics.h>
19 #include <proto/intuition.h>
20 #include <proto/cybergraphics.h>
22 #include "gradientslider_intern.h"
24 /***************************************************************************************************/
26 #define SDEBUG 0
27 #define DEBUG 0
28 #ifdef __AROS__
29 #include <aros/debug.h>
30 #endif
32 /***************************************************************************************************/
34 #define MATRIX_HALFTONE 0
35 #define MATRIX_BAYER4 1
36 #define MATRIX_BAYER16 0
37 #define MATRIX_RECTANGULAR 0
40 #define MATRIX Bayer4
41 #define MATRIX_WIDTH Bayer4_Width
42 #define MATRIX_HEIGHT Bayer4_Height
43 #define MATRIX_MAXVAL Bayer4_MaxVal
45 /***************************************************************************************************/
47 #if MATRIX_HALFTONE
49 #define Halftone_Width 6
50 #define Halftone_Height 6
51 #define Halftone_MaxVal 36
53 const UBYTE Halftone[6][6] =
55 {15, 9,17,32,22,30},
56 { 7, 1, 3,19,35,23},
57 {13, 5,11,27,26,33},
58 {31,21,29,16,10,18},
59 {20,36,24, 8, 2, 4},
60 {28,25,34,14, 6,12}
63 #endif
65 /***************************************************************************************************/
67 #if MATRIX_BAYER4
69 #define Bayer4_Width 4
70 #define Bayer4_Height 4
71 #define Bayer4_MaxVal 16
73 const UBYTE Bayer4[4][4] =
75 { 1, 9, 3,11},
76 {13, 5,15, 7},
77 { 4,12, 2,10},
78 {16, 8,14, 6}
81 #endif
83 /***************************************************************************************************/
85 #if MATRIX_BAYER16
87 #define Bayer16_Width 16
88 #define Bayer16_Height 16
89 #define Bayer16_MaxVal 254
91 const UBYTE Bayer16[16][16] =
93 { 1,235, 59,219, 15,231, 55,215, 2,232, 56,216, 12,228, 52,212},
94 {129, 65,187,123,143, 79,183,119,130, 66,184,120,140, 76,180,116},
95 { 33,193, 17,251, 47,207, 31,247, 34,194, 18,248, 44,204, 28,244},
96 {161, 97,145, 81,175,111,159, 95,162, 98,146, 82,172,108,156, 92},
97 { 9,225, 49,209, 5,239, 63,223, 10,226, 50,210, 6,236, 60,220},
98 {137, 73,177,113,133, 69,191,127,138, 74,178,114,134, 70,188,124},
99 { 41,201, 25,241, 37,197, 21,254, 42,202, 26,242, 38,198, 22,252},
100 {169,105,153, 89,165,101,149, 85,170,106,154, 90,166,102,150, 86},
101 { 3,233, 57,217, 13,229, 53,213, 0,234, 58,218, 14,230, 54,214},
102 {131, 67,185,121,141, 77,181,117,128, 64,186,122,142, 78,182,118},
103 { 35,195, 19,249, 45,205, 29,245, 32,192, 16,250, 46,206, 30,246},
104 {163, 99,147, 83,173,109,157, 93,160, 96,144, 80,174,110,158, 94},
105 { 11,227, 51,211, 7,237, 61,221, 8,224, 48,208, 4,238, 62,222},
106 {139, 75,179,115,135, 71,189,125,136, 72,176,112,132, 68,190,126},
107 { 43,203, 27,243, 39,199, 23,253, 40,200, 24,240, 36,196, 20,254},
108 {171,107,155, 91,167,103,151, 87,168,104,152, 88,164,100,148, 84}
111 #endif
113 /***************************************************************************************************/
115 #if MATRIX_RECTANGULAR
117 #define Rectangular_Width 3
118 #define Rectangular_Height 3
119 #define Rectangular_MaxVal 4
121 const UBYTE Rectangular[3][3] =
123 {2, 3, 2},
124 {4, 1, 4},
125 {2, 3, 2}
128 #endif
130 /***************************************************************************************************/
132 STATIC VOID DitherV(struct RastPort *rp,
133 WORD x1, WORD y1, WORD x2, WORD y2, WORD pen1, WORD pen2
136 LONG width = x2 - x1 + 1;
137 LONG height = y2 - y1 + 1;
139 LONG x, y, t, v, pixel, lastpixel = -1;
141 if (height <= 2)
143 SetAPen(rp, pen1);
144 RectFill(rp, x1, y1, x2, y1);
147 if (height == 2)
149 SetAPen(rp, pen2);
150 RectFill(rp, x1, y1 + 1, x2, y2);
153 if (height <= 2) return;
155 for(y = 0 ; y < height ; y++)
157 /* v = brightness. Make it go from 0 at y = 0 to MATRIX_MAXVAL at y = height - 1 */
159 v = (y * MATRIX_MAXVAL + (height - 1) / 2) / (height - 1);
161 for(x = 0 ; x < width ; x++)
163 /* t = threshold */
165 t = MATRIX[y % MATRIX_HEIGHT][x % MATRIX_WIDTH];
167 /* if brightness is smaller than threshold use pen1, otherwise pen2 */
169 if(v < t)
170 pixel = pen1;
171 else
172 pixel = pen2;
174 if (pixel != lastpixel)
176 SetAPen(rp, pixel);
177 lastpixel = pixel;
180 WritePixel(rp, x1 + x, y1 + y);
185 /***************************************************************************************************/
187 STATIC VOID DitherH(struct RastPort *rp,
188 WORD x1, WORD y1, WORD x2, WORD y2, WORD pen1, WORD pen2
191 LONG width = x2 - x1 + 1;
192 LONG height = y2 - y1 + 1;
194 LONG x, y, t, v, pixel, lastpixel = -1;
196 if (width <= 2)
198 SetAPen(rp, pen1);
199 RectFill(rp, x1, y1, x1, y2);
202 if (width == 2)
204 SetAPen(rp, pen2);
205 RectFill(rp, x1 + 1, y1, x2, y2);
208 if (width <= 2) return;
210 for(x = 0 ; x < width ; x++)
212 /* v = brightness. Make it go from 0 at x = 0 to MATRIX_MAXVAL at x = width - 1 */
214 v = (x * MATRIX_MAXVAL + (width - 1) / 2) / (width - 1);
216 for(y = 0 ; y < height ; y++)
218 /* t = threshold */
220 t = MATRIX[y % MATRIX_HEIGHT][x % MATRIX_WIDTH];
222 /* if brightness is smaller than threshold use pen1, otherwise pen2 */
224 if(v < t)
225 pixel = pen1;
226 else
227 pixel = pen2;
229 if (pixel != lastpixel)
231 SetAPen(rp, pixel);
232 lastpixel = pixel;
235 WritePixel(rp, x1 + x, y1 + y);
240 /***************************************************************************************************/
242 STATIC VOID CalcRGB(struct ColorMap *cm, WORD pen1, WORD pen2, ULONG *pen1_rgb, ULONG *pen2_rgb,
243 LONG *delta_r, LONG *delta_g, LONG *delta_b
246 GetRGB32(cm, pen1, 1, (ULONG *)pen1_rgb);
247 GetRGB32(cm, pen2, 1, (ULONG *)pen2_rgb);
249 pen1_rgb[0] >>= 24;
250 pen1_rgb[1] >>= 24;
251 pen1_rgb[2] >>= 24;
253 pen2_rgb[0] >>= 24;
254 pen2_rgb[1] >>= 24;
255 pen2_rgb[2] >>= 24;
257 *delta_r = (LONG)(pen2_rgb[0] - pen1_rgb[0]);
258 *delta_g = (LONG)(pen2_rgb[1] - pen1_rgb[1]);
259 *delta_b = (LONG)(pen2_rgb[2] - pen1_rgb[2]);
262 /***************************************************************************************************/
264 STATIC VOID TrueDitherV(struct RastPort *rp,
265 WORD x1, WORD y1, WORD x2, WORD y2, WORD pen1, WORD pen2,
266 struct ColorMap *cm
269 LONG width = x2 - x1 + 1;
270 LONG height = y2 - y1 + 1;
271 LONG y;
272 ULONG pen1_rgb[3], pen2_rgb[3];
273 LONG delta_r, delta_g, delta_b;
275 if (height <= 2)
277 SetAPen(rp, pen1);
278 RectFill(rp, x1, y1, x2, y1);
281 if (height == 2)
283 SetAPen(rp, pen2);
284 RectFill(rp, x1, y1 + 1, x2, y2);
287 if (height <= 2) return;
289 CalcRGB(cm, pen1, pen2, pen1_rgb, pen2_rgb, &delta_r, &delta_g, &delta_b);
291 for(y = 0; y < height; y++)
293 LONG red = pen1_rgb[0] + (delta_r * y + (height - 1) / 2) / (height - 1);
294 LONG green = pen1_rgb[1] + (delta_g * y + (height - 1) / 2) / (height - 1);
295 LONG blue = pen1_rgb[2] + (delta_b * y + (height - 1) / 2) / (height - 1);
297 FillPixelArray(rp, x1, y1 + y, width, 1, (red << 16) + (green << 8) + blue);
301 /***************************************************************************************************/
303 STATIC VOID TrueDitherH(struct RastPort *rp,
304 WORD x1, WORD y1, WORD x2, WORD y2, WORD pen1, WORD pen2,
305 struct ColorMap *cm
308 LONG width = x2 - x1 + 1;
309 LONG height = y2 - y1 + 1;
310 LONG x;
311 ULONG pen1_rgb[3], pen2_rgb[3];
312 LONG delta_r, delta_g, delta_b;
314 if (width <= 2)
316 SetAPen(rp, pen1);
317 RectFill(rp, x1, y1, x1, y2);
320 if (width == 2)
322 SetAPen(rp, pen2);
323 RectFill(rp, x1 + 1, y1, x2, y2);
326 if (width <= 2) return;
328 CalcRGB(cm, pen1, pen2, pen1_rgb, pen2_rgb, &delta_r, &delta_g, &delta_b);
330 for(x = 0; x < width; x++)
332 LONG red = pen1_rgb[0] + (delta_r * x + (width - 1) / 2) / (width - 1);
333 LONG green = pen1_rgb[1] + (delta_g * x + (width - 1) / 2) / (width - 1);
334 LONG blue = pen1_rgb[2] + (delta_b * x + (width - 1) / 2) / (width - 1);
336 FillPixelArray(rp, x1 + x, y1, 1, height, (red << 16) + (green << 8) + blue);
340 /***************************************************************************************************/
342 VOID DrawGradient(struct RastPort *rp, WORD x1, WORD y1, WORD x2, WORD y2, UWORD *penarray,
343 WORD numpens, WORD orientation, struct ColorMap *cm
346 UWORD *pen = penarray;
347 ULONG step, pos = 0;
348 WORD x, y, width, height, oldx, oldy, endx, endy;
349 WORD pen1, pen2, i;
350 BOOL truecolor = FALSE;
352 if (CyberGfxBase && (GetBitMapAttr(rp->BitMap, BMA_DEPTH) >= 15))
354 truecolor = TRUE;
356 pen1 = *pen++;
358 switch(orientation)
360 case LORIENT_VERT:
361 height = y2 - y1 + 1;
362 step = height * 65536 / (numpens - 1);
363 oldy = y1;
364 for(i = 0; i < numpens - 1; i++)
366 pen2 = *pen++;
367 pos += step;
368 y = y1 + (pos / 65536);
369 endy = y; if (endy != y2) endy--;
370 if (endy >= oldy)
372 if (truecolor)
374 TrueDitherV(rp, x1, oldy, x2, endy, pen1, pen2, cm);
375 } else {
376 DitherV(rp, x1, oldy, x2, endy, pen1, pen2);
378 pen1 = pen2;
379 oldy = y;
382 break;
384 case LORIENT_HORIZ:
385 width = x2 - x1 + 1;
386 step = width * 65536 / (numpens - 1);
387 oldx = x1;
388 for(i = 0; i < numpens - 1;i++)
390 pen2 = *pen++;
391 pos += step;
392 x = x1 + (pos / 65536);
393 endx = x; if (endx != x2) endx--;
394 if (endx >= oldx)
396 if (truecolor)
398 TrueDitherH(rp, oldx, y1, endx, y2, pen1, pen2, cm);
399 } else {
400 DitherH(rp, oldx, y1, endx, y2, pen1, pen2);
402 pen1 = pen2;
403 oldx = x;
406 break;
408 } /* switch(orientation) */
412 /***************************************************************************************************/
414 VOID GetGadgetIBox(Object *o, struct GadgetInfo *gi, struct IBox *ibox)
416 ibox->Left = EG(o)->LeftEdge;
417 ibox->Top = EG(o)->TopEdge;
418 ibox->Width = EG(o)->Width;
419 ibox->Height = EG(o)->Height;
421 if (gi)
423 if (EG(o)->Flags & GFLG_RELRIGHT)
424 ibox->Left += gi->gi_Domain.Width - 1;
426 if (EG(o)->Flags & GFLG_RELBOTTOM)
427 ibox->Top += gi->gi_Domain.Height - 1;
429 if (EG(o)->Flags & GFLG_RELWIDTH)
430 ibox->Width += gi->gi_Domain.Width;
432 if (EG(o)->Flags & GFLG_RELHEIGHT)
433 ibox->Height += gi->gi_Domain.Height;
438 /***************************************************************************************************/
440 VOID GetSliderBox(struct IBox *gadgetbox, struct IBox *sliderbox)
442 sliderbox->Left = gadgetbox->Left + FRAMESLIDERSPACINGX;
443 sliderbox->Top = gadgetbox->Top + FRAMESLIDERSPACINGY;
444 sliderbox->Width = gadgetbox->Width - FRAMESLIDERSPACINGX * 2;
445 sliderbox->Height = gadgetbox->Height - FRAMESLIDERSPACINGY * 2;
448 /***************************************************************************************************/
450 VOID GetKnobBox(struct GradientSliderData *data, struct IBox *sliderbox, struct IBox * knobbox)
452 if (data->freedom == LORIENT_HORIZ)
454 knobbox->Left = sliderbox->Left + (sliderbox->Width - data->knobpixels) * data->curval / data->maxval;
455 knobbox->Top = sliderbox->Top;
456 knobbox->Width = data->knobpixels;
457 knobbox->Height = sliderbox->Height;
458 } else {
459 knobbox->Left = sliderbox->Left;
460 knobbox->Top = sliderbox->Top + (sliderbox->Height - data->knobpixels) * data->curval / data->maxval;
461 knobbox->Width = sliderbox->Width;
462 knobbox->Height = data->knobpixels;
466 /***************************************************************************************************/
468 VOID DrawKnob(struct GradientSliderData *data, struct RastPort *rp, struct DrawInfo *dri,
469 struct IBox *box, WORD state
472 if ((box->Width > 2) && (box->Height > 2))
475 /* black frame around box */
476 #if 1
477 SetDrMd(rp, JAM1);
478 SetAPen(rp, dri->dri_Pens[SHADOWPEN]);
480 RectFill(rp, box->Left, box->Top, box->Left + box->Width - 1, box->Top);
481 RectFill(rp, box->Left + box->Width - 1, box->Top + 1, box->Left + box->Width - 1, box->Top + box->Height - 1);
482 RectFill(rp, box->Left, box->Top + box->Height - 1, box->Left + box->Width - 2, box->Top + box->Height - 1);
483 RectFill(rp, box->Left, box->Top + 1, box->Left, box->Top + box->Height - 2);
485 /* white box inside */
487 SetAPen(rp, dri->dri_Pens[SHINEPEN]);
489 RectFill(rp, box->Left + 1, box->Top + 1, box->Left + box->Width - 2, box->Top + box->Height - 2);
490 #else
491 struct TagItem tags[] =
493 {RPTAG_APen , dri->dri_Pens[SHINEPEN] },
494 {RPTAG_OutlinePen , dri->dri_Pens[SHADOWPEN] },
495 {RPTAG_DrMd , JAM1 },
496 {TAG_DONE }
499 SetRPAttrsA(rp, tags);
500 RectFill(rp, box->Left, box->Top, box->Left + box->Width - 1, box->Top + box->Height - 1);
501 rp->Flags &= ~AREAOUTLINE;
502 #endif
506 /***************************************************************************************************/
508 VOID DrawDisabledPattern(struct RastPort *rport, struct IBox *gadbox, UWORD pen)
510 UWORD pattern[] = { 0x8888, 0x2222 };
512 EnterFunc(bug("DrawDisabledPattern(rp=%p, gadbox=%p, pen=%d)\n",
513 rport, gadbox, pen));
515 SetDrMd( rport, JAM1 );
516 SetAPen( rport, pen );
517 SetAfPt( rport, pattern, 1);
519 /* render disable pattern */
520 RectFill( rport, gadbox->Left,
521 gadbox->Top,
522 gadbox->Left + gadbox->Width - 1,
523 gadbox->Top + gadbox->Height -1 );
525 SetAfPt ( rport, NULL, 0);
527 ReturnVoid("DrawDisabledPattern");
530 /***************************************************************************************************/
531 /***************************************************************************************************/
532 /***************************************************************************************************/
533 /***************************************************************************************************/
534 /***************************************************************************************************/
535 /***************************************************************************************************/
536 /***************************************************************************************************/
537 /***************************************************************************************************/
538 /***************************************************************************************************/
539 /***************************************************************************************************/