revert between 56095 -> 55830 in arch
[AROS.git] / workbench / c / Decoration / drawfuncs.c
blob1f70c35ea91f68a48d72883f2aa0caa15bc4e053
1 /*
2 Copyright © 2011-2017, The AROS Development Team.
3 $Id$
4 */
6 #define DEBUG 0
7 #include <aros/debug.h>
9 #include <intuition/imageclass.h>
10 #include <graphics/rpattr.h>
11 #include <libraries/cybergraphics.h>
12 #include <proto/arossupport.h>
13 #include <proto/graphics.h>
14 #include <proto/cybergraphics.h>
15 #include <proto/layers.h>
16 #include <proto/exec.h>
18 #include <hidd/gfx.h>
20 #include <math.h>
22 #include "drawfuncs.h"
24 #define DECOR_USELINEBUFF
25 //#define DECOR_FAKESHADE
26 //#define DECOR_NODIRECT
27 //#define DECOR_NOSHADE
29 #if AROS_BIG_ENDIAN
30 #define GET_ARGB_A(rgb) ((rgb >> 24) & 0xff)
31 #define GET_ARGB_R(rgb) ((rgb >> 16) & 0xff)
32 #define GET_ARGB_G(rgb) ((rgb >> 8) & 0xff)
33 #define GET_ARGB_B(rgb) (rgb & 0xff)
34 #define SET_ARGB(a, r, g, b) (a << 24 | r << 16 | g << 8 | b)
35 #define GET_ARCH_A GET_ARGB_A
36 #define GET_ARCH_R GET_ARGB_R
37 #define GET_ARCH_G GET_ARGB_G
38 #define GET_ARCH_B GET_ARGB_B
39 #else
40 #define GET_ARGB_A(rgb) (rgb & 0xff)
41 #define GET_ARGB_R(rgb) ((rgb >> 8) & 0xff)
42 #define GET_ARGB_G(rgb) ((rgb >> 16) & 0xff)
43 #define GET_ARGB_B(rgb) ((rgb >> 24) & 0xff)
44 #define GET_ARCH_A GET_ARGB_B
45 #define GET_ARCH_R GET_ARGB_G
46 #define GET_ARCH_G GET_ARGB_R
47 #define GET_ARCH_B GET_ARGB_A
48 #define SET_ARGB(a, r, g, b) (b << 24 | g << 16 | r << 8 | a)
49 #endif
51 struct ShadeData
53 struct NewImage *ni;
54 struct BitMap *rpBm;
55 UWORD offy;
56 UWORD fact;
57 WORD startx, starty;
60 struct RectList
62 ULONG rl_num;
63 struct RectList *rl_next;
64 struct Rectangle rl_rect;
67 struct layerhookmsg
69 struct Layer *l;
70 /* struct Rectangle rect; (replaced by the next line!) */
71 WORD MinX, MinY, MaxX, MaxY;
72 LONG OffsetX, OffsetY;
75 /* This function provides a number of ways to blit a NewImage onto RastPort. Please take great care when modifying it.
77 * The number of combinations of arguments is quite high. Please take time to understand it.
79 * Arguments:
80 * ni - a NewImage that is to be blitted
81 * subimageCol, subimageRow - define the initial read offset in source image based on assumption that image contains
82 * a number of subimages drawn in rows or columns
83 * xSrc, ySrc - define additional read offset in the source image subimage
84 * destRP - destination RastPort to blit the image to
85 * xDest, yDest - coordinates on the destination RastPort to where the imatge will be blitted
86 * widthSrc, heightSrc - width/height of region to be read from, if -1 then use the width/height of subimage
87 * widthDest, heightDest - width/height of blit on destination RastPort, if -1 then use widthSrc/heightSrc
90 static void BltScaleNewImageSubImageRastPort(struct NewImage * ni, ULONG subimageCol, ULONG subimageRow,
91 LONG xSrc, LONG ySrc, struct RastPort * destRP, LONG xDest, LONG yDest,
92 LONG widthSrc, LONG heightSrc, LONG widthDest, LONG heightDest)
94 ULONG subimagewidth = ni->w / ni->subimagescols;
95 ULONG subimageheight = ni->h / ni->subimagesrows;
97 if (subimageCol >= ni->subimagescols) return;
98 if (subimageRow >= ni->subimagesrows) return;
100 /* If source size not provided, use subimage size */
101 if (widthSrc < 0) widthSrc = (LONG)subimagewidth;
102 if (heightSrc < 0) heightSrc = (LONG)subimageheight;
104 /* If destination size not provided, use source */
105 if (widthDest < 0) widthDest = widthSrc;
106 if (heightDest < 0) heightDest = heightSrc;
108 /* If source and destination sizes do not match, scale */
109 if ((widthSrc != widthDest) || (heightSrc != heightDest))
111 /* FIXME: The scaled blitting needs similar optimized code paths as non-scaled */
112 ULONG * srcptr = (ni->data) + (((subimageheight * subimageRow) + ySrc) * ni->w) +
113 ((subimagewidth * subimageCol) + xSrc); /* Go to (0,0) of source rect */
115 ULONG * scaleddata = ScaleBuffer(srcptr, ni->w, widthSrc, heightSrc, widthDest, heightDest);
117 D(bug("[Decoration] SCALED %d,%d -> %d,%d!\n", widthSrc, heightSrc, widthDest, heightDest));
119 WritePixelArrayAlpha(scaleddata, 0, 0, widthDest * 4, destRP, xDest, yDest, widthDest, heightDest, 0xffffffff);
121 FreeVec(scaleddata);
123 else /* ((widthSrc != widthDest) || (heightSrc != heightDest)) */
125 /* Detect if image can be drawn using blitting instead of alpha draw */
126 if ((!ni->subimageinbm) || (!(ni->subimageinbm[subimageCol + (subimageRow * ni->subimagescols)])))
128 WritePixelArrayAlpha(ni->data, (subimagewidth * subimageCol) + xSrc ,
129 (subimageheight * subimageRow) + ySrc, ni->w * 4, destRP,
130 xDest, yDest, widthSrc, heightSrc, 0xffffffff);
132 else
134 /* LUT */
135 if (ni->bitmap != NULL)
137 if (ni->mask)
139 BltMaskBitMapRastPort(ni->bitmap, (subimagewidth * subimageCol) + xSrc ,
140 (subimageheight * subimageRow) + ySrc, destRP, xDest, yDest,
141 widthSrc, heightSrc, 0xe0, (PLANEPTR) ni->mask);
143 else
145 BltBitMapRastPort(ni->bitmap, (subimagewidth * subimageCol) + xSrc ,
146 (subimageheight * subimageRow) + ySrc, destRP, xDest, yDest,
147 widthSrc, heightSrc, 0xc0);
151 /* Truecolor */
152 if (ni->bitmap2 != NULL)
154 BltBitMapRastPort(ni->bitmap2, (subimagewidth * subimageCol) + xSrc ,
155 (subimageheight * subimageRow) + ySrc, destRP, xDest, yDest,
156 widthSrc, heightSrc, 0xc0);
162 /* HELPER WRAPPERS */
163 static inline void BltNewImageSubImageRastPort(struct NewImage * ni, ULONG subimageCol, ULONG subimageRow,
164 LONG xSrc, LONG ySrc, struct RastPort * destRP, LONG xDest, LONG yDest, LONG widthSrc, LONG heightSrc)
166 BltScaleNewImageSubImageRastPort(ni, subimageCol, subimageRow, xSrc, ySrc, destRP,
167 xDest, yDest, widthSrc, heightSrc, -1, -1);
170 static inline void BltNewImageSubImageRastPortSimple(struct NewImage * ni, ULONG subimageCol, ULONG subimageRow,
171 struct RastPort * destRP, LONG xDest, LONG yDest)
173 BltNewImageSubImageRastPort(ni, subimageCol, subimageRow, 0, 0, destRP,
174 xDest, yDest, -1, -1);
177 static inline void BltScaleNewImageSubImageRastPortSimple(struct NewImage * ni, ULONG subimageCol, ULONG subimageRow,
178 struct RastPort * destRP, LONG xDest, LONG yDest, LONG widthDest, LONG heightDest)
180 BltScaleNewImageSubImageRastPort(ni, subimageCol, subimageRow, 0, 0, destRP,
181 xDest, yDest, -1, -1, widthDest, heightDest);
183 /* HELPER WRAPPERS */
185 static void DrawTileToImage(struct NewImage *src, struct NewImage *dest, UWORD _sx, UWORD _sy, UWORD _sw, UWORD _sh, UWORD _dx, UWORD _dy, UWORD _dw, UWORD _dh)
188 ULONG dy, dx;
189 LONG dh, height, dw, width;
191 if (src == NULL) return;
192 if (dest == NULL) return;
194 dh = _sh;
195 dy = _dy;
196 height = _dh;
198 while (height > 0)
200 if ((height-dh)<0) dh = height;
201 height -= dh;
202 dw = _sw;
203 width = _dw;
204 dx = _dx;
205 while (width > 0)
207 if ((width-dw)<0) dw = width;
208 width -= dw;
209 DrawPartToImage(src, dest, _sx, _sy, dw, dh, dx, dy);
210 dx += dw;
212 dy += dh;
216 static void TileImageToImageMenuBar(struct NewImage *src, struct TileInfo * srcti, struct NewImage *dest)
218 UWORD y, h;
220 if (dest == NULL) return;
221 if (src == NULL) return;
222 if (srcti == NULL) return;
223 y = 0;
225 h = src->h;
227 if ((srcti->TileTop + srcti->TileBottom) > dest->h) return;
228 if (srcti->TileRight > dest->w) return;
230 DrawTileToImage(src, dest, srcti->TileLeft, y, src->w - srcti->TileLeft - srcti->TileRight, srcti->TileTop, 0, 0, dest->w - srcti->TileRight, srcti->TileTop);
231 DrawTileToImage(src, dest, srcti->TileLeft, y + h - srcti->TileBottom, src->w - srcti->TileLeft - srcti->TileRight, srcti->TileBottom, 0, dest->h - srcti->TileBottom, dest->w - srcti->TileRight, srcti->TileBottom);
232 DrawTileToImage(src, dest, srcti->TileLeft, y + srcti->TileTop, src->w - srcti->TileLeft - srcti->TileRight, h - srcti->TileBottom - srcti->TileTop, 0, srcti->TileTop + 0, dest->w - srcti->TileRight, dest->h - srcti->TileTop - srcti->TileBottom - 0);
235 DrawTileToImage(src, dest, src->w - srcti->TileRight, y, srcti->TileRight, srcti->TileTop, dest->w - srcti->TileRight, 0, srcti->TileRight, srcti->TileTop);
236 DrawTileToImage(src, dest, src->w - srcti->TileRight, y + h - srcti->TileBottom, srcti->TileRight, srcti->TileBottom, dest->w - srcti->TileRight , dest->h - srcti->TileBottom, srcti->TileRight, srcti->TileBottom);
237 DrawTileToImage(src, dest, src->w - srcti->TileRight, y + srcti->TileTop, srcti->TileRight, h - srcti->TileBottom - srcti->TileTop, dest->w - srcti->TileRight, srcti->TileTop + 0, srcti->TileRight, dest->h - srcti->TileTop - srcti->TileBottom - 0);
241 static void TileImageToImage(struct NewImage *src, struct TileInfo * srcti, struct NewImage *dest)
243 UWORD y, h;
245 if (dest == NULL) return;
246 if (src == NULL) return;
247 if (srcti == NULL) return;
248 y = 0;
250 h = src->h;
252 if ((srcti->TileTop + srcti->TileBottom) > dest->h) return;
253 if ((srcti->TileLeft + srcti->TileRight) > dest->w) return;
255 DrawTileToImage(src, dest, 0, y, srcti->TileLeft, srcti->TileTop, 0 , 0, srcti->TileLeft, srcti->TileTop);
256 DrawTileToImage(src, dest, 0, y + h - srcti->TileBottom, srcti->TileLeft, srcti->TileBottom, 0 , dest->h - srcti->TileBottom, srcti->TileLeft, srcti->TileBottom);
257 DrawTileToImage(src, dest, src->w - srcti->TileRight, y, srcti->TileRight, srcti->TileTop, dest->w - srcti->TileRight, 0, srcti->TileRight, srcti->TileTop);
258 DrawTileToImage(src, dest, src->w - srcti->TileRight, y + h - srcti->TileBottom, srcti->TileRight, srcti->TileBottom, dest->w - srcti->TileRight , dest->h - srcti->TileBottom, srcti->TileRight, srcti->TileBottom);
260 DrawTileToImage(src, dest, srcti->TileLeft, y, src->w - srcti->TileLeft - srcti->TileRight, srcti->TileTop, srcti->TileLeft, 0, dest->w - srcti->TileLeft - srcti->TileRight, srcti->TileTop);
261 DrawTileToImage(src, dest, srcti->TileLeft, y + h - srcti->TileBottom, src->w - srcti->TileLeft - srcti->TileRight, srcti->TileBottom, srcti->TileLeft, dest->h - srcti->TileBottom, dest->w - srcti->TileLeft - srcti->TileRight, srcti->TileBottom);
262 DrawTileToImage(src, dest, 0, y + srcti->TileTop, srcti->TileLeft, h - srcti->TileBottom - srcti->TileTop, 0 , srcti->TileTop + 0, srcti->TileLeft, dest->h - srcti->TileTop - srcti->TileBottom - 0);
263 DrawTileToImage(src, dest, src->w - srcti->TileRight, y + srcti->TileTop, srcti->TileRight, h - srcti->TileBottom - srcti->TileTop, dest->w - srcti->TileRight, srcti->TileTop + 0, srcti->TileRight, dest->h - srcti->TileTop - srcti->TileBottom - 0);
264 DrawTileToImage(src, dest, srcti->TileLeft, y + srcti->TileTop, src->w - srcti->TileLeft - srcti->TileRight, h - srcti->TileBottom - srcti->TileTop, srcti->TileLeft, srcti->TileTop + 0, dest->w - srcti->TileLeft - srcti->TileRight, dest->h - srcti->TileTop - srcti->TileBottom - 0);
267 static void MixImage(struct NewImage *dst, struct NewImage *src, struct TileInfo *srcti, UWORD ratio, UWORD w, UWORD h, UWORD dx, UWORD dy)
269 ULONG *s, *d;
270 ULONG rgba, rgb;
271 UWORD r, g, b;
272 UBYTE as, rs, gs, bs, rd, gd, bd;
273 BOOL tiled = FALSE;
274 int x, y;
276 if (src == NULL) return;
277 if (dst == NULL) return;
279 s = src->data;
280 d = dst->data;
282 if (srcti) tiled = TRUE;
284 for (y = 0; y < h; y++)
286 for (x = 0; x < w; x++)
288 rgba = s[x+y*src->w];
289 as = GET_ARGB_A(rgba);
290 rs = GET_ARGB_R(rgba);
291 gs = GET_ARGB_G(rgba);
292 bs = GET_ARGB_B(rgba);
293 rgb = d[x+dx + (y+dy) * dst->w];
295 rd = GET_ARGB_R(rgb);
296 gd = GET_ARGB_G(rgb);
297 bd = GET_ARGB_B(rgb);
299 r = ((rs * ratio) >> 8) + ((rd * (255 - ratio)) >> 8);
300 g = ((gs * ratio) >> 8) + ((gd * (255 - ratio)) >> 8);
301 b = ((bs * ratio) >> 8) + ((bd * (255 - ratio)) >> 8);
303 if (tiled) {
304 r = ((r * as) >> 8) + ((rd * (255 - as)) >> 8);
305 g = ((g * as) >> 8) + ((gd * (255 - as)) >> 8);
306 b = ((b * as) >> 8) + ((bd * (255 - as)) >> 8);
309 r = r & 0xff;
310 g = g & 0xff;
311 b = b & 0xff;
313 d[x+dx + (y+dy) * dst->w] = SET_ARGB(as, r, g, b);
319 static void BlurSourceAndMixTexture(struct NewImage *pic, struct NewImage *texture, struct TileInfo * textureti, UWORD ratio)
321 int x, y, ytw, t1, t2, b1, b2, l1, l2, r1, r2;
322 UWORD red, green, blue, alpha= 0, rs, gs, bs, as;
323 ULONG rgb, argb;
324 int width, w, height, ah, aw, xpos, ypos;
325 BOOL tiled = FALSE;
326 ULONG *raw, tw, th;
328 if (pic == NULL) return;
329 if (pic->data == NULL) return;
331 tw = pic->w;
332 if (textureti) tiled = TRUE;
333 th = pic->h;
334 raw = pic->data;
335 height = th;
336 width = tw;
338 if (raw)
340 for (y = 0; y < th; y++)
342 t1 = tw;
343 t2 = tw+tw;
344 b1 = tw;
345 b2 = tw+tw;
346 if (y == 0) t1 = t2 = 0;
347 else if (y == 1) t2 = t1;
349 if (y == (th-1)) b1 = b2 = 0;
350 else if (y == (th-2)) b2 = b1;
352 ytw = y*tw;
354 for (x = 0; x < tw; x++)
356 r1 = 1;
357 r2 = 2;
358 l1 = 1;
359 l2 = 2;
361 if (x == 0) l1 = r1 = 0;
362 else if (x == 1) l2 = l1;
364 if (x == (tw-1)) r1 = r2 = 0;
365 else if (x == (tw-2)) r2 = r1;
367 rgb = raw[x+ytw];
368 red = GET_ARGB_R(rgb);
369 green = GET_ARGB_G(rgb);
370 blue = GET_ARGB_B(rgb);
372 rgb = raw[x+ytw-t2];
373 red += GET_ARGB_R(rgb);
374 green += GET_ARGB_G(rgb);
375 blue += GET_ARGB_B(rgb);
377 rgb = raw[x+ytw-l1-t1];
378 red += GET_ARGB_R(rgb);
379 green += GET_ARGB_G(rgb);
380 blue += GET_ARGB_B(rgb);
382 rgb = raw[x+ytw-t1];
383 red += GET_ARGB_R(rgb);
384 green += GET_ARGB_G(rgb);
385 blue += GET_ARGB_B(rgb);
387 rgb = raw[x+ytw-t1];
388 red += GET_ARGB_R(rgb);
389 green += GET_ARGB_G(rgb);
390 blue += GET_ARGB_B(rgb);
392 rgb = raw[x+ytw-t1+r1];
393 red += GET_ARGB_R(rgb);
394 green += GET_ARGB_G(rgb);
395 blue += GET_ARGB_B(rgb);
397 rgb = raw[x+ytw-l2];
398 red += GET_ARGB_R(rgb);
399 green += GET_ARGB_G(rgb);
400 blue += GET_ARGB_B(rgb);
402 rgb = raw[x+ytw-l1];
403 red += GET_ARGB_R(rgb);
404 green += GET_ARGB_G(rgb);
405 blue += GET_ARGB_B(rgb);
407 rgb = raw[x+ytw+r1];
408 red += GET_ARGB_R(rgb);
409 green += GET_ARGB_G(rgb);
410 blue += GET_ARGB_B(rgb);
412 rgb = raw[x+ytw+r2];
413 red += GET_ARGB_R(rgb);
414 green += GET_ARGB_G(rgb);
415 blue += GET_ARGB_B(rgb);
417 rgb = raw[x+ytw+b1-l1];
418 red += GET_ARGB_R(rgb);
419 green += GET_ARGB_G(rgb);
420 blue += GET_ARGB_B(rgb);
422 rgb = raw[x+ytw+b1];
423 red += GET_ARGB_R(rgb);
424 green += GET_ARGB_G(rgb);
425 blue += GET_ARGB_B(rgb);
427 rgb = raw[x+ytw+b1+r1];
428 red += GET_ARGB_R(rgb);
429 green += GET_ARGB_G(rgb);
430 blue += GET_ARGB_B(rgb);
432 rgb = raw[x+ytw+b2];
433 red += GET_ARGB_R(rgb);
434 green += GET_ARGB_G(rgb);
435 blue += GET_ARGB_B(rgb);
437 red = red/14;
438 green = green/14;
439 blue = blue/14;
440 alpha = 255;
442 if (tiled)
444 argb = raw[x+ytw];
445 as = 255 - GET_ARGB_A(texture->data[x + y * texture->w]);
446 rs = GET_ARGB_R(argb);
447 gs = GET_ARGB_G(argb);
448 bs = GET_ARGB_B(argb);
450 red = ((rs * as) >> 8) + ((red * (255 - as)) >> 8);
451 green = ((gs * as) >> 8) + ((green * (255 - as)) >> 8);
452 blue = ((bs * as) >> 8) + ((blue * (255 - as)) >> 8);
454 raw[x+ytw] = SET_ARGB(as, red, green, blue);
457 else
459 raw[x+ytw] = SET_ARGB(alpha, red, green, blue);
464 if (ratio < 100)
466 if (texture)
468 ypos = 0;
469 while (height>0)
471 ah = texture->h;
472 if (ah > height) ah = height;
473 xpos = 0;
474 w = width;
475 while (w>0)
477 aw = texture->w;
478 if (aw > w) aw = w;
479 MixImage(pic, texture, textureti, 255 - (2.55 * ratio), aw, ah, xpos, ypos);
480 w -= aw;
481 xpos += aw;
483 height -= ah;
484 ypos += ah;
490 static void RenderBackgroundTiled(struct NewImage *pic, struct NewImage *texture, struct TileInfo *textureti,
491 UWORD ratio, VOID (*TileImageToImageFunc)(struct NewImage *src, struct TileInfo * srcti, struct NewImage *dest))
493 struct NewImage *ni;
495 if (texture)
497 ni = NewImageContainer(pic->w, pic->h);
498 if (ni)
500 if (textureti)
502 TileImageToImageFunc(texture, textureti, ni);
503 BlurSourceAndMixTexture(pic, ni, textureti, ratio);
505 else BlurSourceAndMixTexture(pic, texture, textureti, ratio);
507 DisposeImageContainer(ni);
509 else BlurSourceAndMixTexture(pic, texture, textureti, ratio);
511 else BlurSourceAndMixTexture(pic, NULL, NULL, ratio);
514 static void DrawMapTileToRP(struct NewImage *src, struct RastPort *rp, UWORD _sx, UWORD _sy, UWORD _sw, UWORD _sh, UWORD _dx, UWORD _dy, UWORD _dw, UWORD _dh)
517 ULONG dy, dx;
518 LONG dh, height, dw, width;
520 if (src == NULL) return;
521 if (rp == NULL) return;
523 dh = _sh;
524 dy = _dy;
525 height = _dh;
527 if (!src->ok) return;
529 while (height > 0)
531 if ((height-dh)<0) dh = height;
532 height -= dh;
533 dw = _sw;
534 width = _dw;
535 dx = _dx;
536 while (width > 0)
538 if ((width-dw)<0) dw = width;
539 width -= dw;
541 if (src->mask)
543 BltMaskBitMapRastPort(src->bitmap, _sx, _sy, rp, dx, dy, dw, dh, 0xe0, (PLANEPTR) src->mask);
545 else BltBitMapRastPort(src->bitmap, _sx, _sy, rp, dx, dy, dw, dh, 0xc0);
547 dx += dw;
549 dy += dh;
553 /******************************************************************************/
554 /******************************************************************************/
555 /******************************************************************************/
556 /******************************************************************************/
557 /******************************************************************************/
559 void DrawPartImageToRP(struct RastPort *rp, struct NewImage *ni, UWORD x, UWORD y, UWORD sx, UWORD sy, UWORD sw, UWORD sh)
561 if (ni->ok)
563 if (ni->bitmap == NULL)
565 WritePixelArray(ni->data, sx, sy, ni->w*4, rp, x, y, sw, sh, RECTFMT_ARGB);
567 else
569 BltBitMapRastPort(ni->bitmap, sx, sy, rp, x, y, sw, sh, 0xc0);
574 void DrawPartToImage(struct NewImage *src, struct NewImage *dest, UWORD sx, UWORD sy, UWORD sw, UWORD sh, UWORD dx, UWORD dy)
576 UWORD x, y;
578 for (y = 0; y < sh; y++)
580 for (x = 0; x < sw; x++)
582 dest->data[dx + x + (dy + y) * dest->w] = src->data[sx + x + (sy + y) * src->w];
587 void RenderMenuBackground(struct NewImage *pic, struct NewImage *texture, struct TileInfo *textureti, UWORD ratio)
589 if (texture)
591 if (textureti) RenderBackgroundTiled(pic, texture, textureti, ratio, TileImageToImage);
592 else BlurSourceAndMixTexture(pic, texture, textureti, ratio);
594 else BlurSourceAndMixTexture(pic, NULL, NULL, ratio);
597 void RenderMenuBarBackground(struct NewImage *pic, struct NewImage *texture, struct TileInfo *textureti, UWORD ratio)
599 if (texture && textureti)
602 /* Fill the image with the center tile */
603 DrawTileToImage(texture, pic,
604 textureti->TileLeft, textureti->TileTop,
605 texture->w - textureti->TileLeft - textureti->TileRight, texture->h - textureti->TileBottom - textureti->TileTop,
606 0, 0, pic->w, pic->h);
608 RenderBackgroundTiled(pic, texture, textureti, ratio, TileImageToImageMenuBar);
612 void WriteAlphaPixelArray(struct NewImage *src, struct NewLUT8Image *dst, LONG sx, LONG sy, LONG dx, LONG dy, LONG w, LONG h)
614 ULONG *s = src->data;
615 ULONG argb;
616 UBYTE *d = dst->data;
617 int x, y;
619 for (y = 0; y < h; y++)
621 for (x = 0; x < w; x++)
623 argb = s[sx + x + (sy + y) * src->w];
624 d[dx + x + (dy + y) * dst->w] = GET_ARGB_A(argb);
629 void SetImageTint(struct NewImage *dst, UWORD ratio, ULONG argb)
632 ULONG *d;
633 ULONG rgb;
634 UWORD r, g, b, w, h;
635 UBYTE rs, gs, bs, rd, gd, bd;
636 int x, y;
638 if (dst == NULL) return;
640 d = dst->data;
642 w = dst->w;
643 h = dst->h;
645 rs = (argb >> 16) & 0xff;
646 gs = (argb >> 8) & 0xff;
647 bs = argb & 0xff;
649 for (y = 0; y < h; y++)
651 for (x = 0; x < w; x++)
653 rgb = d[x + y * w];
654 rd = GET_ARGB_R(rgb);
655 gd = GET_ARGB_G(rgb);
656 bd = GET_ARGB_B(rgb);
657 r = ((rs * ratio) >> 8) + ((rd * (255 - ratio)) >> 8);
658 g = ((gs * ratio) >> 8) + ((gd * (255 - ratio)) >> 8);
659 b = ((bs * ratio) >> 8) + ((bd * (255 - ratio)) >> 8);
661 r = r & 0xff;
662 g = g & 0xff;
663 b = b & 0xff;
665 d[x + y * w] = SET_ARGB(255, r, g, b);
671 * offx - offset between start of ni and place where image should be sample from
672 * offy - offset between start of ni and place where image should be sample from
673 * x, y, w, h - coords in rastport rp
675 void HorizVertRepeatNewImage(struct NewImage *ni, ULONG color, UWORD offx, UWORD offy, struct RastPort *rp, UWORD x, UWORD y, WORD w, WORD h)
677 ULONG ow, oh, sy, sx, dy, dx;
678 LONG dh, height, dw, width;
680 if ((w <= 0) || (h <= 0)) return;
682 if (!ni->ok)
684 FillPixelArray(rp, x, y, w, h, color);
685 return;
688 ow = ni->w;
689 oh = ni->h;
691 sy = offy % oh;
692 dh = oh - sy;
693 height = h;
694 dy = y;
695 while (height > 0)
697 if ((height-dh)<0) dh = height;
698 height -= dh;
700 sx = offx % ow;
701 dw = ow - sx;
702 width = w;
703 dx = x;
704 while (width > 0)
706 if ((width-dw)<0) dw = width;
707 width -= dw;
709 BltNewImageSubImageRastPort(ni, 0, 0, sx, sy, rp, dx, dy, dw, dh);
711 dx += dw;
712 sx = 0;
713 dw = ow;
715 dy += dh;
716 sy = 0;
717 dh = oh;
721 /* NOTE: fill parameter is ignored, previously it was forcing a no-alpha blit, but
722 this is already handled in BltNewImageSubImageRastPort */
723 /* dh - destination height to which subimage will be scaled to */
724 LONG WriteTiledImageTitle(BOOL fill, struct Window *win,
725 struct RastPort *rp, struct NewImage *ni, LONG sx, LONG sy, LONG sw,
726 LONG sh, LONG xp, LONG yp, LONG dw, LONG dh)
728 int w = dw;
729 int x = xp;
730 int ddw;
732 if (!ni->ok) return x;
734 if ((sw == 0) || (dw == 0)) return xp;
736 if (win)
738 if (x > win->Width) return xp;
739 if ((x + w) > win->Width) w = win->Width - x;
742 while (w > 0)
744 ddw = sw;
745 if (w < ddw) ddw = w;
747 BltScaleNewImageSubImageRastPort(ni, 0, 0, sx, sy, rp, x, yp, ddw, -1, -1, dh);
749 w -= ddw;
750 x += ddw;
752 return x;
756 * dh - destination height to scale to, -1 to use subimage height
758 LONG WriteVerticalScaledTiledImageHorizontal(struct RastPort *rp, struct NewImage *ni, ULONG subimage,
759 LONG sx, LONG sw, LONG xp, LONG yp, LONG sh, LONG dw, LONG dh)
761 LONG w = dw;
762 LONG x = xp;
763 LONG ddw;
765 if (!ni->ok) return xp;
767 if ((sw == 0) || (dw == 0)) return xp;
769 while (w > 0)
771 ddw = sw;
772 if (w < ddw) ddw = w;
774 BltScaleNewImageSubImageRastPort(ni, 0, subimage, sx, 0, rp, x, yp, ddw, sh, -1, dh);
776 w -= ddw;
777 x += ddw;
780 return x;
783 LONG WriteTiledImageHorizontal(struct RastPort *rp, struct NewImage *ni, ULONG subimage, LONG sx, LONG sw, LONG xp, LONG yp, LONG dw)
785 return WriteVerticalScaledTiledImageHorizontal(rp, ni, subimage, sx, sw, xp, yp, -1, dw, -1);
788 LONG WriteTiledImageVertical(struct RastPort *rp, struct NewImage *ni, ULONG subimage, LONG sy, LONG sh, LONG xp, LONG yp, LONG dh)
790 int h = dh;
791 int y = yp;
792 int ddh;
794 if (!ni->ok) return y;
796 if ((sh == 0) || (dh == 0)) return yp;
798 while (h > 0)
800 ddh = sh;
801 if (h < ddh) ddh = h;
803 BltNewImageSubImageRastPort(ni, subimage, 0, 0, sy, rp, xp, y, -1, ddh);
805 h -= ddh;
806 y += ddh;
808 return y;
811 struct myrgb
813 int red,green,blue;
816 void FillMemoryBufferRGBGradient(UBYTE * buf, LONG pen, LONG xt, LONG yt, LONG xb, LONG yb, LONG xp, LONG yp, LONG w, LONG h, ULONG start_rgb, ULONG end_rgb, LONG angle)
818 /* The basic idea of this algorithm is to calc the intersection between the
819 * diagonal of the rectangle (xs,ys) with dimension (xw,yw) a with the line starting
820 * at (x,y) (every pixel inside the rectangle) and angle angle with direction vector (vx,vy).
822 * Having the intersection point we then know the color of the pixel.
824 * TODO: Turn the algorithm into a incremental one
825 * Remove the use of floating point variables */
826 double rad = angle*M_PI/180;
827 double cosarc = cos(rad);
828 double sinarc = sin(rad);
830 struct myrgb startRGB,endRGB;
832 int diffR, diffG, diffB;
834 int r,t; /* some helper variables to short the code */
835 int l,y,c,x;
836 int y1; /* The intersection point */
837 int incr_y1; /* increment of y1 */
838 int xs,ys,xw,yw;
839 int xadd,ystart,yadd;
840 // double vx = -cosarc;
841 // double vy = sinarc;
842 int vx = (int)(-cosarc*0xff);
843 int vy = (int)(sinarc*0xff);
845 int width = xb - xt + 1;
846 int height = yb - yt + 1;
848 if (buf == NULL) return;
850 startRGB.red = (start_rgb >> 16) & 0xff;
851 startRGB.green = (start_rgb >> 8) & 0xff;
852 startRGB.blue = start_rgb & 0xff;
854 endRGB.red = (end_rgb >> 16) & 0xff;
855 endRGB.green = (end_rgb >> 8) & 0xff;
856 endRGB.blue = end_rgb & 0xff;
858 diffR = endRGB.red - startRGB.red;
859 diffG = endRGB.green - startRGB.green;
860 diffB = endRGB.blue - startRGB.blue;
862 /* Normalize the angle */
863 if (angle < 0) angle = 360 - ((-angle)%360);
864 if (angle >= 0) angle = angle % 360;
866 if (angle <= 90 || (angle > 180 && angle <= 270))
868 /* The to be intersected diagonal goes from the top left edge to the bottom right edge */
869 xs = 0;
870 ys = 0;
871 xw = width;
872 yw = height;
873 } else
875 /* The to be intersected diagonal goes from the bottom left edge to the top right edge */
876 xs = 0;
877 ys = height;
878 xw = width;
879 yw = -height;
882 if (angle > 90 && angle <= 270)
884 /* for these angle we have y1 = height - y1. Instead of
886 * y1 = height - (-vy*(yw* xs -xw* ys) + yw*(vy* x -vx* y)) /(-yw*vx + xw*vy);
888 * we can write
890 * y1 = (-vy*(yw*(-xs)-xw*(-ys+height)) + yw*(vy*(-x)-vx*(-y+height)))/(-yw*vx + xw*vy);
892 * so height - y1 can be expressed with the normal formular adapting some parameters.
894 * Note that if one would exchanging startRGB/endRGB the values would only work
895 * for linear color gradients */
896 xadd = -1;
897 yadd = -1;
898 ystart = height;
900 xs = -xs;
901 ys = -ys + height;
903 else
905 xadd = 1;
906 yadd = 1;
907 ystart = 0;
910 r = -vy*(yw*xs-xw*ys);
911 t = -yw*vx + xw*vy;
913 /* The formular as shown above is
915 * y1 = ((-vy*(yw*xs-xw*ys) + yw*(vy*x-vx*y)) /(-yw*vx + xw*vy));
917 * We see that only yw*(vy*x-vx*y) changes during the loop.
919 * We write
921 * Current Pixel: y1(x,y) = (r + yw*(vy*x-vx*y))/t = r/t + yw*(vy*x-vx*y)/t
922 * Next Pixel: y1(x+xadd,y) = (r + vw*(vy*(x+xadd)-vx*y))/t
924 * t*(y1(x+xadd,y) - y1(x,y)) = yw*(vy*(x+xadd)-vx*y) - yw*(vy*x-vx*y) = yw*vy*xadd; */
926 incr_y1 = yw*vy*xadd;
927 UBYTE *bufptr = buf;
928 for (l = 0, y = ystart + ((yp - yt)* yadd); l < h; l++, y+=yadd)
930 /* Calculate initial y1 accu, can be brought out of the loop as well (x=0). It's probably a
931 * a good idea to add here also a value of (t-1)/2 to ensure the correct rounding
932 * This (and for r) is also a place were actually a overflow can happen |yw|=16 |y|=16. So for
933 * vx nothing is left, currently 9 bits are used for vx or vy */
934 int y1_mul_t_accu = r - yw*vx*y;
938 for (c = 0, x = ((xp - xt) * xadd); c < w; c++, x+=xadd)
940 int red,green,blue;
942 /* Calculate the intersection of two lines, this is not the fastet way to do but
943 * it is intuitive. Note: very slow! Will be optimzed later (remove FFP usage
944 * and making it incremental)...update: it's now incremental and no FFP is used
945 * but it probably can be optimized more by removing some more of the divisions and
946 * further specialize the stuff here (use of three accus). */
947 /* y1 = (int)((-vy*(yw*xs-xw*ys) + yw*(vy*x-vx*y)) /(-yw*vx + xw*vy));*/
948 y1 = y1_mul_t_accu / t;
950 red = startRGB.red + (int)(diffR*y1/height);
951 green = startRGB.green + (int)(diffG*y1/height);
952 blue = startRGB.blue + (int)(diffB*y1/height);
953 /* By using full 32 bits this can be made faster as well */
954 *bufptr++ = red;
955 *bufptr++ = green;
956 *bufptr++ = blue;
958 y1_mul_t_accu += incr_y1;
964 void FillPixelArrayGradient(LONG pen, BOOL tc, struct RastPort *rp, LONG xt, LONG yt, LONG xb, LONG yb, LONG xp, LONG yp, LONG w, LONG h, ULONG start_rgb, ULONG end_rgb, LONG angle, LONG dx, LONG dy)
966 UBYTE * buf = NULL;
968 if ((w <= 0) || (h <= 0)) return;
970 /* By bringing building the gradient array in the same format as the RastPort BitMap a call
971 to WritePixelArray() can be made also faster */
972 buf = AllocVec(1 * yb * 3, 0);
974 FillMemoryBufferRGBGradient(buf, pen, xt, yt, xb, yb, xp, yp, 1, yb, start_rgb, end_rgb, angle);
976 HorizRepeatBuffer(buf, dy, pen, tc, rp, xp, yp, w, h);
978 FreeVec(buf);
981 void HorizRepeatBuffer(UBYTE * buf, LONG offy, LONG pen, BOOL tc, struct RastPort *rp, LONG x, LONG y, LONG w, LONG h)
983 UBYTE * bufblit = NULL;
984 ULONG xi, yi;
985 ULONG idxd;
986 ULONG idxs;
988 if ((w <= 0) || (h <= 0)) return;
989 if (!tc)
991 if (pen != -1) SetAPen(rp, pen); else SetAPen(rp, 2);
992 RectFill(rp, x, y, x + w - 1, y + h - 1);
993 return;
996 /* By bringing building the gradient array in the same format as the RastPort BitMap a call
997 to WritePixelArray() can be made also faster */
998 bufblit = AllocVec(w * h * 3, MEMF_ANY);
999 if (!bufblit)
1000 return;
1002 /* Copy one column buffer into blit buffer */
1003 for (yi = 0; yi < h; yi++)
1005 idxs = (offy + yi) * 3; /* source index */
1006 idxd = yi * 3 * w; /* dest index */
1007 for (xi = 0; xi < w; xi++)
1009 /* Copy RGB pixel */
1010 bufblit[idxd++] = buf[idxs + 0];
1011 bufblit[idxd++] = buf[idxs + 1];
1012 bufblit[idxd++] = buf[idxs + 2];
1016 WritePixelArray(bufblit, 0, 0, w * 3, rp, x, y, w, h, RECTFMT_RGB);
1018 FreeVec(bufblit);
1021 void TileMapToBitmap(struct NewImage *src, struct TileInfo *srcti, struct BitMap *map, UWORD dw, UWORD dh)
1023 UWORD y, h;
1025 if (map == NULL) return;
1026 if (src == NULL) return;
1027 if (srcti == NULL) return;
1028 y = 0;
1030 h = src->h;
1032 if ((srcti->TileTop + srcti->TileBottom) > dh) return;
1033 if ((srcti->TileLeft + srcti->TileRight) > dw) return;
1035 struct RastPort *dest = CreateRastPort();
1037 if (dest != NULL)
1039 dest->BitMap = map;
1041 DrawMapTileToRP(src, dest, 0, y, srcti->TileLeft, srcti->TileTop, 0 , 0, srcti->TileLeft, srcti->TileTop);
1042 DrawMapTileToRP(src, dest, 0, y + h - srcti->TileBottom, srcti->TileLeft, srcti->TileBottom, 0 , dh - srcti->TileBottom, srcti->TileLeft, srcti->TileBottom);
1043 DrawMapTileToRP(src, dest, src->w - srcti->TileRight, y, srcti->TileRight, srcti->TileTop, dw - srcti->TileRight, 0, srcti->TileRight, srcti->TileTop);
1044 DrawMapTileToRP(src, dest, src->w - srcti->TileRight, y + h - srcti->TileBottom, srcti->TileRight, srcti->TileBottom, dw - srcti->TileRight , dh - srcti->TileBottom, srcti->TileRight, srcti->TileBottom);
1046 DrawMapTileToRP(src, dest, srcti->TileLeft, y, src->w - srcti->TileLeft - srcti->TileRight, srcti->TileTop, srcti->TileLeft, 0, dw - srcti->TileLeft - srcti->TileRight, srcti->TileTop);
1047 DrawMapTileToRP(src, dest, srcti->TileLeft, y + h - srcti->TileBottom, src->w - srcti->TileLeft - srcti->TileRight, srcti->TileBottom, srcti->TileLeft, dh - srcti->TileBottom, dw - srcti->TileLeft - srcti->TileRight, srcti->TileBottom);
1048 DrawMapTileToRP(src, dest, 0, y + srcti->TileTop, srcti->TileLeft, h - srcti->TileBottom - srcti->TileTop, 0 , srcti->TileTop + 0, srcti->TileLeft, dh - srcti->TileTop - srcti->TileBottom - 0);
1049 DrawMapTileToRP(src, dest, src->w - srcti->TileRight, y + srcti->TileTop, srcti->TileRight, h - srcti->TileBottom - srcti->TileTop, dw - srcti->TileRight, srcti->TileTop + 0, srcti->TileRight, dh - srcti->TileTop - srcti->TileBottom - 0);
1050 DrawMapTileToRP(src, dest, srcti->TileLeft, y + srcti->TileTop, src->w - srcti->TileLeft - srcti->TileRight, h - srcti->TileBottom - srcti->TileTop, srcti->TileLeft, srcti->TileTop + 0, dw - srcti->TileLeft - srcti->TileRight, dh - srcti->TileTop - srcti->TileBottom - 0);
1051 FreeRastPort(dest);
1055 struct NewImage *GetImageFromRP(struct RastPort *rp, UWORD x, UWORD y, UWORD w, UWORD h)
1057 struct NewImage *ni;
1059 ni = NewImageContainer(w, h);
1060 if (ni)
1062 ReadPixelArray(ni->data, 0, 0, w*4, rp, x, y, w, h, RECTFMT_ARGB);
1064 return ni;
1067 void PutImageToRP(struct RastPort *rp, struct NewImage *ni, UWORD x, UWORD y) {
1069 if (ni)
1071 if (ni->data) WritePixelArray(ni->data, 0, 0, ni->w*4, rp, x, y, ni->w, ni->h, RECTFMT_ARGB);
1072 DisposeImageContainer(ni);
1076 ULONG CalcShade(ULONG base, UWORD fact)
1078 int c0, c1, c2, c3;
1080 c0 = GET_ARGB_A(base);
1081 c1 = GET_ARGB_R(base);
1082 c2 = GET_ARGB_G(base);
1083 c3 = GET_ARGB_B(base);
1084 #if !defined(DECOR_NOSHADE)
1085 c0 *= fact;
1086 c1 *= fact;
1087 c2 *= fact;
1088 c3 *= fact;
1089 c0 = c0 >> 8;
1090 c1 = c1 >> 8;
1091 c2 = c2 >> 8;
1092 c3 = c3 >> 8;
1093 #endif
1094 if (c0 > 255) c0 = 255;
1095 if (c1 > 255) c1 = 255;
1096 if (c2 > 255) c2 = 255;
1097 if (c3 > 255) c3 = 255;
1099 return (ULONG)SET_ARGB(c0, c1, c2, c3);
1102 AROS_UFH3(void, RectShadeFunc,
1103 AROS_UFHA(struct Hook * , h, A0),
1104 AROS_UFHA(struct RastPort * , rp, A2),
1105 AROS_UFHA(struct layerhookmsg *, msg, A1))
1107 AROS_USERFUNC_INIT
1109 struct ShadeData *data = h->h_Data;
1111 #if defined(DECOR_USELINEBUFF)
1112 ULONG *outline = NULL;
1113 ULONG linesize = 0;
1114 #endif
1115 UWORD startx, starty, width = 1 + msg->MaxX - msg->MinX;
1116 UWORD height = 1 + msg->MaxY - msg->MinY;
1117 WORD src_offset_x = 0;
1118 WORD src_offset_y = 0;
1119 struct RastPort *dstRp;
1120 ULONG color;
1122 HIDDT_Color col;
1123 APTR bm_handle = NULL;
1124 int px, py;
1125 #if !defined(DECOR_FAKESHADE)
1126 int x = 0, y;
1128 #endif
1130 bug("[Decoration] %s: data @ 0x%p\n", __func__, data);
1131 bug("[Decoration] %s: offy = %d, fact = %d, ni @ 0x%p\n", __func__, data->offy, data->fact, data->ni);
1132 bug("[Decoration] %s: Msg Area = %d,%d -> %d,%d\n", __func__, msg->MinX, msg->MinY, msg->MaxX, msg->MaxY);
1133 bug("[Decoration] %s: Offset = %d,%d\n", __func__, msg->OffsetX, msg->OffsetY);
1136 if (data->rpBm == rp->BitMap)
1138 startx = msg->MinX;
1139 starty = msg->MinY;
1140 src_offset_x = msg->OffsetX;
1141 src_offset_y = msg->OffsetY;
1143 else
1145 struct ClipRect * CR;
1147 // Hidden cliprect..
1148 startx = msg->MinX;
1149 starty = msg->MinY;
1151 for (CR=rp->Layer->ClipRect;CR;CR=CR->Next)
1153 if (CR->BitMap == rp->BitMap)
1155 src_offset_x = startx + (CR->bounds.MinX - rp->Layer->bounds.MinX) - ALIGN_OFFSET(CR->bounds.MinX);
1156 src_offset_y = starty + (CR->bounds.MinY - rp->Layer->bounds.MinY);
1162 bug("[Decoration] %s: Offset = %d,%d\n", __func__, src_offset_x, src_offset_y);
1165 #if defined(DECOR_USELINEBUFF)
1166 if (width > 1)
1167 linesize = width << 2;
1168 else if (height > 1)
1170 #if !defined(DECOR_FAKESHADE)
1171 x = src_offset_x % data->ni->w;
1172 #endif
1173 linesize = height << 2;
1176 if (linesize)
1178 outline = AllocMem(linesize, MEMF_ANY);
1181 if (!outline)
1182 #endif
1184 #if !defined(DECOR_NODIRECT)
1185 bm_handle = LockBitMapTags(rp->BitMap,
1186 TAG_END);
1187 #endif
1188 dstRp = rp;
1190 else
1192 dstRp = CloneRastPort(rp);
1193 dstRp->Layer = NULL;
1196 for (py = starty; py < (starty + height); py++)
1198 #if !defined(DECOR_FAKESHADE)
1199 y = (src_offset_y + py - starty) % data->ni->h;
1200 #endif
1202 #if defined(DECOR_USELINEBUFF)
1203 if (width == 1 && outline)
1205 #if !defined(DECOR_FAKESHADE)
1206 color = CalcShade(data->ni->data[(y * data->ni->w) + x], data->fact);
1207 #else
1208 color = SET_ARGB(00, 0xFF, 0x00, 0x70);
1209 #endif
1210 outline[py - starty] = color;
1212 continue;
1215 #endif
1216 for (px = startx; px < (startx + width); px++)
1218 #if !defined(DECOR_FAKESHADE)
1219 x = (src_offset_x + px - startx) % data->ni->w;
1221 color = CalcShade(data->ni->data[(y * data->ni->w) + x], data->fact);
1222 #else
1223 color = SET_ARGB(00, 0xFF, 0x00, 0x70);
1224 #endif
1226 #if defined(DECOR_USELINEBUFF)
1227 if (outline)
1229 outline[px - startx] = color;
1231 else
1232 #endif
1233 if (bm_handle)
1235 col.alpha = (HIDDT_ColComp) GET_ARGB_A(color) << 8;
1236 col.red = (HIDDT_ColComp) GET_ARGB_R(color) << 8;
1237 col.green = (HIDDT_ColComp) GET_ARGB_G(color) << 8;
1238 col.blue = (HIDDT_ColComp) GET_ARGB_B(color) << 8;
1240 HIDD_BM_PutPixel(HIDD_BM_OBJ(dstRp->BitMap), px, py, HIDD_BM_MapColor(HIDD_BM_OBJ(dstRp->BitMap), &col));
1242 else
1244 WriteRGBPixel(dstRp,
1247 #if AROS_BIG_ENDIAN
1248 color);
1249 #else
1250 SET_ARGB(GET_ARCH_A(color), GET_ARCH_R(color), GET_ARCH_G(color), GET_ARCH_B(color)));
1251 #endif
1254 #if defined(DECOR_USELINEBUFF)
1255 if (outline && (width > 1))
1257 WritePixelArray(outline,
1258 0, 0,
1259 linesize,
1260 dstRp,
1261 startx,
1262 starty,
1263 width, 1,
1264 RECTFMT_ARGB);
1266 #endif
1269 #if defined(DECOR_USELINEBUFF)
1270 if (outline)
1272 if (width == 1)
1274 WritePixelArray(outline,
1275 0, 0,
1276 sizeof(ULONG),
1277 dstRp,
1278 startx,
1279 starty,
1280 1, height,
1281 RECTFMT_ARGB);
1283 FreeMem(outline, linesize);
1285 else
1286 #endif
1287 if (bm_handle)
1289 struct RectList bm_rectlist;
1290 struct TagItem bm_ultags[3] =
1292 {UBMI_REALLYUNLOCK, TRUE },
1293 {UBMI_UPDATERECTS, (IPTR)&bm_rectlist },
1294 {TAG_DONE, 0 }
1297 bm_rectlist.rl_num = 1;
1298 bm_rectlist.rl_next = (struct RectList *)0;
1299 bm_rectlist.rl_rect.MinX = msg->MinX;
1300 bm_rectlist.rl_rect.MinY = msg->MinY;
1301 bm_rectlist.rl_rect.MaxX = msg->MaxX;
1302 bm_rectlist.rl_rect.MaxY = msg->MaxY;
1304 UnLockBitMapTagList(bm_handle, bm_ultags);
1307 if (dstRp != rp)
1308 FreeRastPort(dstRp);
1310 AROS_USERFUNC_EXIT
1313 void ShadeLine(LONG pen, BOOL tc, BOOL usegradients, struct RastPort *rp, struct NewImage *ni, ULONG basecolor, UWORD fact, UWORD _offy, UWORD x0, UWORD y0, UWORD x1, UWORD y1)
1315 ULONG color;
1317 if ((x1 < x0) || (y1 < y0)) return;
1318 if (!tc)
1320 SetAPen(rp, pen);
1321 Move(rp, x0, y0);
1322 Draw(rp, x1, y1);
1323 return;
1325 if (usegradients)
1327 D(bug("[Decoration] %s: GRADIENT > %d,%d -> %d,%d\n", __func__, x0, y0, x1, y1);)
1329 color = CalcShade(basecolor, fact);
1331 SetRPAttrs(rp, RPTAG_PenMode, FALSE, RPTAG_FgColor, color, TAG_DONE);
1332 Move(rp, x0, y0);
1333 Draw(rp, x1, y1);
1335 else if (ni->ok)
1337 struct ShadeData shadeParams;
1338 struct Hook shadeHook;
1339 struct Rectangle shadeRect;
1341 shadeRect.MinX = x0;
1342 shadeRect.MaxX = x1;
1343 shadeRect.MinY = y0;
1344 shadeRect.MaxY = y1;
1346 D(bug("[Decoration] %s: SHADE > %d,%d -> %d,%d\n", __func__, x0, y0, x1, y1);)
1348 shadeParams.ni = ni;
1349 shadeParams.rpBm = rp->BitMap;
1350 shadeParams.startx = x0,
1351 shadeParams.starty = y0;
1352 shadeParams.offy = _offy;
1353 shadeParams.fact = fact;
1355 shadeHook.h_Entry = (HOOKFUNC)AROS_ASMSYMNAME(RectShadeFunc);
1356 shadeHook.h_Data = &shadeParams;
1358 DoHookClipRects(&shadeHook, rp, &shadeRect);
1360 else
1362 D(bug("[Decoration] %s: DRAW > %d,%d -> %d,%d\n", __func__, x0, y0, x1, y1);)
1363 Move(rp, x0, y0);
1364 Draw(rp, x1, y1);
1368 void DrawScaledStatefulGadgetImageToRP(struct RastPort *rp, struct NewImage *ni, ULONG state, UWORD xp, UWORD yp,
1369 WORD scaledwidth, WORD scaledheight)
1372 UWORD subimagecol = 0;
1373 UWORD subimagerow = 0;
1375 if (ni->ok)
1377 switch(state)
1379 case IDS_NORMAL:
1380 break;
1381 case IDS_SELECTED:
1382 subimagecol = 1;
1383 break;
1384 case IDS_INACTIVENORMAL:
1385 subimagecol = 2;
1386 break;
1389 BltScaleNewImageSubImageRastPortSimple(ni, subimagecol, subimagerow, rp, xp, yp, scaledwidth, scaledheight);
1393 void DrawStatefulGadgetImageToRP(struct RastPort *rp, struct NewImage *ni, ULONG state, UWORD xp, UWORD yp)
1395 DrawScaledStatefulGadgetImageToRP(rp, ni, state, xp, yp, -1, -1);