oops. broke the BM_PUTPIXEL coords. use PIXFMT_BGRA32 for x86, and convert the color...
[AROS.git] / workbench / c / Decoration / drawfuncs.c
blobc85e321d5ee2f5507b67f0ff45f956a47bacfc9e
1 /*
2 Copyright © 2011-2017, The AROS Development Team.
3 $Id$
4 */
6 #include <aros/debug.h>
8 #include <intuition/imageclass.h>
9 #include <graphics/rpattr.h>
10 #include <libraries/cybergraphics.h>
11 #include <proto/arossupport.h>
12 #include <proto/graphics.h>
13 #include <proto/cybergraphics.h>
14 #include <proto/layers.h>
15 #include <proto/exec.h>
17 #include <hidd/gfx.h>
19 #include <math.h>
21 #include "drawfuncs.h"
23 #define DECOR_USELINEBUFF
24 //#define DECOR_FAKESHADE
25 //#define DECOR_NODIRECT
27 #if AROS_BIG_ENDIAN
28 #define GET_ARGB_A(rgb) ((rgb >> 24) & 0xff)
29 #define GET_ARGB_R(rgb) ((rgb >> 16) & 0xff)
30 #define GET_ARGB_G(rgb) ((rgb >> 8) & 0xff)
31 #define GET_ARGB_B(rgb) (rgb & 0xff)
32 #define SET_ARGB(a, r, g, b) (a << 24 | r << 16 | g << 8 | b)
33 #else
34 #define GET_ARGB_A(rgb) (rgb & 0xff)
35 #define GET_ARGB_R(rgb) ((rgb >> 8) & 0xff)
36 #define GET_ARGB_G(rgb) ((rgb >> 16) & 0xff)
37 #define GET_ARGB_B(rgb) ((rgb >> 24) & 0xff)
38 #define SET_ARGB(a, r, g, b) (b << 24 | g << 16 | r << 8 | a)
39 #endif
41 struct ShadeData
43 struct NewImage *ni;
44 UWORD fact;
47 struct RectList
49 ULONG rl_num;
50 struct RectList *rl_next;
51 struct Rectangle rl_rect;
54 struct layerhookmsg
56 struct Layer *l;
57 /* struct Rectangle rect; (replaced by the next line!) */
58 WORD MinX, MinY, MaxX, MaxY;
59 LONG OffsetX, OffsetY;
62 /* This function provides a number of ways to blit a NewImage onto RastPort. Please take great care when modifying it.
64 * The number of combinations of arguments is quite high. Please take time to understand it.
66 * Arguments:
67 * ni - a NewImage that is to be blitted
68 * subimageCol, subimageRow - define the initial read offset in source image based on assumption that image contains
69 * a number of subimages drawn in rows or columns
70 * xSrc, ySrc - define additional read offset in the source image subimage
71 * destRP - destination RastPort to blit the image to
72 * xDest, yDest - coordinates on the destination RastPort to where the imatge will be blitted
73 * widthSrc, heightSrc - width/height of region to be read from, if -1 then use the width/height of subimage
74 * widthDest, heightDest - width/height of blit on destination RastPort, if -1 then use widthSrc/heightSrc
77 static void BltScaleNewImageSubImageRastPort(struct NewImage * ni, ULONG subimageCol, ULONG subimageRow,
78 LONG xSrc, LONG ySrc, struct RastPort * destRP, LONG xDest, LONG yDest,
79 LONG widthSrc, LONG heightSrc, LONG widthDest, LONG heightDest)
81 ULONG subimagewidth = ni->w / ni->subimagescols;
82 ULONG subimageheight = ni->h / ni->subimagesrows;
84 if (subimageCol >= ni->subimagescols) return;
85 if (subimageRow >= ni->subimagesrows) return;
87 /* If source size not provided, use subimage size */
88 if (widthSrc < 0) widthSrc = (LONG)subimagewidth;
89 if (heightSrc < 0) heightSrc = (LONG)subimageheight;
91 /* If destination size not provided, use source */
92 if (widthDest < 0) widthDest = widthSrc;
93 if (heightDest < 0) heightDest = heightSrc;
95 /* If source and destination sizes do not match, scale */
96 if ((widthSrc != widthDest) || (heightSrc != heightDest))
98 /* FIXME: The scaled blitting needs similar optimized code paths as non-scaled */
99 ULONG * srcptr = (ni->data) + (((subimageheight * subimageRow) + ySrc) * ni->w) +
100 ((subimagewidth * subimageCol) + xSrc); /* Go to (0,0) of source rect */
102 ULONG * scaleddata = ScaleBuffer(srcptr, ni->w, widthSrc, heightSrc, widthDest, heightDest);
104 D(bug("[Decoration] SCALED %d,%d -> %d,%d!\n", widthSrc, heightSrc, widthDest, heightDest));
106 WritePixelArrayAlpha(scaleddata, 0, 0, widthDest * 4, destRP, xDest, yDest, widthDest, heightDest, 0xffffffff);
108 FreeVec(scaleddata);
110 else /* ((widthSrc != widthDest) || (heightSrc != heightDest)) */
112 /* Detect if image can be drawn using blitting instead of alpha draw */
113 if ((!ni->subimageinbm) || (!(ni->subimageinbm[subimageCol + (subimageRow * ni->subimagescols)])))
115 WritePixelArrayAlpha(ni->data, (subimagewidth * subimageCol) + xSrc ,
116 (subimageheight * subimageRow) + ySrc, ni->w * 4, destRP,
117 xDest, yDest, widthSrc, heightSrc, 0xffffffff);
119 else
121 /* LUT */
122 if (ni->bitmap != NULL)
124 if (ni->mask)
126 BltMaskBitMapRastPort(ni->bitmap, (subimagewidth * subimageCol) + xSrc ,
127 (subimageheight * subimageRow) + ySrc, destRP, xDest, yDest,
128 widthSrc, heightSrc, 0xe0, (PLANEPTR) ni->mask);
130 else
132 BltBitMapRastPort(ni->bitmap, (subimagewidth * subimageCol) + xSrc ,
133 (subimageheight * subimageRow) + ySrc, destRP, xDest, yDest,
134 widthSrc, heightSrc, 0xc0);
138 /* Truecolor */
139 if (ni->bitmap2 != NULL)
141 BltBitMapRastPort(ni->bitmap2, (subimagewidth * subimageCol) + xSrc ,
142 (subimageheight * subimageRow) + ySrc, destRP, xDest, yDest,
143 widthSrc, heightSrc, 0xc0);
149 /* HELPER WRAPPERS */
150 static inline void BltNewImageSubImageRastPort(struct NewImage * ni, ULONG subimageCol, ULONG subimageRow,
151 LONG xSrc, LONG ySrc, struct RastPort * destRP, LONG xDest, LONG yDest, LONG widthSrc, LONG heightSrc)
153 BltScaleNewImageSubImageRastPort(ni, subimageCol, subimageRow, xSrc, ySrc, destRP,
154 xDest, yDest, widthSrc, heightSrc, -1, -1);
157 static inline void BltNewImageSubImageRastPortSimple(struct NewImage * ni, ULONG subimageCol, ULONG subimageRow,
158 struct RastPort * destRP, LONG xDest, LONG yDest)
160 BltNewImageSubImageRastPort(ni, subimageCol, subimageRow, 0, 0, destRP,
161 xDest, yDest, -1, -1);
164 static inline void BltScaleNewImageSubImageRastPortSimple(struct NewImage * ni, ULONG subimageCol, ULONG subimageRow,
165 struct RastPort * destRP, LONG xDest, LONG yDest, LONG widthDest, LONG heightDest)
167 BltScaleNewImageSubImageRastPort(ni, subimageCol, subimageRow, 0, 0, destRP,
168 xDest, yDest, -1, -1, widthDest, heightDest);
170 /* HELPER WRAPPERS */
172 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)
175 ULONG dy, dx;
176 LONG dh, height, dw, width;
178 if (src == NULL) return;
179 if (dest == NULL) return;
181 dh = _sh;
182 dy = _dy;
183 height = _dh;
185 while (height > 0)
187 if ((height-dh)<0) dh = height;
188 height -= dh;
189 dw = _sw;
190 width = _dw;
191 dx = _dx;
192 while (width > 0)
194 if ((width-dw)<0) dw = width;
195 width -= dw;
196 DrawPartToImage(src, dest, _sx, _sy, dw, dh, dx, dy);
197 dx += dw;
199 dy += dh;
203 static void TileImageToImageMenuBar(struct NewImage *src, struct TileInfo * srcti, struct NewImage *dest)
205 UWORD y, h;
207 if (dest == NULL) return;
208 if (src == NULL) return;
209 if (srcti == NULL) return;
210 y = 0;
212 h = src->h;
214 if ((srcti->TileTop + srcti->TileBottom) > dest->h) return;
215 if (srcti->TileRight > dest->w) return;
217 DrawTileToImage(src, dest, srcti->TileLeft, y, src->w - srcti->TileLeft - srcti->TileRight, srcti->TileTop, 0, 0, dest->w - srcti->TileRight, srcti->TileTop);
218 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);
219 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);
222 DrawTileToImage(src, dest, src->w - srcti->TileRight, y, srcti->TileRight, srcti->TileTop, dest->w - srcti->TileRight, 0, srcti->TileRight, srcti->TileTop);
223 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);
224 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);
228 static void TileImageToImage(struct NewImage *src, struct TileInfo * srcti, struct NewImage *dest)
230 UWORD y, h;
232 if (dest == NULL) return;
233 if (src == NULL) return;
234 if (srcti == NULL) return;
235 y = 0;
237 h = src->h;
239 if ((srcti->TileTop + srcti->TileBottom) > dest->h) return;
240 if ((srcti->TileLeft + srcti->TileRight) > dest->w) return;
242 DrawTileToImage(src, dest, 0, y, srcti->TileLeft, srcti->TileTop, 0 , 0, srcti->TileLeft, srcti->TileTop);
243 DrawTileToImage(src, dest, 0, y + h - srcti->TileBottom, srcti->TileLeft, srcti->TileBottom, 0 , dest->h - srcti->TileBottom, srcti->TileLeft, srcti->TileBottom);
244 DrawTileToImage(src, dest, src->w - srcti->TileRight, y, srcti->TileRight, srcti->TileTop, dest->w - srcti->TileRight, 0, srcti->TileRight, srcti->TileTop);
245 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);
247 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);
248 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);
249 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);
250 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);
251 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);
254 static void MixImage(struct NewImage *dst, struct NewImage *src, struct TileInfo *srcti, UWORD ratio, UWORD w, UWORD h, UWORD dx, UWORD dy)
256 ULONG *s, *d;
257 ULONG rgba, rgb;
258 UWORD r, g, b;
259 UBYTE as, rs, gs, bs, rd, gd, bd;
260 BOOL tiled = FALSE;
261 int x, y;
263 if (src == NULL) return;
264 if (dst == NULL) return;
266 s = src->data;
267 d = dst->data;
269 if (srcti) tiled = TRUE;
271 for (y = 0; y < h; y++)
273 for (x = 0; x < w; x++)
275 rgba = s[x+y*src->w];
276 as = GET_ARGB_A(rgba);
277 rs = GET_ARGB_R(rgba);
278 gs = GET_ARGB_G(rgba);
279 bs = GET_ARGB_B(rgba);
280 rgb = d[x+dx + (y+dy) * dst->w];
282 rd = GET_ARGB_R(rgb);
283 gd = GET_ARGB_G(rgb);
284 bd = GET_ARGB_B(rgb);
286 r = ((rs * ratio) >> 8) + ((rd * (255 - ratio)) >> 8);
287 g = ((gs * ratio) >> 8) + ((gd * (255 - ratio)) >> 8);
288 b = ((bs * ratio) >> 8) + ((bd * (255 - ratio)) >> 8);
290 if (tiled) {
291 r = ((r * as) >> 8) + ((rd * (255 - as)) >> 8);
292 g = ((g * as) >> 8) + ((gd * (255 - as)) >> 8);
293 b = ((b * as) >> 8) + ((bd * (255 - as)) >> 8);
296 r = r & 0xff;
297 g = g & 0xff;
298 b = b & 0xff;
300 d[x+dx + (y+dy) * dst->w] = SET_ARGB(as, r, g, b);
306 static void BlurSourceAndMixTexture(struct NewImage *pic, struct NewImage *texture, struct TileInfo * textureti, UWORD ratio)
308 int x, y, ytw, t1, t2, b1, b2, l1, l2, r1, r2;
309 UWORD red, green, blue, alpha= 0, rs, gs, bs, as;
310 ULONG rgb, argb;
311 int width, w, height, ah, aw, xpos, ypos;
312 BOOL tiled = FALSE;
313 ULONG *raw, tw, th;
315 if (pic == NULL) return;
316 if (pic->data == NULL) return;
318 tw = pic->w;
319 if (textureti) tiled = TRUE;
320 th = pic->h;
321 raw = pic->data;
322 height = th;
323 width = tw;
325 if (raw)
327 for (y = 0; y < th; y++)
329 t1 = tw;
330 t2 = tw+tw;
331 b1 = tw;
332 b2 = tw+tw;
333 if (y == 0) t1 = t2 = 0;
334 else if (y == 1) t2 = t1;
336 if (y == (th-1)) b1 = b2 = 0;
337 else if (y == (th-2)) b2 = b1;
339 ytw = y*tw;
341 for (x = 0; x < tw; x++)
343 r1 = 1;
344 r2 = 2;
345 l1 = 1;
346 l2 = 2;
348 if (x == 0) l1 = r1 = 0;
349 else if (x == 1) l2 = l1;
351 if (x == (tw-1)) r1 = r2 = 0;
352 else if (x == (tw-2)) r2 = r1;
354 rgb = raw[x+ytw];
355 red = GET_ARGB_R(rgb);
356 green = GET_ARGB_G(rgb);
357 blue = GET_ARGB_B(rgb);
359 rgb = raw[x+ytw-t2];
360 red += GET_ARGB_R(rgb);
361 green += GET_ARGB_G(rgb);
362 blue += GET_ARGB_B(rgb);
364 rgb = raw[x+ytw-l1-t1];
365 red += GET_ARGB_R(rgb);
366 green += GET_ARGB_G(rgb);
367 blue += GET_ARGB_B(rgb);
369 rgb = raw[x+ytw-t1];
370 red += GET_ARGB_R(rgb);
371 green += GET_ARGB_G(rgb);
372 blue += GET_ARGB_B(rgb);
374 rgb = raw[x+ytw-t1];
375 red += GET_ARGB_R(rgb);
376 green += GET_ARGB_G(rgb);
377 blue += GET_ARGB_B(rgb);
379 rgb = raw[x+ytw-t1+r1];
380 red += GET_ARGB_R(rgb);
381 green += GET_ARGB_G(rgb);
382 blue += GET_ARGB_B(rgb);
384 rgb = raw[x+ytw-l2];
385 red += GET_ARGB_R(rgb);
386 green += GET_ARGB_G(rgb);
387 blue += GET_ARGB_B(rgb);
389 rgb = raw[x+ytw-l1];
390 red += GET_ARGB_R(rgb);
391 green += GET_ARGB_G(rgb);
392 blue += GET_ARGB_B(rgb);
394 rgb = raw[x+ytw+r1];
395 red += GET_ARGB_R(rgb);
396 green += GET_ARGB_G(rgb);
397 blue += GET_ARGB_B(rgb);
399 rgb = raw[x+ytw+r2];
400 red += GET_ARGB_R(rgb);
401 green += GET_ARGB_G(rgb);
402 blue += GET_ARGB_B(rgb);
404 rgb = raw[x+ytw+b1-l1];
405 red += GET_ARGB_R(rgb);
406 green += GET_ARGB_G(rgb);
407 blue += GET_ARGB_B(rgb);
409 rgb = raw[x+ytw+b1];
410 red += GET_ARGB_R(rgb);
411 green += GET_ARGB_G(rgb);
412 blue += GET_ARGB_B(rgb);
414 rgb = raw[x+ytw+b1+r1];
415 red += GET_ARGB_R(rgb);
416 green += GET_ARGB_G(rgb);
417 blue += GET_ARGB_B(rgb);
419 rgb = raw[x+ytw+b2];
420 red += GET_ARGB_R(rgb);
421 green += GET_ARGB_G(rgb);
422 blue += GET_ARGB_B(rgb);
424 red = red/14;
425 green = green/14;
426 blue = blue/14;
427 alpha = 255;
429 if (tiled)
431 argb = raw[x+ytw];
432 as = 255 - GET_ARGB_A(texture->data[x + y * texture->w]);
433 rs = GET_ARGB_R(argb);
434 gs = GET_ARGB_G(argb);
435 bs = GET_ARGB_B(argb);
437 red = ((rs * as) >> 8) + ((red * (255 - as)) >> 8);
438 green = ((gs * as) >> 8) + ((green * (255 - as)) >> 8);
439 blue = ((bs * as) >> 8) + ((blue * (255 - as)) >> 8);
441 raw[x+ytw] = SET_ARGB(as, red, green, blue);
444 else
446 raw[x+ytw] = SET_ARGB(alpha, red, green, blue);
451 if (ratio < 100)
453 if (texture)
455 ypos = 0;
456 while (height>0)
458 ah = texture->h;
459 if (ah > height) ah = height;
460 xpos = 0;
461 w = width;
462 while (w>0)
464 aw = texture->w;
465 if (aw > w) aw = w;
466 MixImage(pic, texture, textureti, 255 - (2.55 * ratio), aw, ah, xpos, ypos);
467 w -= aw;
468 xpos += aw;
470 height -= ah;
471 ypos += ah;
477 static void RenderBackgroundTiled(struct NewImage *pic, struct NewImage *texture, struct TileInfo *textureti,
478 UWORD ratio, VOID (*TileImageToImageFunc)(struct NewImage *src, struct TileInfo * srcti, struct NewImage *dest))
480 struct NewImage *ni;
482 if (texture)
484 ni = NewImageContainer(pic->w, pic->h);
485 if (ni)
487 if (textureti)
489 TileImageToImageFunc(texture, textureti, ni);
490 BlurSourceAndMixTexture(pic, ni, textureti, ratio);
492 else BlurSourceAndMixTexture(pic, texture, textureti, ratio);
494 DisposeImageContainer(ni);
496 else BlurSourceAndMixTexture(pic, texture, textureti, ratio);
498 else BlurSourceAndMixTexture(pic, NULL, NULL, ratio);
501 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)
504 ULONG dy, dx;
505 LONG dh, height, dw, width;
507 if (src == NULL) return;
508 if (rp == NULL) return;
510 dh = _sh;
511 dy = _dy;
512 height = _dh;
514 if (!src->ok) return;
516 while (height > 0)
518 if ((height-dh)<0) dh = height;
519 height -= dh;
520 dw = _sw;
521 width = _dw;
522 dx = _dx;
523 while (width > 0)
525 if ((width-dw)<0) dw = width;
526 width -= dw;
528 if (src->mask)
530 BltMaskBitMapRastPort(src->bitmap, _sx, _sy, rp, dx, dy, dw, dh, 0xe0, (PLANEPTR) src->mask);
532 else BltBitMapRastPort(src->bitmap, _sx, _sy, rp, dx, dy, dw, dh, 0xc0);
534 dx += dw;
536 dy += dh;
540 /******************************************************************************/
541 /******************************************************************************/
542 /******************************************************************************/
543 /******************************************************************************/
544 /******************************************************************************/
546 void DrawPartImageToRP(struct RastPort *rp, struct NewImage *ni, UWORD x, UWORD y, UWORD sx, UWORD sy, UWORD sw, UWORD sh)
548 if (ni->ok)
550 if (ni->bitmap == NULL)
552 WritePixelArray(ni->data, sx, sy, ni->w*4, rp, x, y, sw, sh, RECTFMT_ARGB);
554 else
556 BltBitMapRastPort(ni->bitmap, sx, sy, rp, x, y, sw, sh, 0xc0);
561 void DrawPartToImage(struct NewImage *src, struct NewImage *dest, UWORD sx, UWORD sy, UWORD sw, UWORD sh, UWORD dx, UWORD dy)
563 UWORD x, y;
565 for (y = 0; y < sh; y++)
567 for (x = 0; x < sw; x++)
569 dest->data[dx + x + (dy + y) * dest->w] = src->data[sx + x + (sy + y) * src->w];
574 void RenderMenuBackground(struct NewImage *pic, struct NewImage *texture, struct TileInfo *textureti, UWORD ratio)
576 if (texture)
578 if (textureti) RenderBackgroundTiled(pic, texture, textureti, ratio, TileImageToImage);
579 else BlurSourceAndMixTexture(pic, texture, textureti, ratio);
581 else BlurSourceAndMixTexture(pic, NULL, NULL, ratio);
584 void RenderMenuBarBackground(struct NewImage *pic, struct NewImage *texture, struct TileInfo *textureti, UWORD ratio)
586 if (texture && textureti)
589 /* Fill the image with the center tile */
590 DrawTileToImage(texture, pic,
591 textureti->TileLeft, textureti->TileTop,
592 texture->w - textureti->TileLeft - textureti->TileRight, texture->h - textureti->TileBottom - textureti->TileTop,
593 0, 0, pic->w, pic->h);
595 RenderBackgroundTiled(pic, texture, textureti, ratio, TileImageToImageMenuBar);
599 void WriteAlphaPixelArray(struct NewImage *src, struct NewLUT8Image *dst, LONG sx, LONG sy, LONG dx, LONG dy, LONG w, LONG h)
601 ULONG *s = src->data;
602 ULONG argb;
603 UBYTE *d = dst->data;
604 int x, y;
606 for (y = 0; y < h; y++)
608 for (x = 0; x < w; x++)
610 argb = s[sx + x + (sy + y) * src->w];
611 d[dx + x + (dy + y) * dst->w] = GET_ARGB_A(argb);
616 void SetImageTint(struct NewImage *dst, UWORD ratio, ULONG argb)
619 ULONG *d;
620 ULONG rgb;
621 UWORD r, g, b, w, h;
622 UBYTE rs, gs, bs, rd, gd, bd;
623 int x, y;
625 if (dst == NULL) return;
627 d = dst->data;
629 w = dst->w;
630 h = dst->h;
632 rs = (argb >> 16) & 0xff;
633 gs = (argb >> 8) & 0xff;
634 bs = argb & 0xff;
636 for (y = 0; y < h; y++)
638 for (x = 0; x < w; x++)
640 rgb = d[x + y * w];
641 rd = GET_ARGB_R(rgb);
642 gd = GET_ARGB_G(rgb);
643 bd = GET_ARGB_B(rgb);
644 r = ((rs * ratio) >> 8) + ((rd * (255 - ratio)) >> 8);
645 g = ((gs * ratio) >> 8) + ((gd * (255 - ratio)) >> 8);
646 b = ((bs * ratio) >> 8) + ((bd * (255 - ratio)) >> 8);
648 r = r & 0xff;
649 g = g & 0xff;
650 b = b & 0xff;
652 d[x + y * w] = SET_ARGB(255, r, g, b);
658 * offx - offset between start of ni and place where image should be sample from
659 * offy - offset between start of ni and place where image should be sample from
660 * x, y, w, h - coords in rastport rp
662 void HorizVertRepeatNewImage(struct NewImage *ni, ULONG color, UWORD offx, UWORD offy, struct RastPort *rp, UWORD x, UWORD y, WORD w, WORD h)
664 ULONG ow, oh, sy, sx, dy, dx;
665 LONG dh, height, dw, width;
667 if ((w <= 0) || (h <= 0)) return;
669 if (!ni->ok)
671 FillPixelArray(rp, x, y, w, h, color);
672 return;
675 ow = ni->w;
676 oh = ni->h;
678 sy = offy % oh;
679 dh = oh - sy;
680 height = h;
681 dy = y;
682 while (height > 0)
684 if ((height-dh)<0) dh = height;
685 height -= dh;
687 sx = offx % ow;
688 dw = ow - sx;
689 width = w;
690 dx = x;
691 while (width > 0)
693 if ((width-dw)<0) dw = width;
694 width -= dw;
696 BltNewImageSubImageRastPort(ni, 0, 0, sx, sy, rp, dx, dy, dw, dh);
698 dx += dw;
699 sx = 0;
700 dw = ow;
702 dy += dh;
703 sy = 0;
704 dh = oh;
708 /* NOTE: fill parameter is ignored, previously it was forcing a no-alpha blit, but
709 this is already handled in BltNewImageSubImageRastPort */
710 /* dh - destination height to which subimage will be scaled to */
711 LONG WriteTiledImageTitle(BOOL fill, struct Window *win,
712 struct RastPort *rp, struct NewImage *ni, LONG sx, LONG sy, LONG sw,
713 LONG sh, LONG xp, LONG yp, LONG dw, LONG dh)
715 int w = dw;
716 int x = xp;
717 int ddw;
719 if (!ni->ok) return x;
721 if ((sw == 0) || (dw == 0)) return xp;
723 if (win)
725 if (x > win->Width) return xp;
726 if ((x + w) > win->Width) w = win->Width - x;
729 while (w > 0)
731 ddw = sw;
732 if (w < ddw) ddw = w;
734 BltScaleNewImageSubImageRastPort(ni, 0, 0, sx, sy, rp, x, yp, ddw, -1, -1, dh);
736 w -= ddw;
737 x += ddw;
739 return x;
743 * dh - destination height to scale to, -1 to use subimage height
745 LONG WriteVerticalScaledTiledImageHorizontal(struct RastPort *rp, struct NewImage *ni, ULONG subimage,
746 LONG sx, LONG sw, LONG xp, LONG yp, LONG sh, LONG dw, LONG dh)
748 LONG w = dw;
749 LONG x = xp;
750 LONG ddw;
752 if (!ni->ok) return xp;
754 if ((sw == 0) || (dw == 0)) return xp;
756 while (w > 0)
758 ddw = sw;
759 if (w < ddw) ddw = w;
761 BltScaleNewImageSubImageRastPort(ni, 0, subimage, sx, 0, rp, x, yp, ddw, sh, -1, dh);
763 w -= ddw;
764 x += ddw;
767 return x;
770 LONG WriteTiledImageHorizontal(struct RastPort *rp, struct NewImage *ni, ULONG subimage, LONG sx, LONG sw, LONG xp, LONG yp, LONG dw)
772 return WriteVerticalScaledTiledImageHorizontal(rp, ni, subimage, sx, sw, xp, yp, -1, dw, -1);
775 LONG WriteTiledImageVertical(struct RastPort *rp, struct NewImage *ni, ULONG subimage, LONG sy, LONG sh, LONG xp, LONG yp, LONG dh)
777 int h = dh;
778 int y = yp;
779 int ddh;
781 if (!ni->ok) return y;
783 if ((sh == 0) || (dh == 0)) return yp;
785 while (h > 0)
787 ddh = sh;
788 if (h < ddh) ddh = h;
790 BltNewImageSubImageRastPort(ni, subimage, 0, 0, sy, rp, xp, y, -1, ddh);
792 h -= ddh;
793 y += ddh;
795 return y;
798 struct myrgb
800 int red,green,blue;
803 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)
805 /* The basic idea of this algorithm is to calc the intersection between the
806 * diagonal of the rectangle (xs,ys) with dimension (xw,yw) a with the line starting
807 * at (x,y) (every pixel inside the rectangle) and angle angle with direction vector (vx,vy).
809 * Having the intersection point we then know the color of the pixel.
811 * TODO: Turn the algorithm into a incremental one
812 * Remove the use of floating point variables */
813 double rad = angle*M_PI/180;
814 double cosarc = cos(rad);
815 double sinarc = sin(rad);
817 struct myrgb startRGB,endRGB;
819 int diffR, diffG, diffB;
821 int r,t; /* some helper variables to short the code */
822 int l,y,c,x;
823 int y1; /* The intersection point */
824 int incr_y1; /* increment of y1 */
825 int xs,ys,xw,yw;
826 int xadd,ystart,yadd;
827 // double vx = -cosarc;
828 // double vy = sinarc;
829 int vx = (int)(-cosarc*0xff);
830 int vy = (int)(sinarc*0xff);
832 int width = xb - xt + 1;
833 int height = yb - yt + 1;
835 if (buf == NULL) return;
837 startRGB.red = (start_rgb >> 16) & 0xff;
838 startRGB.green = (start_rgb >> 8) & 0xff;
839 startRGB.blue = start_rgb & 0xff;
841 endRGB.red = (end_rgb >> 16) & 0xff;
842 endRGB.green = (end_rgb >> 8) & 0xff;
843 endRGB.blue = end_rgb & 0xff;
845 diffR = endRGB.red - startRGB.red;
846 diffG = endRGB.green - startRGB.green;
847 diffB = endRGB.blue - startRGB.blue;
849 /* Normalize the angle */
850 if (angle < 0) angle = 360 - ((-angle)%360);
851 if (angle >= 0) angle = angle % 360;
853 if (angle <= 90 || (angle > 180 && angle <= 270))
855 /* The to be intersected diagonal goes from the top left edge to the bottom right edge */
856 xs = 0;
857 ys = 0;
858 xw = width;
859 yw = height;
860 } else
862 /* The to be intersected diagonal goes from the bottom left edge to the top right edge */
863 xs = 0;
864 ys = height;
865 xw = width;
866 yw = -height;
869 if (angle > 90 && angle <= 270)
871 /* for these angle we have y1 = height - y1. Instead of
873 * y1 = height - (-vy*(yw* xs -xw* ys) + yw*(vy* x -vx* y)) /(-yw*vx + xw*vy);
875 * we can write
877 * y1 = (-vy*(yw*(-xs)-xw*(-ys+height)) + yw*(vy*(-x)-vx*(-y+height)))/(-yw*vx + xw*vy);
879 * so height - y1 can be expressed with the normal formular adapting some parameters.
881 * Note that if one would exchanging startRGB/endRGB the values would only work
882 * for linear color gradients */
883 xadd = -1;
884 yadd = -1;
885 ystart = height;
887 xs = -xs;
888 ys = -ys + height;
890 else
892 xadd = 1;
893 yadd = 1;
894 ystart = 0;
897 r = -vy*(yw*xs-xw*ys);
898 t = -yw*vx + xw*vy;
900 /* The formular as shown above is
902 * y1 = ((-vy*(yw*xs-xw*ys) + yw*(vy*x-vx*y)) /(-yw*vx + xw*vy));
904 * We see that only yw*(vy*x-vx*y) changes during the loop.
906 * We write
908 * Current Pixel: y1(x,y) = (r + yw*(vy*x-vx*y))/t = r/t + yw*(vy*x-vx*y)/t
909 * Next Pixel: y1(x+xadd,y) = (r + vw*(vy*(x+xadd)-vx*y))/t
911 * t*(y1(x+xadd,y) - y1(x,y)) = yw*(vy*(x+xadd)-vx*y) - yw*(vy*x-vx*y) = yw*vy*xadd; */
913 incr_y1 = yw*vy*xadd;
914 UBYTE *bufptr = buf;
915 for (l = 0, y = ystart + ((yp - yt)* yadd); l < h; l++, y+=yadd)
917 /* Calculate initial y1 accu, can be brought out of the loop as well (x=0). It's probably a
918 * a good idea to add here also a value of (t-1)/2 to ensure the correct rounding
919 * This (and for r) is also a place were actually a overflow can happen |yw|=16 |y|=16. So for
920 * vx nothing is left, currently 9 bits are used for vx or vy */
921 int y1_mul_t_accu = r - yw*vx*y;
925 for (c = 0, x = ((xp - xt) * xadd); c < w; c++, x+=xadd)
927 int red,green,blue;
929 /* Calculate the intersection of two lines, this is not the fastet way to do but
930 * it is intuitive. Note: very slow! Will be optimzed later (remove FFP usage
931 * and making it incremental)...update: it's now incremental and no FFP is used
932 * but it probably can be optimized more by removing some more of the divisions and
933 * further specialize the stuff here (use of three accus). */
934 /* y1 = (int)((-vy*(yw*xs-xw*ys) + yw*(vy*x-vx*y)) /(-yw*vx + xw*vy));*/
935 y1 = y1_mul_t_accu / t;
937 red = startRGB.red + (int)(diffR*y1/height);
938 green = startRGB.green + (int)(diffG*y1/height);
939 blue = startRGB.blue + (int)(diffB*y1/height);
940 /* By using full 32 bits this can be made faster as well */
941 *bufptr++ = red;
942 *bufptr++ = green;
943 *bufptr++ = blue;
945 y1_mul_t_accu += incr_y1;
951 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)
953 UBYTE * buf = NULL;
955 if ((w <= 0) || (h <= 0)) return;
957 /* By bringing building the gradient array in the same format as the RastPort BitMap a call
958 to WritePixelArray() can be made also faster */
959 buf = AllocVec(1 * yb * 3, 0);
961 FillMemoryBufferRGBGradient(buf, pen, xt, yt, xb, yb, xp, yp, 1, yb, start_rgb, end_rgb, angle);
963 HorizRepeatBuffer(buf, dy, pen, tc, rp, xp, yp, w, h);
965 FreeVec(buf);
968 void HorizRepeatBuffer(UBYTE * buf, LONG offy, LONG pen, BOOL tc, struct RastPort *rp, LONG x, LONG y, LONG w, LONG h)
970 UBYTE * bufblit = NULL;
971 ULONG xi, yi;
972 ULONG idxd;
973 ULONG idxs;
975 if ((w <= 0) || (h <= 0)) return;
976 if (!tc)
978 if (pen != -1) SetAPen(rp, pen); else SetAPen(rp, 2);
979 RectFill(rp, x, y, x + w - 1, y + h - 1);
980 return;
983 /* By bringing building the gradient array in the same format as the RastPort BitMap a call
984 to WritePixelArray() can be made also faster */
985 bufblit = AllocVec(w * h * 3, MEMF_ANY);
986 if (!bufblit)
987 return;
989 /* Copy one column buffer into blit buffer */
990 for (yi = 0; yi < h; yi++)
992 idxs = (offy + yi) * 3; /* source index */
993 idxd = yi * 3 * w; /* dest index */
994 for (xi = 0; xi < w; xi++)
996 /* Copy RGB pixel */
997 bufblit[idxd++] = buf[idxs + 0];
998 bufblit[idxd++] = buf[idxs + 1];
999 bufblit[idxd++] = buf[idxs + 2];
1003 WritePixelArray(bufblit, 0, 0, w * 3, rp, x, y, w, h, RECTFMT_RGB);
1005 FreeVec(bufblit);
1008 void TileMapToBitmap(struct NewImage *src, struct TileInfo *srcti, struct BitMap *map, UWORD dw, UWORD dh)
1010 UWORD y, h;
1012 if (map == NULL) return;
1013 if (src == NULL) return;
1014 if (srcti == NULL) return;
1015 y = 0;
1017 h = src->h;
1019 if ((srcti->TileTop + srcti->TileBottom) > dh) return;
1020 if ((srcti->TileLeft + srcti->TileRight) > dw) return;
1022 struct RastPort *dest = CreateRastPort();
1024 if (dest != NULL)
1026 dest->BitMap = map;
1028 DrawMapTileToRP(src, dest, 0, y, srcti->TileLeft, srcti->TileTop, 0 , 0, srcti->TileLeft, srcti->TileTop);
1029 DrawMapTileToRP(src, dest, 0, y + h - srcti->TileBottom, srcti->TileLeft, srcti->TileBottom, 0 , dh - srcti->TileBottom, srcti->TileLeft, srcti->TileBottom);
1030 DrawMapTileToRP(src, dest, src->w - srcti->TileRight, y, srcti->TileRight, srcti->TileTop, dw - srcti->TileRight, 0, srcti->TileRight, srcti->TileTop);
1031 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);
1033 DrawMapTileToRP(src, dest, srcti->TileLeft, y, src->w - srcti->TileLeft - srcti->TileRight, srcti->TileTop, srcti->TileLeft, 0, dw - srcti->TileLeft - srcti->TileRight, srcti->TileTop);
1034 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);
1035 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);
1036 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);
1037 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);
1038 FreeRastPort(dest);
1042 struct NewImage *GetImageFromRP(struct RastPort *rp, UWORD x, UWORD y, UWORD w, UWORD h)
1044 struct NewImage *ni;
1046 ni = NewImageContainer(w, h);
1047 if (ni)
1049 ReadPixelArray(ni->data, 0, 0, w*4, rp, x, y, w, h, RECTFMT_ARGB);
1051 return ni;
1054 void PutImageToRP(struct RastPort *rp, struct NewImage *ni, UWORD x, UWORD y) {
1056 if (ni)
1058 if (ni->data) WritePixelArray(ni->data, 0, 0, ni->w*4, rp, x, y, ni->w, ni->h, RECTFMT_ARGB);
1059 DisposeImageContainer(ni);
1063 ULONG CalcShade(ULONG base, UWORD fact)
1065 int c0, c1, c2, c3;
1067 c0 = GET_ARGB_A(base);
1068 c1 = GET_ARGB_R(base);
1069 c2 = GET_ARGB_G(base);
1070 c3 = GET_ARGB_B(base);
1071 c0 *= fact;
1072 c1 *= fact;
1073 c2 *= fact;
1074 c3 *= fact;
1075 c0 = c0 >> 8;
1076 c1 = c1 >> 8;
1077 c2 = c2 >> 8;
1078 c3 = c3 >> 8;
1080 if (c0 > 255) c0 = 255;
1081 if (c1 > 255) c1 = 255;
1082 if (c2 > 255) c2 = 255;
1083 if (c3 > 255) c3 = 255;
1085 return (ULONG)SET_ARGB(c0, c1, c2, c3);
1088 AROS_UFH3(void, RectShadeFunc,
1089 AROS_UFHA(struct Hook * , h, A0),
1090 AROS_UFHA(struct RastPort * , rp, A2),
1091 AROS_UFHA(struct layerhookmsg *, msg, A1))
1093 AROS_USERFUNC_INIT
1095 #if defined(DECOR_USELINEBUFF)
1096 ULONG *outline = NULL;
1097 UWORD width = 1 + msg->MaxX - msg->MinX;
1098 UWORD height = 1 + msg->MaxY - msg->MinY;
1099 ULONG linesize = 0;
1100 #endif
1101 ULONG color;
1103 HIDDT_Color col;
1104 APTR bm_handle = NULL;
1105 int px, py;
1106 #if !defined(DECOR_FAKESHADE)
1107 int x = 0, y;
1108 struct ShadeData *data = h->h_Data;
1109 #endif
1111 #if defined(DECOR_USELINEBUFF)
1112 if (width > 1)
1113 linesize = width << 2;
1114 else if (height > 1)
1116 #if !defined(DECOR_FAKESHADE)
1117 x = (msg->MinX - msg->OffsetX - rp->Layer->bounds.MinX) % data->ni->h;
1118 #endif
1119 linesize = height << 2;
1122 if (linesize)
1123 outline = AllocMem(linesize, MEMF_ANY);
1124 else
1125 #endif
1127 #if !defined(DECOR_NODIRECT)
1128 bm_handle = LockBitMapTags(rp->BitMap,
1129 TAG_END);
1130 #endif
1133 for (py = msg->MinY; py <= msg->MaxY; py++)
1135 #if !defined(DECOR_FAKESHADE)
1136 y = (py - msg->OffsetY - rp->Layer->bounds.MinY) % data->ni->h;
1137 #endif
1139 #if defined(DECOR_USELINEBUFF)
1140 if (width == 1 && outline)
1142 #if !defined(DECOR_FAKESHADE)
1143 color = CalcShade(data->ni->data[(y * data->ni->w) + x], data->fact);
1144 #else
1145 color = SET_ARGB(00, 0xFF, 0x00, 0x70);
1146 #endif
1147 outline[py - msg->MinY] = color;
1149 continue;
1152 #endif
1153 for (px = msg->MinX; px <= msg->MaxX; px++)
1155 #if !defined(DECOR_FAKESHADE)
1156 x = (px - msg->OffsetX - rp->Layer->bounds.MinX) % data->ni->w;
1158 color = CalcShade(data->ni->data[(y * data->ni->w) + x], data->fact);
1159 #else
1160 color = SET_ARGB(00, 0xFF, 0x00, 0x70);
1161 #endif
1163 #if defined(DECOR_USELINEBUFF)
1164 if (outline)
1166 outline[px - msg->MinX] = color;
1168 else
1169 #endif
1170 if (bm_handle)
1172 col.alpha = (HIDDT_ColComp) GET_ARGB_A(color) << 8;
1173 col.red = (HIDDT_ColComp) GET_ARGB_R(color) << 8;
1174 col.green = (HIDDT_ColComp) GET_ARGB_G(color) << 8;
1175 col.blue = (HIDDT_ColComp) GET_ARGB_B(color) << 8;
1177 HIDD_BM_PutPixel(HIDD_BM_OBJ(rp->BitMap), px, py, HIDD_BM_MapColor(HIDD_BM_OBJ(rp->BitMap), &col));
1179 else
1181 WriteRGBPixel(rp,
1182 msg->OffsetX + (px - msg->MinX),
1183 msg->OffsetY + (py - msg->MinY),
1184 #if AROS_BIG_ENDIAN
1185 color);
1186 #else
1187 SET_ARGB(GET_ARGB_B(color), GET_ARGB_G(color), GET_ARGB_R(color), GET_ARGB_A(color)));
1188 #endif
1191 #if defined(DECOR_USELINEBUFF)
1192 if (outline && (width > 1))
1194 WritePixelArray(outline,
1195 0, 0,
1196 linesize,
1198 msg->OffsetX,
1199 msg->OffsetY + (py - msg->MinY),
1200 width, 1,
1201 #if AROS_BIG_ENDIAN
1202 RECTFMT_ARGB);
1203 #else
1204 RECTFMT_BGRA32);
1205 #endif
1207 #endif
1210 #if defined(DECOR_USELINEBUFF)
1211 if (outline)
1213 if (width == 1)
1215 WritePixelArray(outline,
1216 0, 0,
1217 sizeof(ULONG),
1219 msg->OffsetX,
1220 msg->OffsetY,
1221 1, height,
1222 #if AROS_BIG_ENDIAN
1223 RECTFMT_ARGB);
1224 #else
1225 RECTFMT_BGRA32);
1226 #endif
1228 FreeMem(outline, linesize);
1230 else
1231 #endif
1232 if (bm_handle)
1234 struct RectList bm_rectlist;
1235 struct TagItem bm_ultags[3] =
1237 {UBMI_REALLYUNLOCK, TRUE },
1238 {UBMI_UPDATERECTS, (IPTR)&bm_rectlist },
1239 {TAG_DONE, 0 }
1242 bm_rectlist.rl_num = 1;
1243 bm_rectlist.rl_next = (struct RectList *)0;
1244 bm_rectlist.rl_rect.MinX = msg->MinX;
1245 bm_rectlist.rl_rect.MinY = msg->MinY;
1246 bm_rectlist.rl_rect.MaxX = msg->MaxX;
1247 bm_rectlist.rl_rect.MaxY = msg->MaxY;
1249 UnLockBitMapTagList(bm_handle, bm_ultags);
1252 AROS_USERFUNC_EXIT
1255 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)
1257 ULONG color;
1259 if ((x1 < x0) || (y1 < y0)) return;
1260 if (!tc)
1262 SetAPen(rp, pen);
1263 Move(rp, x0, y0);
1264 Draw(rp, x1, y1);
1265 return;
1267 if (usegradients)
1269 color = CalcShade(
1270 #if AROS_BIG_ENDIAN
1271 basecolor,
1272 #else
1273 SET_ARGB(GET_ARGB_B(basecolor), GET_ARGB_G(basecolor), GET_ARGB_R(basecolor), GET_ARGB_A(basecolor)),
1274 #endif
1275 fact);
1277 SetRPAttrs(rp, RPTAG_PenMode, FALSE, RPTAG_FgColor, color, TAG_DONE);
1278 Move(rp, x0, y0);
1279 Draw(rp, x1, y1);
1281 else if (ni->ok)
1283 struct ShadeData shadeParams;
1284 struct Hook shadeHook;
1285 struct Rectangle shadeRect;
1287 shadeRect.MinX = x0;
1288 shadeRect.MaxX = x1;
1289 shadeRect.MinY = y0;
1290 shadeRect.MaxY = y1;
1292 shadeParams.ni = ni;
1293 shadeParams.fact = fact;
1295 shadeHook.h_Entry = (HOOKFUNC)AROS_ASMSYMNAME(RectShadeFunc);
1296 shadeHook.h_Data = &shadeParams;
1298 DoHookClipRects(&shadeHook, rp, &shadeRect);
1300 else
1302 Move(rp, x0, y0);
1303 Draw(rp, x1, y1);
1307 void DrawScaledStatefulGadgetImageToRP(struct RastPort *rp, struct NewImage *ni, ULONG state, UWORD xp, UWORD yp,
1308 WORD scaledwidth, WORD scaledheight)
1311 UWORD subimagecol = 0;
1312 UWORD subimagerow = 0;
1314 if (ni->ok)
1316 switch(state)
1318 case IDS_NORMAL:
1319 break;
1320 case IDS_SELECTED:
1321 subimagecol = 1;
1322 break;
1323 case IDS_INACTIVENORMAL:
1324 subimagecol = 2;
1325 break;
1328 BltScaleNewImageSubImageRastPortSimple(ni, subimagecol, subimagerow, rp, xp, yp, scaledwidth, scaledheight);
1332 void DrawStatefulGadgetImageToRP(struct RastPort *rp, struct NewImage *ni, ULONG state, UWORD xp, UWORD yp)
1334 DrawScaledStatefulGadgetImageToRP(rp, ni, state, xp, yp, -1, -1);