Don't call InvertPixelArray with negative width and/or height.
[tangerine.git] / workbench / libs / muimaster / frame.c
blob47b1a2fb78867971b290acf95db1b0a37401d585
1 /*
2 Copyright © 1999, David Le Corfec.
3 Copyright © 2002, The AROS Development Team.
4 All rights reserved.
6 $Id$
7 */
9 #include <exec/types.h>
11 #include <proto/graphics.h>
12 #include <stdio.h>
14 #include "muimaster_intern.h"
15 #include "mui.h"
16 #include "frame.h"
18 extern struct Library *MUIMasterBase;
20 /**************************************************************************
21 no frame
22 **************************************************************************/
23 static void frame_none_draw (struct MUI_RenderInfo *mri,
24 int left, int top, int width, int height)
28 /**************************************************************************
29 1 : FST_RECT
30 **************************************************************************/
31 static void rect_draw(struct MUI_RenderInfo *mri,
32 int left, int top, int width, int height,
33 MPen preset_color)
35 struct RastPort *rp = mri->mri_RastPort;
37 SetAPen(rp, mri->mri_Pens[preset_color]);
39 /* FIXME: usually RectFill() is faster */
40 Move(rp, left, top);
41 Draw(rp, left + width - 1, top);
42 Draw(rp, left + width - 1, top + height - 1);
43 Draw(rp, left, top + height - 1);
44 Draw(rp, left, top);
48 /**************************************************************************
49 simple white border
50 **************************************************************************/
51 static void frame_white_rect_draw (struct MUI_RenderInfo *mri,
52 int left, int top, int width, int height)
54 rect_draw(mri, left, top, width, height, MPEN_SHINE);
57 /**************************************************************************
58 simple black border
59 **************************************************************************/
60 static void frame_black_rect_draw (struct MUI_RenderInfo *mri,
61 int left, int top, int width, int height)
63 rect_draw(mri, left, top, width, height, MPEN_SHADOW);
66 /**************************************************************************
67 2 : FST_BEVEL
69 Draw a bicolor rectangle
70 **************************************************************************/
71 static void button_draw (struct MUI_RenderInfo *mri,
72 int left, int top, int width, int height,
73 MPen ul_preset, MPen lr_preset)
75 struct RastPort *rp = mri->mri_RastPort;
77 SetAPen(rp, mri->mri_Pens[ul_preset]);
78 Move(rp, left, top + height - 2);
79 Draw(rp, left, top);
80 Draw(rp, left + width - 2, top);
82 SetAPen(rp, mri->mri_Pens[lr_preset]);
83 Move(rp, left + width - 1, top);
84 Draw(rp, left + width - 1, top + height - 1);
85 Draw(rp, left, top + height - 1);
87 SetAPen(rp, mri->mri_Pens[MPEN_BACKGROUND]);
88 WritePixel(rp, left, top + height - 1);
89 WritePixel(rp, left + width - 1, top);
92 /**************************************************************************
93 classic button
94 **************************************************************************/
95 static void frame_bevelled_draw (struct MUI_RenderInfo *mri,
96 int left, int top, int width, int height)
98 button_draw(mri, left, top, width, height, MPEN_SHINE, MPEN_SHADOW);
101 /**************************************************************************
102 classic pressed button
103 **************************************************************************/
104 static void frame_recessed_draw (struct MUI_RenderInfo *mri,
105 int left, int top, int width, int height)
107 button_draw(mri, left, top, width, height, MPEN_SHADOW, MPEN_SHINE);
110 /**************************************************************************
111 3 : FST_THIN_BORDER
112 Draw a thin relief border
113 **************************************************************************/
114 static void thinborder_draw (struct MUI_RenderInfo *mri,
115 int left, int top, int width, int height,
116 MPen ul_preset, MPen lr_preset)
118 struct RastPort *rp = mri->mri_RastPort;
120 SetAPen(rp, mri->mri_Pens[ul_preset]);
121 Move(rp, left, top + height - 1);
122 Draw(rp, left, top);
123 Draw(rp, left + width - 1, top);
125 Move(rp, left + width - 2, top + 2);
126 Draw(rp, left + width - 2, top + height - 2);
127 Draw(rp, left + 2, top + height - 2);
129 rect_draw(mri, left+1, top+1, width-1, height-1, lr_preset);
132 /**************************************************************************
133 draw border up
134 **************************************************************************/
135 static void frame_thin_border_up_draw (struct MUI_RenderInfo *mri,
136 int left, int top, int width, int height)
138 thinborder_draw(mri, left, top, width, height, MPEN_SHINE, MPEN_SHADOW);
141 /**************************************************************************
142 draw border down
143 **************************************************************************/
144 static void frame_thin_border_down_draw (struct MUI_RenderInfo *mri,
145 int left, int top, int width, int height)
147 thinborder_draw(mri, left, top, width, height, MPEN_SHADOW, MPEN_SHINE);
150 /**************************************************************************
151 4 : FST_THICK_BORDER
152 Draw a thick relief border
153 **************************************************************************/
154 static void thickborder_draw (struct MUI_RenderInfo *mri,
155 int left, int top, int width, int height,
156 BOOL bevelled)
159 if (bevelled)
161 button_draw(mri, left, top, width, height, MPEN_SHINE, MPEN_SHADOW);
162 button_draw(mri, left+2, top+2, width-4, height-4, MPEN_SHADOW, MPEN_SHINE);
164 else
166 button_draw(mri, left, top, width, height, MPEN_SHADOW, MPEN_SHINE);
167 button_draw(mri, left+2, top+2, width-4, height-4, MPEN_SHINE, MPEN_SHADOW);
170 rect_draw(mri, left+1, top+1, width-2, height-2, MPEN_BACKGROUND);
173 /**************************************************************************
174 draw thick border up
175 **************************************************************************/
176 static void frame_thick_border_up_draw (struct MUI_RenderInfo *mri,
177 int left, int top, int width, int height)
179 thickborder_draw(mri, left, top, width, height, TRUE);
182 /**************************************************************************
183 draw thick border down
184 **************************************************************************/
185 static void frame_thick_border_down_draw (struct MUI_RenderInfo *mri,
186 int left, int top, int width, int height)
188 thickborder_draw(mri, left, top, width, height, FALSE);
191 /**************************************************************************
192 5 : FST_ROUND_BEVEL
193 **************************************************************************/
194 static void round_bevel_draw (struct MUI_RenderInfo *mri,
195 int left, int top, int width, int height,
196 MPen ul, MPen lr)
198 SetAPen(mri->mri_RastPort, mri->mri_Pens[MPEN_BACKGROUND]);
199 RectFill(mri->mri_RastPort,
200 left, top, left + 3, top + height - 1);
201 RectFill(mri->mri_RastPort,
202 left + width - 4, top, left + width - 1, top + height - 1);
203 rect_draw(mri, left, top+2, 2, height-4, ul);
204 rect_draw(mri, left+1, top+1, 2, 1, ul);
205 rect_draw(mri, left+1, top + height - 2, 2, 1, ul);
206 rect_draw(mri, left+2, top + height - 1, 1, 1, ul);
207 rect_draw(mri, left+2, top, width - 5, 1, ul);
209 rect_draw(mri, left + width - 2, top+2, 2, height-4, lr);
210 rect_draw(mri, left + width - 3, top+1, 2, 1, lr);
211 rect_draw(mri, left + width - 3, top + height - 2, 2, 1, lr);
212 rect_draw(mri, left+3, top + height - 1, width - 5, 1, lr);
213 rect_draw(mri, left + width - 3, top, 1, 1, lr);
216 /**************************************************************************
218 **************************************************************************/
219 static void frame_round_bevel_up_draw (struct MUI_RenderInfo *mri,
220 int left, int top, int width, int height)
222 round_bevel_draw (mri, left, top, width, height,
223 MPEN_SHINE, MPEN_SHADOW);
226 /**************************************************************************
228 **************************************************************************/
229 static void frame_round_bevel_down_draw (struct MUI_RenderInfo *mri,
230 int left, int top, int width, int height)
232 round_bevel_draw (mri, left, top, width, height,
233 MPEN_SHADOW, MPEN_SHINE);
236 /**************************************************************************
237 6 : FST_WIN_BEVEL
238 **************************************************************************/
239 static void frame_border_button_up_draw (struct MUI_RenderInfo *mri,
240 int left, int top, int width, int height)
242 rect_draw(mri, left, top, width, height, MPEN_SHADOW);
243 button_draw(mri, left+1, top+1, width-2, height-2,
244 MPEN_SHINE, MPEN_HALFSHADOW);
247 /**************************************************************************
249 **************************************************************************/
250 static void frame_border_button_down_draw (struct MUI_RenderInfo *mri,
251 int left, int top, int width, int height)
253 button_draw(mri, left+2, top+2, width-2, height-2,
254 MPEN_BACKGROUND, MPEN_SHADOW);
255 button_draw(mri, left+1, top+1, width-1, height-1,
256 MPEN_HALFSHADOW, MPEN_SHADOW);
257 rect_draw(mri, left, top, width, height, MPEN_SHADOW);
260 /**************************************************************************
261 7 : FST_ROUND_THICK_BORDER
262 **************************************************************************/
263 static void round_thick_border_draw (struct MUI_RenderInfo *mri,
264 int left, int top, int width, int height,
265 MPen pen1, MPen pen2, MPen pen3, MPen pen4, MPen pen5)
267 struct RastPort *rp = mri->mri_RastPort;
269 rect_draw(mri, left, top, width - 2, height - 2, pen1);
270 rect_draw(mri, left + 2, top + 2, width - 2, height - 2, pen5);
272 rect_draw(mri, left, top, 2, 2, pen2);
273 rect_draw(mri, left, top + height - 3, 2, 2, pen2);
274 rect_draw(mri, left + width - 3, top, 2, 2, pen2);
276 rect_draw(mri, left + width - 2, top + height - 2, 2, 2, pen4);
277 rect_draw(mri, left + 1, top + height - 2, 2, 2, pen4);
278 rect_draw(mri, left + width - 2, top + 1, 2, 2, pen4);
280 rect_draw(mri, left + 1, top + 1, width - 2, height - 2, pen3);
282 rect_draw(mri, left + 2, top + 2, 2, 2, pen3);
283 rect_draw(mri, left + 2, top + height - 4, 2, 2, pen3);
284 rect_draw(mri, left + width - 4, top + height - 4, 2, 2, pen3);
285 rect_draw(mri, left + width - 4, top + 2, 2, 2, pen3);
287 /* these points were not in the original frame. -dlc */
288 SetAPen(rp, mri->mri_Pens[pen5]);
289 WritePixel(rp, left + 3, top + 3);
291 SetAPen(rp, mri->mri_Pens[pen1]);
292 WritePixel(rp, left + width - 4, top + height - 4);
295 /**************************************************************************
297 **************************************************************************/
298 static void frame_round_thick_border_up_draw (struct MUI_RenderInfo *mri,
299 int left, int top, int width, int height)
301 round_thick_border_draw(mri, left, top, width, height,
302 MPEN_SHINE, MPEN_HALFSHINE, MPEN_BACKGROUND,
303 MPEN_HALFSHADOW, MPEN_SHADOW);
306 /**************************************************************************
308 **************************************************************************/
309 static void frame_round_thick_border_down_draw (struct MUI_RenderInfo *mri,
310 int left, int top, int width, int height)
312 round_thick_border_draw(mri, left, top, width, height,
313 MPEN_SHADOW, MPEN_HALFSHADOW, MPEN_BACKGROUND,
314 MPEN_HALFSHINE, MPEN_SHINE);
317 /**************************************************************************
318 8 : FST_ROUND_THIN_BORDER
319 **************************************************************************/
320 static void round_thin_border_draw (struct MUI_RenderInfo *mri,
321 int left, int top, int width, int height,
322 MPen pen1, MPen pen2, MPen pen3, MPen pen4, MPen pen5)
324 struct RastPort *rp = mri->mri_RastPort;
326 rect_draw(mri, left, top, width - 1, height - 1, pen1);
327 rect_draw(mri, left + 1, top + 1, width - 1, height - 1, pen5);
329 rect_draw(mri, left, top, 2, 2, pen2);
330 rect_draw(mri, left + width - 4, top + height - 4, 2, 2, pen2);
331 rect_draw(mri, left + 2, top + 2, 2, 2, pen4);
332 rect_draw(mri, left + width - 2, top + height - 2, 2, 2, pen4);
333 rect_draw(mri, left + 1, top + 1, 2, 2, pen3);
334 rect_draw(mri, left + width - 3, top + height - 3, 2, 2, pen3);
336 rect_draw(mri, left + 1, top + height - 3, 1, 3, pen4);
337 rect_draw(mri, left + width - 3, top + 1, 3, 1, pen4);
339 WritePixel(rp, left + 2, top + height - 3);
340 WritePixel(rp, left + width - 3, top + 2);
342 SetAPen(rp, mri->mri_Pens[pen2]);
343 WritePixel(rp, left, top + height - 2);
344 WritePixel(rp, left + 2, top + height - 2);
345 WritePixel(rp, left + width - 2, top);
346 WritePixel(rp, left + width - 2, top + 2);
349 /**************************************************************************
351 **************************************************************************/
352 static void frame_round_thin_border_up_draw (struct MUI_RenderInfo *mri,
353 int left, int top, int width, int height)
355 round_thin_border_draw(mri, left, top, width, height,
356 MPEN_SHINE, MPEN_HALFSHINE, MPEN_BACKGROUND,
357 MPEN_HALFSHADOW, MPEN_SHADOW);
360 /**************************************************************************
362 **************************************************************************/
363 static void frame_round_thin_border_down_draw (struct MUI_RenderInfo *mri,
364 int left, int top, int width, int height)
366 round_thin_border_draw(mri, left, top, width, height,
367 MPEN_SHADOW, MPEN_HALFSHADOW, MPEN_BACKGROUND,
368 MPEN_HALFSHINE, MPEN_SHINE);
371 /**************************************************************************
372 9 : FST_GRAY_BORDER
373 **************************************************************************/
374 static void frame_gray_border_up_draw (struct MUI_RenderInfo *mri,
375 int left, int top, int width, int height)
377 thinborder_draw(mri, left, top, width, height,
378 MPEN_HALFSHINE, MPEN_HALFSHADOW);
381 /**************************************************************************
383 **************************************************************************/
384 static void frame_gray_border_down_draw (struct MUI_RenderInfo *mri,
385 int left, int top, int width, int height)
387 thinborder_draw(mri, left, top, width, height,
388 MPEN_HALFSHADOW, MPEN_HALFSHINE);
391 /**************************************************************************
392 A : FST_SEMIROUND_BEVEL
393 **************************************************************************/
394 static void semiround_bevel_draw (struct MUI_RenderInfo *mri,
395 int left, int top, int width, int height,
396 MPen pen1, MPen pen2, MPen pen3, MPen pen4, MPen pen5)
398 struct RastPort *rp = mri->mri_RastPort;
400 button_draw(mri, left, top, width, height, pen1, pen5);
401 button_draw(mri, left+1, top+1, width-2, height-2, pen2, pen4);
403 SetAPen(rp, mri->mri_Pens[pen2]);
404 WritePixel(rp, left, top);
406 SetAPen(rp, mri->mri_Pens[pen1]);
407 WritePixel(rp, left + 1, top + 1);
409 SetAPen(mri->mri_RastPort, mri->mri_Pens[pen5]);
410 WritePixel(rp, left + width - 2, top + height - 2);
412 SetAPen(mri->mri_RastPort, mri->mri_Pens[pen4]);
413 WritePixel(rp, left + width - 1, top + height - 1);
415 SetAPen(mri->mri_RastPort, mri->mri_Pens[pen3]);
416 WritePixel(rp, left, top + height - 2);
417 WritePixel(rp, left + 1, top + height - 1);
418 WritePixel(rp, left + width - 2, top);
419 WritePixel(rp, left + width - 1, top + 1);
422 /**************************************************************************
424 **************************************************************************/
425 static void frame_semiround_bevel_up_draw (struct MUI_RenderInfo *mri,
426 int left, int top, int width, int height)
428 semiround_bevel_draw (mri, left, top, width, height,
429 MPEN_SHINE, MPEN_HALFSHINE, MPEN_BACKGROUND,
430 MPEN_HALFSHADOW, MPEN_SHADOW);
433 /**************************************************************************
435 **************************************************************************/
436 static void frame_semiround_bevel_down_draw (struct MUI_RenderInfo *mri,
437 int left, int top, int width, int height)
439 semiround_bevel_draw (mri, left, top, width, height,
440 MPEN_SHADOW, MPEN_HALFSHADOW, MPEN_BACKGROUND,
441 MPEN_HALFSHINE, MPEN_SHINE);
444 /**************************************************************************
445 hold builtin frames.
446 **************************************************************************/
447 static const struct ZuneFrameGfx __builtinFrameGfx[] = {
448 /* type 0 : FST_NONE */
449 {frame_none_draw, 0, 0, 0, 0},
450 {frame_none_draw, 0, 0, 0, 0},
452 /* monochrome border */
453 /* 1 : FST_RECT */
454 {frame_white_rect_draw, 1, 1, 1, 1},
455 {frame_black_rect_draw, 1, 1, 1, 1},
457 /* clean 3D look */
458 /* 2 : FST_BEVEL */
459 {frame_bevelled_draw, 1, 1, 1, 1},
460 {frame_recessed_draw, 1, 1, 1, 1},
462 /* thin relief border */
463 /* 3 : FST_THIN_BORDER */
464 {frame_thin_border_up_draw, 2, 2, 2, 2},
465 {frame_thin_border_down_draw, 2, 2, 2, 2},
467 /* thick relief border */
468 /* 4 : FST_THICK_BORDER */
469 {frame_thick_border_up_draw, 3, 3, 3, 3},
470 {frame_thick_border_down_draw, 3, 3, 3, 3},
472 /* rounded bevel */
473 /* 5 : FST_ROUND_BEVEL */
474 {frame_round_bevel_up_draw, 4, 4, 1, 1},
475 {frame_round_bevel_down_draw, 4, 4, 1, 1},
477 /* zin31/xen look */
478 /* 6 : FST_WIN_BEVEL */
479 {frame_border_button_up_draw, 2, 2, 2, 2},
480 {frame_border_button_down_draw, 3, 1, 3, 1},
482 /* rounded thick border */
483 /* 7 : FST_ROUND_THICK_BORDER */
484 {frame_round_thick_border_up_draw, 4, 4, 4, 4},
485 {frame_round_thick_border_down_draw, 4, 4, 4, 4},
487 /* rounded thin border */
488 /* 8 : FST_ROUND_THIN_BORDER */
489 {frame_round_thin_border_up_draw, 4, 4, 4, 4},
490 {frame_round_thin_border_down_draw, 4, 4, 4, 4},
492 /* strange gray border */
493 /* 9 : FST_GRAY_BORDER */
494 {frame_gray_border_up_draw, 2, 2, 2, 2},
495 {frame_gray_border_down_draw, 2, 2, 2, 2},
497 /* semi rounded bevel */
498 /* A : FST_SEMIROUND_BEVEL */
499 {frame_semiround_bevel_up_draw, 2, 2, 2, 2},
500 {frame_semiround_bevel_down_draw, 2, 2, 2, 2},
504 /**************************************************************************
506 **************************************************************************/
507 const struct ZuneFrameGfx *zune_zframe_get (const struct MUI_FrameSpec_intern *frameSpec)
509 if (frameSpec->type >= FST_COUNT) return &__builtinFrameGfx[2 * FST_RECT];
510 return &__builtinFrameGfx[2 * frameSpec->type + frameSpec->state];
513 const struct ZuneFrameGfx *zune_zframe_get_with_state (const struct MUI_FrameSpec_intern *frameSpec,
514 UWORD state)
516 if (frameSpec->type >= FST_COUNT) return &__builtinFrameGfx[2 * FST_RECT];
517 return &__builtinFrameGfx[2 * frameSpec->type + state];
520 /*------------------------------------------------------------------------*/
522 BOOL zune_frame_intern_to_spec (const struct MUI_FrameSpec_intern *intern,
523 STRPTR spec)
525 if (!intern || !spec)
526 return FALSE;
528 /* Must cast to LONG because on AmigaOS SNPrintf() is used which is like
529 * RawDoFmt() 16 bit */
530 snprintf(&spec[0], 2, "%lx", (LONG)intern->type);
531 snprintf(&spec[1], 2, "%lx", (LONG)intern->state);
532 snprintf(&spec[2], 2, "%lx", (LONG)intern->innerLeft);
533 snprintf(&spec[3], 2, "%lx", (LONG)intern->innerRight);
534 snprintf(&spec[4], 2, "%lx", (LONG)intern->innerTop);
535 snprintf(&spec[5], 2, "%lx", (LONG)intern->innerBottom);
536 /* 0 byte is ensured through snprintf */
537 return TRUE;
540 /*------------------------------------------------------------------------*/
542 static int hexasciichar_to_int(char x)
544 if (x >= '0' && x <= '9') return x - '0';
545 if (x >= 'a' && x <= 'f') return x - 'a';
546 if (x >= 'A' && x <= 'F') return x - 'A';
547 return -1;
550 BOOL zune_frame_spec_to_intern(CONST_STRPTR spec,
551 struct MUI_FrameSpec_intern *intern)
553 int val;
555 if (!intern || !spec)
556 return FALSE;
558 val = hexasciichar_to_int(spec[0]);
559 if (val == -1) return FALSE;
560 intern->type = val;
562 val = hexasciichar_to_int(spec[1]);
563 if (val == -1) return FALSE;
564 intern->state = val;
566 val = hexasciichar_to_int(spec[2]);
567 if (val == -1) return FALSE;
568 intern->innerLeft = val;
570 val = hexasciichar_to_int(spec[3]);
571 if (val == -1) return FALSE;
572 intern->innerRight = val;
574 val = hexasciichar_to_int(spec[4]);
575 if (val == -1) return FALSE;
576 intern->innerTop = val;
578 val = hexasciichar_to_int(spec[5]);
579 if (val == -1) return FALSE;
580 intern->innerBottom = val;
581 return TRUE;