2 Copyright © 1995-2005, The AROS Development Team. All rights reserved.
5 Desc: Support functions for the gradientslider class
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 /***************************************************************************************************/
29 #include <aros/debug.h>
32 /***************************************************************************************************/
34 #define MATRIX_HALFTONE 0
35 #define MATRIX_BAYER4 1
36 #define MATRIX_BAYER16 0
37 #define MATRIX_RECTANGULAR 0
41 #define MATRIX_WIDTH Bayer4_Width
42 #define MATRIX_HEIGHT Bayer4_Height
43 #define MATRIX_MAXVAL Bayer4_MaxVal
45 /***************************************************************************************************/
49 #define Halftone_Width 6
50 #define Halftone_Height 6
51 #define Halftone_MaxVal 36
53 const UBYTE Halftone
[6][6] =
65 /***************************************************************************************************/
69 #define Bayer4_Width 4
70 #define Bayer4_Height 4
71 #define Bayer4_MaxVal 16
73 const UBYTE Bayer4
[4][4] =
83 /***************************************************************************************************/
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}
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] =
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;
144 RectFill(rp
, x1
, y1
, x2
, y1
);
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
++)
165 t
= MATRIX
[y
% MATRIX_HEIGHT
][x
% MATRIX_WIDTH
];
167 /* if brightness is smaller than threshold use pen1, otherwise pen2 */
174 if (pixel
!= lastpixel
)
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;
199 RectFill(rp
, x1
, y1
, x1
, y2
);
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
++)
220 t
= MATRIX
[y
% MATRIX_HEIGHT
][x
% MATRIX_WIDTH
];
222 /* if brightness is smaller than threshold use pen1, otherwise pen2 */
229 if (pixel
!= lastpixel
)
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
);
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
,
269 LONG width
= x2
- x1
+ 1;
270 LONG height
= y2
- y1
+ 1;
272 ULONG pen1_rgb
[3], pen2_rgb
[3];
273 LONG delta_r
, delta_g
, delta_b
;
278 RectFill(rp
, x1
, y1
, x2
, y1
);
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
,
308 LONG width
= x2
- x1
+ 1;
309 LONG height
= y2
- y1
+ 1;
311 ULONG pen1_rgb
[3], pen2_rgb
[3];
312 LONG delta_r
, delta_g
, delta_b
;
317 RectFill(rp
, x1
, y1
, x1
, y2
);
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
;
348 WORD x
, y
, width
, height
, oldx
, oldy
, endx
, endy
;
350 BOOL truecolor
= FALSE
;
352 if (CyberGfxBase
&& (GetBitMapAttr(rp
->BitMap
, BMA_DEPTH
) >= 15))
361 height
= y2
- y1
+ 1;
362 step
= height
* 65536 / (numpens
- 1);
364 for(i
= 0; i
< numpens
- 1; i
++)
368 y
= y1
+ (pos
/ 65536);
369 endy
= y
; if (endy
!= y2
) endy
--;
374 TrueDitherV(rp
, x1
, oldy
, x2
, endy
, pen1
, pen2
, cm
);
376 DitherV(rp
, x1
, oldy
, x2
, endy
, pen1
, pen2
);
386 step
= width
* 65536 / (numpens
- 1);
388 for(i
= 0; i
< numpens
- 1;i
++)
392 x
= x1
+ (pos
/ 65536);
393 endx
= x
; if (endx
!= x2
) endx
--;
398 TrueDitherH(rp
, oldx
, y1
, endx
, y2
, pen1
, pen2
, cm
);
400 DitherH(rp
, oldx
, y1
, endx
, y2
, pen1
, pen2
);
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
;
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
;
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 */
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);
491 struct TagItem tags
[] =
493 {RPTAG_APen
, dri
->dri_Pens
[SHINEPEN
] },
494 {RPTAG_OutlinePen
, dri
->dri_Pens
[SHADOWPEN
] },
495 {RPTAG_DrMd
, JAM1
},
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
;
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
,
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 /***************************************************************************************************/