Updated PCI IDs to latest snapshot.
[tangerine.git] / workbench / hidds / graphics / BM_Class.c
blobaa312d0fb4ff01325f54166947a9967b0ca25274
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Graphics bitmap class implementation.
6 Lang: english
7 */
9 /****************************************************************************************/
11 #include <string.h>
12 #include <stdlib.h>
14 #include <proto/exec.h>
15 #include <proto/utility.h>
16 #include <proto/oop.h>
18 #include <exec/memory.h>
19 #include <utility/tagitem.h>
20 #include <oop/oop.h>
21 #include <graphics/text.h>
22 #include <graphics/scale.h>
24 #include <hidd/graphics.h>
26 #include "graphics_intern.h"
28 #undef SDEBUG
29 #undef DEBUG
30 #define SDEBUG 0
31 #define DEBUG 0
32 #include <aros/debug.h>
34 /****************************************************************************************/
36 #define POINT_OUTSIDE_CLIP(gc, x, y) \
37 ( (x) < GC_CLIPX1(gc) \
38 || (x) > GC_CLIPX2(gc) \
39 || (y) < GC_CLIPY1(gc) \
40 || (y) > GC_CLIPY2(gc) )
44 /* BitMap baseclass is a in C++ terminology a pure virtual
45 baseclass. It will not allocate any bitmap data at all,
46 that is up to the subclass to do.
48 The main task of the BitMap baseclass is to store
50 There are two ways the we can find out the pixfmt:
52 Displayable bitmap -
53 The tags will contrain a modeid.
54 One can use this modeid to get a pointer to an
55 allready registered pixfmt.
57 Non-displayable bitmap -
58 The aHidd_BitMap_StdPixFmt attribute will allways be passed
63 /****************************************************************************************/
65 #define GOT_BM_ATTR(code) GOT_ATTR(code, aoHidd_BitMap, bitmap)
66 #define AO(x) aoHidd_BitMap_ ## x
68 #define BMAF(x) (1L << aoHidd_BitMap_ ## x)
70 #define BM_NONDISP_AF ( BMAF(Width) | BMAF(Height) | BMAF(PixFmt) )
73 #define PIXBUFBYTES (50000*4)
75 #define PIXBUF_DECLARE_VARS \
76 LONG __buflines; \
77 LONG __bufy = 0; \
78 LONG __worky = 0; \
79 LONG __height;
81 #define PIXBUF_ALLOC(buf,bytesperline,height) \
82 __height = height; \
83 __buflines = PIXBUFBYTES / (bytesperline); \
84 if (__buflines == 0) \
85 { \
86 __buflines = 1; \
87 } \
88 else if (__buflines > __height) \
89 { \
90 __buflines = __height; \
91 } \
92 buf = AllocVec((bytesperline) * __buflines, MEMF_PUBLIC); \
93 if (!buf && (__buflines > 1)) \
94 { \
95 __buflines = 1; \
96 buf = AllocVec((bytesperline), MEMF_PUBLIC); \
99 #define PIXBUF_TIME_TO_START_PROCESS (__bufy == __worky)
101 #define PIXBUF_LINES_TO_PROCESS (((__height - __bufy) > __buflines) ? \
102 __buflines : __height - __bufy )
104 #define PIXBUF_TIME_TO_END_PROCESS (((__worky - __bufy + 1) == __buflines) || \
105 (__worky == __height - 1))
107 #define PIXBUF_NEXT_LINE \
108 __worky++; \
109 if ((__worky - __bufy) == __buflines) __bufy = __worky;
112 #define PIXBUF_FREE(buf) \
113 if (buf) FreeVec(buf);
115 /****************************************************************************************/
117 OOP_Object *BM__Root__New(OOP_Class *cl, OOP_Object *obj, struct pRoot_New *msg)
119 EnterFunc(bug("BitMap::New()\n"));
121 obj = (OOP_Object *) OOP_DoSuperMethod(cl, obj, (OOP_Msg) msg);
123 if (NULL != obj)
125 struct TagItem colmap_tags[] =
127 { aHidd_ColorMap_NumEntries , 16 },
128 { TAG_DONE }
130 struct HIDDBitMapData *data;
131 BOOL ok = TRUE;
133 DECLARE_ATTRCHECK(bitmap);
134 IPTR attrs[num_Total_BitMap_Attrs];
136 data = OOP_INST_DATA(cl, obj);
138 /* clear all data and set some default values */
139 memset(data, 0, sizeof(struct HIDDBitMapData));
141 data->width = 320;
142 data->height = 200;
143 data->reqdepth = 8;
144 data->displayable = FALSE;
145 data->pf_registered = FALSE;
146 data->modeid = vHidd_ModeID_Invalid;
148 if (0 != OOP_ParseAttrs(msg->attrList, attrs, num_Total_BitMap_Attrs,
149 &ATTRCHECK(bitmap), HiddBitMapAttrBase))
151 D(bug("!!! ERROR PARSING ATTRS IN BitMap::New() !!!\n"));
152 D(bug("!!! NUMBER OF ATTRS IN IF: %d !!!\n", num_Total_BitMap_Attrs));
153 ok = FALSE;
156 if (ok)
158 if (!GOT_BM_ATTR(GfxHidd) || !GOT_BM_ATTR(Displayable))
160 D(bug("!!!! BM CLASS DID NOT GET GFX HIDD !!!\n"));
161 D(bug("!!!! The reason for this is that the gfxhidd subclass NewBitmap() method\n"));
162 D(bug("!!!! has not left it to the baseclass to avtually create the object,\n"));
163 D(bug("!!!! but rather done it itself. This MUST be corrected in the gfxhidd subclass\n"));
164 D(bug("!!!! ATTRCHECK: %p !!!!\n", ATTRCHECK(bitmap)));
166 ok = FALSE;
168 else
170 data->gfxhidd = (OOP_Object *)attrs[AO(GfxHidd)];
174 /* Save pointer to friend bitmap */
175 if (GOT_BM_ATTR(Friend))
176 data->friend = (OOP_Object *)attrs[AO(Friend)];
178 if (ok)
180 if ( attrs[AO(Displayable)] )
182 /* We should allways get modeid, but we check anyway */
183 if (!GOT_BM_ATTR(ModeID))
185 D(bug("!!! BitMap:New() DID NOT GET MODEID FOR DISPLAYABLE BITMAP !!!\n"));
186 ok = FALSE;
188 else
190 HIDDT_ModeID modeid;
191 OOP_Object *sync, *pf;
193 modeid = (HIDDT_ModeID)attrs[AO(ModeID)];
195 if (!HIDD_Gfx_GetMode(data->gfxhidd, modeid, &sync, &pf))
197 D(bug("!!! BitMap::New() RECEIVED INVALID MODEID %p\n", modeid));
198 ok = FALSE;
200 else
202 IPTR width, height;
204 /* Update the bitmap with data from the modeid */
205 OOP_GetAttr(sync, aHidd_Sync_HDisp, &width);
206 OOP_GetAttr(sync, aHidd_Sync_VDisp, &height);
208 data->width = width;
209 data->height = height;
210 data->displayable = TRUE;
212 /* The PixFmt is allready registered and locked in the PixFmt database */
213 data->prot.pixfmt = pf;
217 else
218 { /* displayable */
219 if (BM_NONDISP_AF != (BM_NONDISP_AF & ATTRCHECK(bitmap)))
221 if (OOP_OCLASS(obj) != CSD(cl)->planarbmclass)
223 /* HACK. This is an ugly hack to allow the
224 late initialization of BitMap objects in AROS.
226 The PixelFormat will be set later.
229 #warning Find a better way to do this.
231 /* One could maybe fix this by implementing a separate AmigaPitMap class
234 D(bug("!!! BitMap:New(): NO PIXFMT FOR NONDISPLAYABLE BITMAP !!!\n"));
235 ok = FALSE;
238 else
240 data->width = attrs[AO(Width)];
241 data->height = attrs[AO(Height)];
242 data->prot.pixfmt = (OOP_Object *)attrs[AO(PixFmt)];
245 } /* displayable */
247 } /* if (ok) */
249 if (ok)
251 /* initialize the direct method calling */
253 if (GOT_BM_ATTR(ModeID))
254 data->modeid = attrs[AO(ModeID)];
256 #if USE_FAST_PUTPIXEL
257 data->putpixel = (IPTR (*)(OOP_Class *, OOP_Object *, struct pHidd_BitMap_PutPixel *))
258 OOP_GetMethod(obj, CSD(cl)->putpixel_mid);
259 if (NULL == data->putpixel)
260 ok = FALSE;
261 #endif
263 #if USE_FAST_GETPIXEL
264 data->getpixel = (IPTR (*)(OOP_Class *, OOP_Object *, struct pHidd_BitMap_GetPixel *))
265 OOP_GetMethod(obj, CSD(cl)->getpixel_mid);
266 if (NULL == data->getpixel)
267 ok = FALSE;
268 #endif
270 #if USE_FAST_DRAWPIXEL
271 data->drawpixel = (IPTR (*)(OOP_Class *, OOP_Object *, struct pHidd_BitMap_DrawPixel *))
272 OOP_GetMethod(obj, CSD(cl)->drawpixel_mid);
273 if (NULL == data->drawpixel)
274 ok = FALSE;
275 #endif
277 /* Try to create the colormap */
279 /* stegerg: Only add a ColorMap for a visible bitmap (screen). This
280 is important because one can create for example a bitmap
281 in PIXFMT_LUT8 without friend bitmap and then copy this
282 bitmap to a 16 bit screen. During copy the screen bitmap
283 CLUT must be used, which would not happen if our PIXFMT_LUT8
284 also had a colormap itself because then bltbitmap would use the
285 colormap of the PIXFMT_LUT8 bitmap as lookup, which in this
286 case would just cause everything to become black in the
287 destination (screen) bitmap, because noone ever sets up the
288 colormap of the PIXFMT_LUT8 bitmap */
290 if (data->displayable)
292 data->colmap = OOP_NewObject(NULL, CLID_Hidd_ColorMap, colmap_tags);
293 if (NULL == data->colmap)
294 ok = FALSE;
299 if (!ok)
301 ULONG dispose_mid;
303 dispose_mid = OOP_GetMethodID(IID_Root, moRoot_Dispose);
305 OOP_CoerceMethod(cl, obj, (OOP_Msg)&dispose_mid);
307 obj = NULL;
309 } /* if(obj) */
311 } /* if (NULL != obj) */
313 ReturnPtr("BitMap::New", OOP_Object *, obj);
316 /****************************************************************************************/
318 void BM__Root__Dispose(OOP_Class *cl, OOP_Object *obj, OOP_Msg *msg)
320 struct HIDDBitMapData *data = OOP_INST_DATA(cl, obj);
322 EnterFunc(bug("BitMap::Dispose()\n"));
324 if (NULL != data->colmap)
325 OOP_DisposeObject(data->colmap);
327 D(bug("Calling super\n"));
329 /* Release the previously registered pixel format */
330 if (data->pf_registered)
331 HIDD_Gfx_ReleasePixFmt(data->gfxhidd, data->prot.pixfmt);
333 OOP_DoSuperMethod(cl, obj, (OOP_Msg) msg);
335 ReturnVoid("BitMap::Dispose");
338 /****************************************************************************************/
340 VOID BM__Root__Get(OOP_Class *cl, OOP_Object *obj, struct pRoot_Get *msg)
342 struct HIDDBitMapData *data = OOP_INST_DATA(cl, obj);
343 ULONG idx;
345 EnterFunc(bug("BitMap::Get() attrID: %i storage: %p\n", msg->attrID, msg->storage));
347 if(IS_BITMAP_ATTR(msg->attrID, idx))
349 switch(idx)
351 case aoHidd_BitMap_Width:
352 *msg->storage = data->width;
353 D(bug(" width: %i\n", data->width));
354 break;
356 case aoHidd_BitMap_Height:
357 *msg->storage = data->height;
358 break;
360 case aoHidd_BitMap_Displayable:
361 *msg->storage = (IPTR) data->displayable;
362 break;
364 case aoHidd_BitMap_PixFmt:
365 *msg->storage = (IPTR)data->prot.pixfmt;
366 break;
368 case aoHidd_BitMap_Friend:
369 *msg->storage = (IPTR)data->friend;
370 break;
372 case aoHidd_BitMap_ColorMap:
373 *msg->storage = (IPTR)data->colmap;
374 break;
376 #if 0
377 case aoHidd_BitMap_Depth:
378 if (NULL != data->prot.pixfmt)
380 *msg->storage = ((HIDDT_PixelFormat *)data->prot.pixfmt)->depth;
382 else
384 *msg->storage = data->reqdepth;
386 break;
388 #endif
390 case aoHidd_BitMap_GfxHidd:
391 *msg->storage = (IPTR)data->gfxhidd;
392 break;
394 case aoHidd_BitMap_ModeID:
395 *msg->storage = data->modeid;
396 break;
398 case aoHidd_BitMap_BytesPerRow:
400 HIDDT_PixelFormat *pf;
402 pf = (HIDDT_PixelFormat *)data->prot.pixfmt;
404 *msg->storage = pf->bytes_per_pixel * data->width;
405 break;
408 default:
409 D(bug("UNKNOWN ATTR IN BITMAP BASECLASS: %d\n", idx));
410 OOP_DoSuperMethod(cl, obj, (OOP_Msg) msg);
411 break;
414 else
416 OOP_DoSuperMethod(cl, obj, (OOP_Msg) msg);
419 ReturnVoid("BitMap::Get");
422 /****************************************************************************************/
424 #define UB(x) ((UBYTE *)x)
426 /****************************************************************************************/
428 BOOL BM__Hidd_BitMap__SetColors(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_SetColors *msg)
430 /* Copy the colors into the internal buffer */
431 struct HIDDBitMapData *data;
433 data = OOP_INST_DATA(cl, o);
435 /* Subclass has initialized HIDDT_Color->pixelVal field and such.
436 Just copy it into the colortab.
439 if (NULL == data->colmap)
441 struct TagItem colmap_tags[] =
443 { aHidd_ColorMap_NumEntries, 0 },
444 { TAG_DONE }
447 colmap_tags[0].ti_Data = msg->firstColor + msg->numColors;
448 data->colmap = OOP_NewObject(NULL, CLID_Hidd_ColorMap, colmap_tags);
451 if (NULL == data->colmap)
453 return FALSE;
456 /* Use the colormap class to set the colors */
457 return HIDD_CM_SetColors(data->colmap, msg->colors,
458 msg->firstColor, msg->numColors,
459 data->prot.pixfmt);
463 /*****************************************************************************************
465 BitMap::DrawPixel()
467 NAME
468 moHidd_BitMap_DrawPixel
470 SYNOPSIS
471 OOP_DoMethod(obj, WORD x, WORD y);
474 FUNCTION
475 Changes the pixel at (x,y). The color of the pixel depends on the
476 attributes of gc, eg. colors, drawmode, colormask etc.
477 This function does not the coordinates.
479 INPUTS
480 (x,y) - coordinates of the pixel in hidd units
482 RESULT
484 NOTES
486 EXAMPLE
488 BUGS
490 SEE ALSO
491 GROUP=HIDD_Gfx_Pixel, GROUP=HIDD_Gfx_SetAttributes
493 INTERNALS
495 TODO
496 - Support for shapeplane.
497 - Optimize
499 *****************************************************************************************/
501 ULONG BM__Hidd_BitMap__DrawPixel(OOP_Class *cl, OOP_Object *obj,
502 struct pHidd_BitMap_DrawPixel *msg)
504 HIDDT_Pixel src, dest, val;
505 HIDDT_DrawMode mode;
506 HIDDT_Pixel writeMask;
507 OOP_Object *gc;
508 #if USE_FAST_PUTPIXEL
509 struct pHidd_BitMap_PutPixel p;
510 #endif
512 /* EnterFunc(bug("BitMap::DrawPixel() x: %i, y: %i\n", msg->x, msg->y));
515 Example: Pixels which bits are set to 0 in the colMask must be
516 unchanged
518 data->colMask = 001111
519 dest = 101100
522 writeMask = ~data->colMask & dest
523 = 110000 & 101100
524 = 100000
526 dest = data->fg && dest = 010100
529 dest = dest & (writeMask | data->ColMask)
530 = 010100 & (100000 | 001111)
531 = 010100 & (101111)
532 = 000100
535 dest = dest | writeMask;
536 = 000100 100000
537 = 100100
541 gc = msg->gc;
543 src = GC_FG(gc);
544 mode = GC_DRMD(gc);
546 #if OPTIMIZE_DRAWPIXEL_FOR_COPY
547 if (vHidd_GC_DrawMode_Copy == mode && GC_COLMASK(gc) == ~0)
549 val = src;
551 else
553 #endif
555 dest = HIDD_BM_GetPixel(obj, msg->x, msg->y);
556 writeMask = ~GC_COLMASK(gc) & dest;
558 val = 0;
560 if(mode & 1) val = ( src & dest);
561 if(mode & 2) val = ( src & ~dest) | val;
562 if(mode & 4) val = (~src & dest) | val;
563 if(mode & 8) val = (~src & ~dest) | val;
565 val = (val & (writeMask | GC_COLMASK(gc) )) | writeMask;
567 #if OPTIMIZE_DRAWPIXEL_FOR_COPY
569 #endif
571 #if USE_FAST_PUTPIXEL
572 p.mID = CSD(cl)->putpixel_mid;
573 p.x = msg->x;
574 p.y = msg->y;
575 p.pixel = val;
576 PUTPIXEL(obj, &p);
577 #else
579 HIDD_BM_PutPixel(obj, msg->x, msg->y, val);
580 #endif
582 /* ReturnInt("BitMap::DrawPixel ", ULONG, 1); */ /* in quickmode return always 1 */
584 return 1;
587 /*****************************************************************************************
589 BitMap::DrawLine()
591 NAME
592 DrawLine
594 SYNOPSIS
595 OOP_DoMethod(obj, WORD x1, WORD y1, WORD x2, WORD y2);
597 FUNCTION
598 Draws a line from (x1,y1) to (x2,y2) in the specified gc.
599 The function does not clip the line against the drawing area.
601 x1,y1 - start point of the line in hidd units
602 x2,y2 - end point of the line in hidd units
604 RESULT
606 NOTES
608 EXAMPLE
610 BUGS
612 SEE ALSO
613 GROUP=HIDD_Pixel
615 INTERNALS
616 Uses midpoint line ("Bresenham") algorithm([FOL90] 3.2.2)
618 TODO Support for line pattern
619 Optimize remove if t == 1 ...
620 Implement better clipping: Should be no reason to calculate
621 more than the part of the line that is inside the cliprect
623 HISTORY
625 *****************************************************************************************/
627 VOID BM__Hidd_BitMap__DrawLine
629 OOP_Class *cl, OOP_Object *obj, struct pHidd_BitMap_DrawLine *msg
632 WORD dx, dy, incrE, incrNE, d, x, y, s1, s2, t, i;
633 LONG x1, y1, x2, y2;
634 UWORD maskLine; /* for line pattern */
635 ULONG fg; /* foreground pen */
636 BOOL doclip;
637 BOOL opaque;
638 OOP_Object *gc;
641 /* bug("BitMap::DrawLine()\n");
642 */ EnterFunc(bug("BitMap::DrawLine() x1: %i, y1: %i x2: %i, y2: %i\n", msg->x1, msg->y1, msg->x2, msg->y2));
644 gc = msg->gc;
645 doclip = GC_DOCLIP(gc);
646 opaque = (GC_COLEXP(gc) & vHidd_GC_ColExp_Opaque) ? TRUE : FALSE;
647 fg = GC_FG(gc);
649 maskLine = 1 << GC_LINEPATCNT(gc);
651 if (doclip)
653 /* If line is not inside cliprect, then just return */
654 /* Normalize coords */
655 if (msg->x1 > msg->x2)
657 x1 = msg->x2; x2 = msg->x1;
659 else
661 x1 = msg->x1; x2 = msg->x2;
664 if (msg->y1 > msg->y2)
666 y1 = msg->y2; y2 = msg->y1;
668 else
670 y1 = msg->y1; y2 = msg->y2;
673 if ( x1 > GC_CLIPX2(gc)
674 || x2 < GC_CLIPX1(gc)
675 || y1 > GC_CLIPY2(gc)
676 || y2 < GC_CLIPY1(gc) )
679 /* Line is not inside cliprect, so just return */
680 return;
685 x1 = msg->x1;
686 y1 = msg->y1;
687 x2 = msg->x2;
688 y2 = msg->y2;
690 if (y1 == y2)
693 Horizontal line drawing code.
695 y = y1;
697 /* Don't swap coordinates if x2 < x1! Because of linepattern! */
699 if (x1 < x2)
701 x2++;
702 dx = 1;
704 else
706 x2--;
707 dx = -1;
710 for(i = x1; i != x2; i += dx)
712 /* Pixel inside ? */
714 if (!doclip || !POINT_OUTSIDE_CLIP(gc, i, y ))
716 if(GC_LINEPAT(gc) & maskLine)
718 HIDD_BM_DrawPixel(obj, gc, i, y);
720 else if (opaque)
722 GC_FG(gc) = GC_BG(gc);
723 HIDD_BM_DrawPixel(obj, gc, i, y);
724 GC_FG(gc) = fg;
728 maskLine = maskLine >> 1;
729 if (!maskLine) maskLine = 1L << 15;
732 else if (x1 == x2)
735 Vertical line drawing code.
737 x = x1;
739 /* Don't swap coordinates if y2 < y1! Because of linepattern! */
741 if (y1 < y2)
743 y2++;
744 dy = 1;
746 else
748 y2--;
749 dy = -1;
752 for(i = y1; i != y2; i += dy)
754 /* Pixel inside ? */
755 if (!doclip || !POINT_OUTSIDE_CLIP(gc, x, i ))
757 if(GC_LINEPAT(gc) & maskLine)
759 HIDD_BM_DrawPixel(obj, gc, x, i);
761 else if (opaque)
763 GC_FG(gc) = GC_BG(gc);
764 HIDD_BM_DrawPixel(obj, gc, x, i);
765 GC_FG(gc) = fg;
769 maskLine = maskLine >> 1;
770 if (!maskLine) maskLine = 1L << 15;
774 else
777 Generic line drawing code.
779 /* Calculate slope */
780 dx = abs(x2 - x1);
781 dy = abs(y2 - y1);
783 /* which direction? */
784 if((x2 - x1) > 0) s1 = 1; else s1 = - 1;
785 if((y2 - y1) > 0) s2 = 1; else s2 = - 1;
787 /* change axes if dx < dy */
788 if(dx < dy)
790 d = dx;
791 dx = dy;
792 dy = d;
793 t = 0;
795 else
797 t = 1;
800 d = 2 * dy - dx; /* initial value of d */
802 incrE = 2 * dy; /* Increment use for move to E */
803 incrNE = 2 * (dy - dx); /* Increment use for move to NE */
805 x = x1; y = y1;
807 for(i = 0; i <= dx; i++)
809 /* Pixel inside ? */
810 if (!doclip || !POINT_OUTSIDE_CLIP(gc, x, y ))
812 if(GC_LINEPAT(gc) & maskLine)
814 HIDD_BM_DrawPixel(obj, gc, x, y);
816 else if (opaque)
818 GC_FG(gc) = GC_BG(gc);
819 HIDD_BM_DrawPixel(obj, gc, x, y);
820 GC_FG(gc) = fg;
824 if(d <= 0)
826 if(t == 1)
828 x = x + s1;
830 else
832 y = y + s2;
835 d = d + incrE;
837 else
839 x = x + s1;
840 y = y + s2;
841 d = d + incrNE;
844 maskLine = maskLine >> 1;
845 if (!maskLine) maskLine = 1L << 15;
850 ReturnVoid("BitMap::DrawLine ");
853 /*****************************************************************************************
855 BitMap::DrawRect()
857 NAME
858 DrawRect
860 SYNOPSIS
861 OOP_DoMethod(obj, WORD minX, WORD minY, WORD maxX, WORD maxY);
863 FUNCTION
865 Draws a hollow rectangle from. minX and minY specifies the upper
866 left corner of the rectangle. minY and maxY specifies the lower
867 right corner of the rectangle.
868 The function does not clip the rectangle against the drawing area.
870 INPUTS
871 minX, minY - upper left corner of the rectangle in hidd units
872 maxX, maxY - lower right corner of the rectangle in hidd units
874 RESULT
876 NOTES
878 EXAMPLE
880 BUGS
882 SEE ALSO
883 GROUP=HIDD_Rectangle
885 INTERNALS
887 TODO
889 HISTORY
891 *****************************************************************************************/
893 VOID BM__Hidd_BitMap__DrawRect(OOP_Class *cl, OOP_Object *obj,
894 struct pHidd_BitMap_DrawRect *msg)
896 OOP_Object *gc = msg->gc;
897 WORD addX, addY;
899 EnterFunc(bug("BitMap::DrawRect()"));
901 if(msg->minX == msg->maxX) addX = 0; else addX = 1;
902 if(msg->minY == msg->maxY) addY = 0; else addY = 1;
904 HIDD_BM_DrawLine(obj, gc, msg->minX, msg->minY , msg->maxX, msg->minY);
905 HIDD_BM_DrawLine(obj, gc, msg->maxX, msg->minY + addY, msg->maxX, msg->maxY);
906 HIDD_BM_DrawLine(obj, gc, msg->maxX - addX, msg->maxY, msg->minX, msg->maxY);
907 HIDD_BM_DrawLine(obj, gc, msg->minX, msg->maxY - addY, msg->minX, msg->minY + addY);
909 ReturnVoid("BitMap::DrawRect");
912 /*****************************************************************************************
914 BitMap::FillRect()
916 NAME
917 FillRect
919 SYNOPSIS
920 OOP_DoMethod(obj, WORD minX, WORD minY, WORD maxX, WORD maxY);
922 FUNCTION
924 Draws a solid rectangle. minX and minY specifies the upper
925 left corner of the rectangle. minY and maxY specifies the lower
926 right corner of the rectangle.
927 The function does not clip the rectangle against the drawing area.
929 INPUTS
930 minX, minY - upper left corner of the rectangle in hidd units
931 maxX, maxY - lower right corner of the rectangle in hidd units
933 RESULT
935 NOTES
937 EXAMPLE
939 BUGS
941 SEE ALSO
942 GROUP=HIDD_Rectangle
944 INTERNALS
946 TODO
947 Fill with pattern
949 HISTORY
951 *****************************************************************************************/
953 VOID BM__Hidd_BitMap__FillRect(OOP_Class *cl, OOP_Object *obj,
954 struct pHidd_BitMap_DrawRect *msg)
956 OOP_Object *gc = msg->gc;
957 WORD y = msg->minY;
958 UWORD linepat;
960 EnterFunc(bug("BitMap::FillRect()"));
962 linepat = GC_LINEPAT(gc);
963 GC_LINEPAT(gc) = ~0;
965 for(; y <= msg->maxY; y++)
967 HIDD_BM_DrawLine(obj, gc, msg->minX, y, msg->maxX, y);
970 GC_LINEPAT(gc) = linepat;
972 ReturnVoid("BitMap::FillRect");
975 /*****************************************************************************************
977 BitMap::DrawEllipse()
979 NAME
980 DrawEllipse
982 SYNOPSIS
983 OOP_DoMethod(obj, WORD x, WORD y, UWORD rx, UWORD ry);
985 FUNCTION
986 Draws a hollow ellipse from the center point (x/y) with the radii
987 rx and ry in the specified bitmap.
988 The function does not clip the ellipse against the drawing area.
990 INPUTS
991 x,y - center point in hidd units
992 rx,ry - ry and ry radius in hidd units
994 RESULT
996 NOTES
998 EXAMPLE
1000 BUGS
1001 Because of overflow the current code do not work with big
1002 values of rx and ry.
1004 SEE ALSO
1005 GROUP=HIDD_Ellipse
1007 INTERNALS
1009 TODO
1010 Bugfix
1012 HISTORY
1014 *****************************************************************************************/
1016 #warning Try to opimize clipping here
1018 VOID BM__Hidd_BitMap__DrawEllipse(OOP_Class *cl, OOP_Object *obj,
1019 struct pHidd_BitMap_DrawEllipse *msg)
1021 OOP_Object *gc = msg->gc;
1022 WORD x = msg->rx, y = 0; /* ellipse points */
1024 /* intermediate terms to speed up loop */
1025 LONG t1 = msg->rx * msg->rx, t2 = t1 << 1, t3 = t2 << 1;
1026 LONG t4 = msg->ry * msg->ry, t5 = t4 << 1, t6 = t5 << 1;
1027 LONG t7 = msg->rx * t5, t8 = t7 << 1, t9 = 0L;
1028 LONG d1 = t2 - t7 + (t4 >> 1); /* error terms */
1029 LONG d2 = (t1 >> 1) - t8 + t5;
1031 BOOL doclip = GC_DOCLIP(gc);
1034 EnterFunc(bug("BitMap::DrawEllipse()"));
1036 while (d2 < 0) /* til slope = -1 */
1038 /* draw 4 points using symmetry */
1040 if (doclip)
1043 if (!POINT_OUTSIDE_CLIP(gc, msg->x + x, msg->y + y))
1044 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y + y);
1046 if (!POINT_OUTSIDE_CLIP(gc, msg->x + x, msg->y - y))
1047 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y - y);
1049 if (!POINT_OUTSIDE_CLIP(gc, msg->x - x, msg->y + y))
1050 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y + y);
1052 if (!POINT_OUTSIDE_CLIP(gc, msg->x - x, msg->y - y))
1053 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y - y);
1056 else
1058 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y + y);
1059 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y - y);
1060 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y + y);
1061 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y - y);
1064 y++; /* always move up here */
1065 t9 = t9 + t3;
1066 if (d1 < 0) /* move straight up */
1068 d1 = d1 + t9 + t2;
1069 d2 = d2 + t9;
1071 else /* move up and left */
1073 x--;
1074 t8 = t8 - t6;
1075 d1 = d1 + t9 + t2 - t8;
1076 d2 = d2 + t9 + t5 - t8;
1080 do /* rest of top right quadrant */
1082 /* draw 4 points using symmetry */
1083 #if 1
1084 if (doclip)
1087 if (!POINT_OUTSIDE_CLIP(gc, msg->x + x, msg->y + y))
1088 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y + y);
1090 if (!POINT_OUTSIDE_CLIP(gc, msg->x + x, msg->y - y))
1091 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y - y);
1093 if (!POINT_OUTSIDE_CLIP(gc, msg->x - x, msg->y + y))
1094 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y + y);
1096 if (!POINT_OUTSIDE_CLIP(gc, msg->x - x, msg->y - y))
1097 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y - y);
1100 else
1103 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y + y);
1104 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y - y);
1105 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y + y);
1106 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y - y);
1108 #else
1110 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y + y);
1111 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y - y);
1112 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y + y);
1113 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y - y);
1114 #endif
1115 x--; /* always move left here */
1116 t8 = t8 - t6;
1117 if (d2 < 0) /* move up and left */
1119 y++;
1120 t9 = t9 + t3;
1121 d2 = d2 + t9 + t5 - t8;
1123 else /* move straight left */
1125 d2 = d2 + t5 - t8;
1128 } while (x >= 0);
1131 ReturnVoid("BitMap::DrawEllipse");
1134 /*****************************************************************************************
1136 BitMap::FillEllipse()
1138 NAME
1139 FillEllipse
1141 SYNOPSIS
1142 OOP_DoMethod(obj, WORD x, WORD y, UWORD rx, UWORD ry);
1144 FUNCTION
1145 Draws a solid ellipse from the center point (x/y) with the radii
1146 rx and ry in the specified bitmap.
1147 The function does not clip the ellipse against the drawing area.
1149 INPUTS
1150 x,y - center point in hidd units
1151 rx,ry - ry and ry radius in hidd units
1153 RESULT
1155 NOTES
1157 EXAMPLE
1159 Because of overflow the current code do not work with big
1160 values of rx and ry.
1162 SEE ALSO
1163 GROUP=HIDD_Ellipse
1165 INTERNALS
1167 TODO
1168 Bugfix
1170 HISTORY
1172 *****************************************************************************************/
1174 VOID BM__Hidd_BitMap__FillEllipse(OOP_Class *cl, OOP_Object *obj,
1175 struct pHidd_BitMap_DrawEllipse *msg)
1177 OOP_Object *gc = msg->gc;
1178 WORD x = msg->rx, y = 0; /* ellipse points */
1180 /* intermediate terms to speed up loop */
1181 LONG t1 = msg->rx * msg->rx, t2 = t1 << 1, t3 = t2 << 1;
1182 LONG t4 = msg->ry * msg->ry, t5 = t4 << 1, t6 = t5 << 1;
1183 LONG t7 = msg->rx * t5, t8 = t7 << 1, t9 = 0L;
1184 LONG d1 = t2 - t7 + (t4 >> 1); /* error terms */
1185 LONG d2 = (t1 >> 1) - t8 + t5;
1187 EnterFunc(bug("BitMap::FillEllipse()"));
1189 while (d2 < 0) /* til slope = -1 */
1191 /* draw 4 points using symmetry */
1192 HIDD_BM_DrawLine(obj, gc, msg->x - x, msg->y + y, msg->x + x, msg->y + y);
1193 HIDD_BM_DrawLine(obj, gc, msg->x - x, msg->y - y, msg->x + x, msg->y - y);
1195 y++; /* always move up here */
1196 t9 = t9 + t3;
1197 if (d1 < 0) /* move straight up */
1199 d1 = d1 + t9 + t2;
1200 d2 = d2 + t9;
1202 else /* move up and left */
1204 x--;
1205 t8 = t8 - t6;
1206 d1 = d1 + t9 + t2 - t8;
1207 d2 = d2 + t9 + t5 - t8;
1211 do /* rest of top right quadrant */
1213 /* draw 4 points using symmetry */
1214 HIDD_BM_DrawLine(obj, gc, msg->x - x, msg->y + y, msg->x + x, msg->y + y);
1215 HIDD_BM_DrawLine(obj, gc, msg->x - x, msg->y - y, msg->x + x, msg->y - y);
1217 x--; /* always move left here */
1218 t8 = t8 - t6;
1219 if (d2 < 0) /* move up and left */
1221 y++;
1222 t9 = t9 + t3;
1223 d2 = d2 + t9 + t5 - t8;
1225 else /* move straight left */
1227 d2 = d2 + t5 - t8;
1230 } while (x >= 0);
1232 ReturnVoid("BitMap::FillEllipse");
1235 /*****************************************************************************************
1238 BitMap::DrawPolygon()
1240 NAME
1241 DrawPolygon
1243 SYNOPSIS
1244 OOP_DoMethod(obj, UWORD n, WORD coords[2*n]);
1246 FUNCTION
1247 Draws a hollow polygon from the list of coordinates in coords[].
1248 The function does not clip the polygon against the drawing area.
1250 INPUTS
1251 n - number of coordinate pairs
1252 coords - array of n (x, y) coordinates in hidd units
1254 RESULT
1256 NOTES
1258 EXAMPLE
1260 BUGS
1262 SEE ALSO
1263 GROUP=HIDD_Polygon
1265 INTERNALS
1267 TODO
1269 HISTORY
1271 *****************************************************************************************/
1273 VOID BM__Hidd_BitMap__DrawPolygon(OOP_Class *cl, OOP_Object *obj,
1274 struct pHidd_BitMap_DrawPolygon *msg)
1276 OOP_Object *gc = msg->gc;
1277 WORD i;
1279 EnterFunc(bug("BitMap::DrawPolygon()"));
1281 for(i = 2; i < (2 * msg->n); i = i + 2)
1283 HIDD_BM_DrawLine(obj, gc, msg->coords[i - 2], msg->coords[i - 1],
1284 msg->coords[i], msg->coords[i + 1]);
1287 ReturnVoid("BitMap::DrawPolygon");
1290 /*****************************************************************************************
1292 BitMap::FillPolygon()
1294 NAME
1295 FillPolygon()
1297 SYNOPSIS
1298 OOP_DoMethod(obj, UWORD n, WORD coords[2*n]);
1300 FUNCTION
1301 Draws a solid polygon from the list of coordinates in coords[].
1302 If the last point of the polygon is not equal to the first point
1303 then the function closes the polygon.
1305 The function does not clip the polygon against the drawing area.
1307 INPUTS
1308 n - number of coordinate pairs
1309 coords - array of n (x, y) coordinates in hidd units
1311 RESULT
1313 NOTES
1315 EXAMPLE
1317 BUGS
1319 SEE ALSO
1320 GROUP=HIDD_Polygon
1322 INTERNALS
1324 TODO
1326 HISTORY
1328 *****************************************************************************************/
1330 VOID BM__Hidd_BitMap__FillPolygon(OOP_Class *cl, OOP_Object *obj, struct pHidd_BitMap_DrawPolygon *msg)
1333 EnterFunc(bug("BitMap::FillPolygon()"));
1335 D(bug("Sorry, FillPolygon() not implemented yet in bitmap baseclasss\n"));
1337 ReturnVoid("BitMap::FillPolygon");
1340 /*****************************************************************************************
1342 BitMap::DrawText()
1344 NAME
1345 DrawText()
1347 SYNOPSIS
1348 OOP_DoMethod(obj, WORD x, WORD y, STRPTR text, UWORD length);
1350 FUNCTION
1351 Draws the first length characters of text at (x, y).
1352 The function does not clip the text against the drawing area.
1354 INPUTS
1355 x, y - Position to start drawing in hidd units. The x
1356 coordinate is relativ to the left side of the
1357 first character.
1358 The y coordinate is relative to the baseline of the font.
1359 text - Pointer to a Latin 1 string
1360 length - Number of characters to draw
1362 RESULT
1364 NOTES
1366 EXAMPLE
1368 BUGS
1370 SEE ALSO
1371 GROUP=HIDD_Text
1373 INTERNALS
1375 TODO
1376 - Color fonts
1377 - Fontstyle
1379 HISTORY
1381 *****************************************************************************************/
1383 VOID BM__Hidd_BitMap__DrawText(OOP_Class *cl, OOP_Object *obj,
1384 struct pHidd_BitMap_DrawText *msg)
1386 OOP_Object *gc = msg->gc;
1387 struct TextFont *font = GC_FONT(gc);
1388 UBYTE *charPatternPtr = font->tf_CharData;
1389 UWORD modulo = font->tf_Modulo;
1390 ULONG charLog;
1391 UBYTE ch; /* current character to print */
1392 WORD fx, fx2, fy, fw; /* position and length of character in the */
1393 /* character bitmap */
1394 WORD xMem = msg->x; /* position in bitmap */
1395 WORD yMem = msg->y - font->tf_Baseline;
1396 WORD x, y, i;
1399 EnterFunc(bug("BitMap::DrawText()"));
1401 for(i = 0; i < msg->length; i++)
1403 ch = msg->text[i];
1405 if((ch < font->tf_LoChar) || (ch > font->tf_HiChar))
1407 ch = font->tf_HiChar - font->tf_LoChar + 1;
1409 else
1411 ch = ch - font->tf_LoChar;
1414 if(font->tf_Flags & FPF_PROPORTIONAL)
1416 xMem = xMem + ((UWORD *) font->tf_CharKern)[ch];
1419 charLog = ((ULONG *) font->tf_CharLoc)[ch];
1420 fx2 = charLog >> 16; /* x position of character pattern in character bitmap */
1421 fw = (UWORD) charLog; /* width of character pattern in character bitmap */
1423 y = yMem;
1425 for(fy = 0; fy < font->tf_YSize; fy ++)
1427 x = xMem;
1429 for(fx = fx2; fx < fw + fx2; fx++)
1431 if(*(charPatternPtr + fx / 8 + fy * modulo) & (128 >> (fx % 8)))
1433 HIDD_BM_DrawPixel(obj, msg->gc, x, y);
1435 x++;
1438 y++;
1441 if(font->tf_Flags & FPF_PROPORTIONAL)
1443 xMem = xMem + ((UWORD *) font->tf_CharSpace)[ch];
1445 else
1447 xMem = xMem + font->tf_XSize;
1451 ReturnVoid("BitMap::DrawText");
1454 /*****************************************************************************************
1456 BitMap::DrawFillText ()
1458 NAME
1459 DrawFillText()
1461 SYNOPSIS
1462 OOP_DoMethod(obj, WORD x, WORD y, STRPTR text, UWORD length);
1464 FUNCTION
1465 Fills the area of the text with the background color
1466 and draws the first length characters of text at (x, y).
1467 The function does not clip the text against the drawing area.
1469 INPUTS
1470 x, y - Position to start drawing in hidd units. The x
1471 coordinate is relativ to the left side of the
1472 first character.
1473 The y coordinate is relative to the baseline of the font.
1474 text - Pointer to a Latin 1 string
1475 length - Number of characters to draw
1477 RESULT
1479 NOTES
1481 EXAMPLE
1483 BUGS
1485 SEE ALSO
1486 GROUP=HIDD_Text
1488 INTERNALS
1490 TODO
1492 HISTORY
1494 *****************************************************************************************/
1496 VOID BM__Hidd_BitMap__FillText(OOP_Class *cl, OOP_Object *obj, struct pHidd_BitMap_DrawText *msg)
1499 EnterFunc(bug("BitMap::FillText()\n"));
1501 D(bug("Sorry, FillText() not implemented yet in bitmap baseclass\n"));
1503 ReturnVoid("BitMap::DrawFillText");
1506 /*****************************************************************************************
1508 BitMap::FillSpan()
1510 NAME
1511 FillSpan()
1513 SYNOPSIS
1514 OOP_DoMethod(obj, HIDDT_Span span);
1516 FUNCTION
1517 Draws a solid from a shape description in the specified bitmap. This
1518 command is available in quick and normal mode. In normal mode,
1519 the spans are clipped against the drawing area.
1521 INPUTS
1523 RESULT
1525 NOTES
1527 EXAMPLE
1529 BUGS
1531 SEE ALSO
1533 INTERNALS
1535 TODO
1537 HISTORY
1539 *****************************************************************************************/
1541 VOID BM__Hidd_BitMap__FillSpan(OOP_Class *cl, OOP_Object *obj, struct pHidd_BitMap_DrawText *msg)
1544 EnterFunc(bug("BitMap::FillSpan()\n"));
1546 D(bug("Sorry, not implemented yet\n"));
1548 ReturnVoid("BitMap::FillSpan");
1551 /*****************************************************************************************
1553 BitMap::Clear()
1555 NAME
1556 Clear()
1558 SYNOPSIS
1559 OOP_DoMethod(obj);
1561 FUNCTION
1562 Sets all pixels of the drawing area to the background color.
1563 This command is available in quick and normal mode and behaves
1564 similar in both modes.
1566 INPUTS
1568 RESULT
1570 NOTES
1572 EXAMPLE
1574 BUGS
1576 SEE ALSO
1578 INTERNALS
1580 TODO
1582 HISTORY
1584 *****************************************************************************************/
1586 VOID BM__Hidd_BitMap__Clear(OOP_Class *cl, OOP_Object *obj, struct pHidd_BitMap_Clear *msg)
1588 WORD x, y;
1589 IPTR width, height;
1591 EnterFunc(bug("BitMap::Clear()\n"));
1593 OOP_GetAttr(obj, aHidd_BitMap_Width, &width);
1594 OOP_GetAttr(obj, aHidd_BitMap_Height, &height);
1596 for(y = 0; y < height; y++)
1598 for(x = 0; x < width; x++)
1600 HIDD_BM_PutPixel(obj, x, y, 0);
1604 ReturnVoid("BitMap::Clear");
1607 /****************************************************************************************/
1609 static LONG inline getpixfmtbpp(OOP_Class *cl, OOP_Object *o, HIDDT_StdPixFmt stdpf)
1611 OOP_Object *pf;
1612 struct HIDDBitMapData *data;
1613 SIPTR bpp = -1;
1615 data = OOP_INST_DATA(cl, o);
1617 switch (stdpf)
1619 case vHidd_StdPixFmt_Native:
1620 OOP_GetAttr(data->prot.pixfmt, aHidd_PixFmt_BytesPerPixel, &bpp);
1621 break;
1623 case vHidd_StdPixFmt_Native32:
1624 bpp = sizeof (HIDDT_Pixel);
1625 break;
1627 default:
1628 pf = HIDD_Gfx_GetPixFmt(data->gfxhidd, stdpf);
1630 if (NULL == pf)
1632 D(bug("!!! INVALID PIXFMT IN BitMap::PutImage(): %d !!!\n", stdpf));
1634 else
1636 OOP_GetAttr(pf, aHidd_PixFmt_BytesPerPixel, &bpp);
1638 break;
1641 return bpp;
1644 /****************************************************************************************/
1646 VOID BM__Hidd_BitMap__GetImage(OOP_Class *cl, OOP_Object *o,
1647 struct pHidd_BitMap_GetImage *msg)
1649 WORD x, y;
1650 UBYTE *pixarray = (UBYTE *)msg->pixels;
1651 APTR ppixarray = &pixarray;
1652 LONG bpp;
1653 struct HIDDBitMapData *data;
1655 data = OOP_INST_DATA(cl, o);
1657 EnterFunc(bug("BitMap::GetImage(x=%d, y=%d, width=%d, height=%d)\n"
1658 , msg->x, msg->y, msg->width, msg->height));
1661 bpp = getpixfmtbpp(cl, o, msg->pixFmt);
1662 if (-1 == bpp)
1664 D(bug("!!! INVALID PIXFMT IN BitMap::PutImage(): %d !!!\n", msg->pixFmt));
1665 return;
1669 switch(msg->pixFmt)
1671 case vHidd_StdPixFmt_Native:
1672 case vHidd_StdPixFmt_Native32:
1673 for (y = 0; y < msg->height; y ++)
1675 for (x = 0; x < msg->width; x ++)
1677 register HIDDT_Pixel pix;
1679 pix = HIDD_BM_GetPixel(o, x + msg->x , y + msg->y);
1681 switch (bpp)
1683 case 1:
1684 *pixarray++ = pix;
1685 break;
1687 case 2:
1688 *((UWORD *)pixarray) = pix;
1689 pixarray += 2;
1690 break;
1692 case 3:
1693 #if AROS_BIG_ENDIAN
1694 pixarray[0] = (pix >> 16) & 0xFF;
1695 pixarray[1] = (pix >> 8) & 0xFF;
1696 pixarray[2] = pix & 0xFF;
1697 #else
1698 pixarray[0] = pix & 0xFF;
1699 pixarray[1] = (pix >> 8) & 0xFF;
1700 pixarray[2] = (pix >> 16) & 0xFF;
1701 #endif
1702 pixarray += 3;
1703 break;
1705 case 4:
1706 *(ULONG *)pixarray = pix;
1707 pixarray += 4;
1708 break;
1713 pixarray += (msg->modulo - msg->width * bpp);
1716 break;
1718 default:
1720 OOP_Object *dstpf;
1721 APTR buf, srcPixels;
1723 dstpf = HIDD_Gfx_GetPixFmt(data->gfxhidd, msg->pixFmt);
1725 buf = srcPixels = AllocVec(msg->width * sizeof(HIDDT_Pixel), MEMF_PUBLIC);
1726 if (buf)
1728 for(y = 0; y < msg->height; y++)
1730 HIDD_BM_GetImage(o,
1731 buf,
1733 msg->x,
1734 msg->y + y,
1735 msg->width,
1737 vHidd_StdPixFmt_Native);
1739 HIDD_BM_ConvertPixels(o,
1740 &srcPixels,
1741 (HIDDT_PixelFormat *)data->prot.pixfmt,
1743 (APTR *)ppixarray,
1744 (HIDDT_PixelFormat *)dstpf,
1745 msg->modulo,
1746 msg->width,
1748 NULL);
1751 FreeVec(buf);
1754 break;
1756 } /* switch(msg->pixFmt) */
1758 ReturnVoid("BitMap::GetImage");
1761 /****************************************************************************************/
1763 VOID BM__Hidd_BitMap__PutImage(OOP_Class *cl, OOP_Object *o,
1764 struct pHidd_BitMap_PutImage *msg)
1766 WORD x, y;
1767 UBYTE *pixarray = (UBYTE *)msg->pixels;
1768 APTR ppixarray = &pixarray;
1769 ULONG old_fg;
1770 LONG bpp;
1771 struct HIDDBitMapData *data;
1772 OOP_Object *gc = msg->gc;
1774 data = OOP_INST_DATA(cl, o);
1776 EnterFunc(bug("BitMap::PutImage(x=%d, y=%d, width=%d, height=%d)\n"
1777 , msg->x, msg->y, msg->width, msg->height));
1779 if (msg->width <= 0 || msg->height <= 0)
1780 return;
1782 bpp = getpixfmtbpp(cl, o, msg->pixFmt);
1783 if (-1 == bpp)
1785 D(bug("!!! INVALID PIXFMT IN BitMap::PutImage(): %d !!!\n", msg->pixFmt));
1786 return;
1789 switch(msg->pixFmt)
1791 case vHidd_StdPixFmt_Native:
1792 case vHidd_StdPixFmt_Native32:
1794 /* Preserve old fg pen */
1795 old_fg = GC_FG(gc);
1797 for (y = 0; y < msg->height; y ++)
1799 for (x = 0; x < msg->width; x ++)
1801 register HIDDT_Pixel pix = 0;
1803 switch (bpp)
1805 case 1:
1806 pix = *((UBYTE *)pixarray);
1807 pixarray ++;
1808 break;
1810 case 2:
1811 pix = *((UWORD *)pixarray);
1812 pixarray += 2;
1813 break;
1815 case 3:
1816 #if AROS_BIG_ENDIAN
1817 pix = ((UBYTE *)pixarray)[0] << 16;
1818 pix |= ((UBYTE *)pixarray)[1] << 8;
1819 pix |= ((UBYTE *)pixarray)[2];
1820 #else
1821 pix = ((UBYTE *)pixarray)[2] << 16;
1822 pix |= ((UBYTE *)pixarray)[1] << 8;
1823 pix |= ((UBYTE *)pixarray)[0];
1824 #endif
1825 pixarray += 3;
1826 break;
1828 case 4:
1829 pix = *((ULONG *)pixarray); pixarray += 4;
1830 break;
1834 GC_FG(gc) = pix;
1836 HIDD_BM_DrawPixel(o, gc, x + msg->x , y + msg->y);
1838 pixarray += (msg->modulo - msg->width * bpp);
1841 GC_FG(gc) = old_fg;
1842 break;
1844 default:
1846 OOP_Object *srcpf;
1847 APTR buf, destPixels;
1849 srcpf = HIDD_Gfx_GetPixFmt(data->gfxhidd, msg->pixFmt);
1851 buf = destPixels = AllocVec(msg->width * sizeof(HIDDT_Pixel), MEMF_PUBLIC);
1852 if (buf)
1854 for(y = 0; y < msg->height; y++)
1856 HIDD_BM_ConvertPixels(o,
1857 (APTR *)ppixarray,
1858 (HIDDT_PixelFormat *)srcpf,
1859 msg->modulo,
1860 &destPixels,
1861 (HIDDT_PixelFormat *)data->prot.pixfmt,
1863 msg->width,
1865 NULL);
1867 HIDD_BM_PutImage(o,
1868 msg->gc,
1869 buf,
1871 msg->x,
1872 msg->y + y,
1873 msg->width,
1875 vHidd_StdPixFmt_Native);
1877 FreeVec(buf);
1880 break;
1882 } /* switch(msg->pixFmt) */
1884 ReturnVoid("BitMap::PutImage");
1887 /****************************************************************************************/
1889 int static inline
1890 __attribute__((always_inline, const)) do_alpha(int a, int v)
1892 int tmp = (a*v);
1893 return ((tmp<<8) + tmp + 32768)>>16;
1896 VOID BM__Hidd_BitMap__PutAlphaImage(OOP_Class *cl, OOP_Object *o,
1897 struct pHidd_BitMap_PutAlphaImage *msg)
1899 WORD x, y;
1900 ULONG *pixarray = (ULONG *)msg->pixels;
1901 ULONG *buf, *xbuf;
1902 struct HIDDBitMapData *data;
1903 PIXBUF_DECLARE_VARS
1905 data = OOP_INST_DATA(cl, o);
1907 EnterFunc(bug("BitMap::PutAlphaImage(x=%d, y=%d, width=%d, height=%d)\n"
1908 , msg->x, msg->y, msg->width, msg->height));
1910 if (msg->width <= 0 || msg->height <= 0)
1911 return;
1913 PIXBUF_ALLOC(buf, msg->width * sizeof(ULONG), msg->height);
1915 if (buf)
1917 HIDDT_DrawMode old_drmd = GC_DRMD(msg->gc);
1918 GC_DRMD(msg->gc) = vHidd_GC_DrawMode_Copy;
1920 xbuf = buf;
1922 for(y = msg->y; y < msg->y + msg->height; y++)
1924 if (PIXBUF_TIME_TO_START_PROCESS)
1926 WORD height = PIXBUF_LINES_TO_PROCESS;
1928 HIDD_BM_GetImage(o,
1929 (UBYTE *)buf,
1930 msg->width * sizeof(ULONG),
1931 msg->x,
1933 msg->width,
1934 height,
1935 vHidd_StdPixFmt_ARGB32);
1938 for(x = 0; x < msg->width; x++)
1940 ULONG destpix;
1941 ULONG srcpix;
1942 LONG src_red, src_green, src_blue, src_alpha;
1943 LONG dst_red, dst_green, dst_blue;
1945 srcpix = *pixarray++;
1946 #if AROS_BIG_ENDIAN
1947 src_red = (srcpix & 0x00FF0000) >> 16;
1948 src_green = (srcpix & 0x0000FF00) >> 8;
1949 src_blue = (srcpix & 0x000000FF);
1950 src_alpha = (srcpix & 0xFF000000) >> 24;
1951 #else
1952 src_red = (srcpix & 0x0000FF00) >> 8;
1953 src_green = (srcpix & 0x00FF0000) >> 16;
1954 src_blue = (srcpix & 0xFF000000) >> 24;
1955 src_alpha = (srcpix & 0x000000FF);
1956 #endif
1958 destpix = xbuf[x];
1959 #if AROS_BIG_ENDIAN
1960 dst_red = (destpix & 0x00FF0000) >> 16;
1961 dst_green = (destpix & 0x0000FF00) >> 8;
1962 dst_blue = (destpix & 0x000000FF);
1963 #else
1964 dst_red = (destpix & 0x0000FF00) >> 8;
1965 dst_green = (destpix & 0x00FF0000) >> 16;
1966 dst_blue = (destpix & 0xFF000000) >> 24;
1967 #endif
1969 dst_red += do_alpha(src_alpha, src_red - dst_red);
1970 dst_green += do_alpha(src_alpha, src_green - dst_green);
1971 dst_blue += do_alpha(src_alpha, src_blue - dst_blue);
1973 #if AROS_BIG_ENDIAN
1974 destpix &= 0xFF000000;
1975 destpix |= (dst_red << 16) + (dst_green << 8) + (dst_blue);
1976 #else
1977 destpix &= 0x000000FF;
1978 destpix |= (dst_blue << 24) + (dst_green << 16) + (dst_red << 8);
1979 #endif
1981 xbuf[x] = destpix;
1983 } /* for(x = 0; x < msg->width; x++) */
1985 if (PIXBUF_TIME_TO_END_PROCESS)
1987 LONG height = PIXBUF_LINES_TO_PROCESS;
1989 HIDD_BM_PutImage(o,
1990 msg->gc,
1991 (UBYTE *)buf,
1992 msg->width * sizeof(ULONG),
1993 msg->x,
1994 y - height + 1,
1995 msg->width,
1996 height,
1997 vHidd_StdPixFmt_ARGB32);
1998 xbuf = buf;
2000 else
2002 xbuf += msg->width;
2005 pixarray = (ULONG *)((UBYTE *)pixarray + msg->modulo - msg->width * 4);
2007 PIXBUF_NEXT_LINE;
2010 } /* for(y = msg->y; y < msg->y + msg->height; y++) */
2012 GC_DRMD(msg->gc) = old_drmd;
2014 PIXBUF_FREE(buf);
2016 } /* if (buf) */
2017 else
2019 for(y = msg->y; y < msg->y + msg->height; y++)
2021 for(x = msg->x; x < msg->x + msg->width; x++)
2023 HIDDT_Pixel destpix;
2024 HIDDT_Color col;
2025 ULONG srcpix;
2026 LONG src_red, src_green, src_blue, src_alpha;
2027 LONG dst_red, dst_green, dst_blue;
2029 destpix = HIDD_BM_GetPixel(o, x, y);
2030 HIDD_BM_UnmapPixel(o, destpix, &col);
2032 srcpix = *pixarray++;
2033 #if AROS_BIG_ENDIAN
2034 src_red = (srcpix & 0x00FF0000) >> 16;
2035 src_green = (srcpix & 0x0000FF00) >> 8;
2036 src_blue = (srcpix & 0x000000FF);
2037 src_alpha = (srcpix & 0xFF000000) >> 24;
2038 #else
2039 src_red = (srcpix & 0x0000FF00) >> 8;
2040 src_green = (srcpix & 0x00FF0000) >> 16;
2041 src_blue = (srcpix & 0xFF000000) >> 24;
2042 src_alpha = (srcpix & 0x000000FF);
2043 #endif
2045 dst_red = col.red >> 8;
2046 dst_green = col.green >> 8;
2047 dst_blue = col.blue >> 8;
2049 dst_red += do_alpha(src_alpha, src_red - dst_red);
2050 dst_green += do_alpha(src_alpha, src_green - dst_green);
2051 dst_blue += do_alpha(src_alpha, src_blue - dst_blue);
2053 col.red = dst_red << 8;
2054 col.green = dst_green << 8;
2055 col.blue = dst_blue << 8;
2057 HIDD_BM_PutPixel(o, x, y, HIDD_BM_MapColor(o, &col));
2059 } /* for(x = msg->x; x < msg->x + msg->width; x++) */
2061 pixarray = (ULONG *)((UBYTE *)pixarray + msg->modulo - msg->width * 4);
2063 } /* for(y = msg->y; y < msg->y + msg->height; y++) */
2067 ReturnVoid("BitMap::PutAlphaImage");
2070 /****************************************************************************************/
2072 VOID BM__Hidd_BitMap__PutTemplate(OOP_Class *cl, OOP_Object *o,
2073 struct pHidd_BitMap_PutTemplate *msg)
2075 WORD x, y;
2076 UBYTE *bitarray;
2077 HIDDT_Pixel *buf, *xbuf, bitmask;
2078 OOP_Object *gc = msg->gc;
2079 struct HIDDBitMapData *data;
2080 WORD type = 0;
2081 PIXBUF_DECLARE_VARS
2083 data = OOP_INST_DATA(cl, o);
2085 EnterFunc(bug("BitMap::PutTemplate(x=%d, y=%d, width=%d, height=%d)\n"
2086 , msg->x, msg->y, msg->width, msg->height));
2088 if (msg->width <= 0 || msg->height <= 0)
2089 return;
2091 if (GC_COLEXP(gc) == vHidd_GC_ColExp_Transparent)
2093 type = 0;
2095 else if (GC_DRMD(gc) == vHidd_GC_DrawMode_Invert)
2097 type = 2;
2099 else
2101 type = 4;
2104 if (msg->inverttemplate) type++;
2106 bitarray = msg->template + ((msg->srcx / 16) * 2);
2107 bitmask = 0x8000 >> (msg->srcx & 0xF);
2109 PIXBUF_ALLOC(buf, msg->width * sizeof(HIDDT_Pixel), msg->height);
2111 if (buf)
2113 HIDDT_DrawMode old_drmd = GC_DRMD(msg->gc);
2114 HIDDT_Pixel fg = GC_FG(msg->gc);
2115 HIDDT_Pixel bg = GC_BG(msg->gc);
2117 GC_DRMD(msg->gc) = vHidd_GC_DrawMode_Copy;
2119 xbuf = buf;
2121 for(y = msg->y; y < msg->y + msg->height; y++)
2123 ULONG mask = bitmask;
2124 UWORD *array = (UWORD *)bitarray;
2125 UWORD bitword = AROS_BE2WORD(*array);
2127 if ((type < 4) && PIXBUF_TIME_TO_START_PROCESS)
2129 WORD height = PIXBUF_LINES_TO_PROCESS;
2131 HIDD_BM_GetImage(o,
2132 (UBYTE *)buf,
2133 msg->width * sizeof(HIDDT_Pixel),
2134 msg->x,
2136 msg->width,
2137 height,
2138 vHidd_StdPixFmt_Native32);
2142 switch(type)
2144 case 0: /* JAM1 */
2145 for(x = 0; x < msg->width; x++)
2147 if (bitword & mask) xbuf[x] = fg;
2149 mask >>= 1;
2150 if (!mask)
2152 mask = 0x8000;
2153 array++;
2154 bitword = AROS_BE2WORD(*array);
2157 } /* for(x = 0; x < msg->width; x++) */
2158 break;
2160 case 1: /* JAM1 | INVERSVID */
2161 for(x = 0; x < msg->width; x++)
2163 if (!(bitword & mask)) xbuf[x] = fg;
2165 mask >>= 1;
2166 if (!mask)
2168 mask = 0x8000;
2169 array++;
2170 bitword = AROS_BE2WORD(*array);
2173 } /* for(x = 0; x < msg->width; x++) */
2174 break;
2176 case 2: /* COMPLEMENT */
2177 for(x = 0; x < msg->width; x++)
2179 if (bitword & mask) xbuf[x] = ~xbuf[x];
2181 mask >>= 1;
2182 if (!mask)
2184 mask = 0x8000;
2185 array++;
2186 bitword = AROS_BE2WORD(*array);
2188 } /* for(x = 0; x < msg->width; x++) */
2189 break;
2191 case 3: /* COMPLEMENT | INVERSVID*/
2192 for(x = 0; x < msg->width; x++)
2194 if (!(bitword & mask)) xbuf[x] = ~xbuf[x];
2196 mask >>= 1;
2197 if (!mask)
2199 mask = 0x8000;
2200 array++;
2201 bitword = AROS_BE2WORD(*array);
2203 } /* for(x = 0; x < msg->width; x++) */
2204 break;
2206 case 4: /* JAM2 */
2207 for(x = 0; x < msg->width; x++)
2209 xbuf[x] = (bitword & mask) ? fg : bg;
2211 mask >>= 1;
2212 if (!mask)
2214 mask = 0x8000;
2215 array++;
2216 bitword = AROS_BE2WORD(*array);
2219 } /* for(x = 0; x < msg->width; x++) */
2220 break;
2222 case 5: /* JAM2 | INVERSVID */
2223 for(x = 0; x < msg->width; x++)
2225 xbuf[x] = (bitword & mask) ? bg : fg;
2227 mask >>= 1;
2228 if (!mask)
2230 mask = 0x8000;
2231 array++;
2232 bitword = AROS_BE2WORD(*array);
2234 } /* for(x = 0; x < msg->width; x++) */
2235 break;
2237 } /* switch(type) */
2239 if (PIXBUF_TIME_TO_END_PROCESS)
2241 LONG height = PIXBUF_LINES_TO_PROCESS;
2243 //kprintf(" PutImage at %d height %d __height %d __bufy %d __worky %d\n",
2244 // y - height + 1 - msg->y, height, __height, __bufy, __worky);
2246 HIDD_BM_PutImage(o,
2247 msg->gc,
2248 (UBYTE *)buf,
2249 msg->width * sizeof(HIDDT_Pixel),
2250 msg->x,
2251 y - height + 1,
2252 msg->width,
2253 height,
2254 vHidd_StdPixFmt_Native32);
2255 xbuf = buf;
2257 else
2259 xbuf += msg->width;
2262 bitarray += msg->modulo;
2264 PIXBUF_NEXT_LINE;
2266 } /* for(y = msg->y; y < msg->y + msg->height; y++) */
2268 GC_DRMD(msg->gc) = old_drmd;
2270 PIXBUF_FREE(buf);
2272 } /* if (buf) */
2273 else
2278 ReturnVoid("BitMap::PutTemplate");
2281 /****************************************************************************************/
2283 VOID BM__Hidd_BitMap__PutAlphaTemplate(OOP_Class *cl, OOP_Object *o,
2284 struct pHidd_BitMap_PutAlphaTemplate *msg)
2286 WORD x, y;
2287 UBYTE *pixarray = msg->alpha;
2288 ULONG *buf, *xbuf;
2289 OOP_Object *gc = msg->gc;
2290 struct HIDDBitMapData *data;
2291 HIDDT_Color color;
2292 LONG a_red, a_green, a_blue;
2293 LONG b_red, b_green, b_blue;
2294 WORD type = 0;
2295 PIXBUF_DECLARE_VARS
2297 data = OOP_INST_DATA(cl, o);
2299 EnterFunc(bug("BitMap::PutAlphaTemplate(x=%d, y=%d, width=%d, height=%d)\n"
2300 , msg->x, msg->y, msg->width, msg->height));
2302 if (msg->width <= 0 || msg->height <= 0)
2303 return;
2305 HIDD_BM_UnmapPixel(o, GC_FG(gc), &color);
2307 a_red = color.red >> 8;
2308 a_green = color.green >> 8;
2309 a_blue = color.blue >> 8;
2311 if (GC_COLEXP(gc) == vHidd_GC_ColExp_Transparent)
2313 type = 0;
2315 else if (GC_DRMD(gc) == vHidd_GC_DrawMode_Invert)
2317 type = 2;
2319 else
2321 type = 4;
2323 HIDD_BM_UnmapPixel(o, GC_BG(gc), &color);
2324 b_red = color.red >> 8;
2325 b_green = color.green >> 8;
2326 b_blue = color.blue >> 8;
2329 if (msg->invertalpha) type++;
2331 PIXBUF_ALLOC(buf, msg->width * sizeof(ULONG), msg->height);
2333 if (buf)
2335 HIDDT_DrawMode old_drmd = GC_DRMD(msg->gc);
2336 GC_DRMD(msg->gc) = vHidd_GC_DrawMode_Copy;
2338 xbuf = buf;
2340 for(y = msg->y; y < msg->y + msg->height; y++)
2342 if ((type < 4) && PIXBUF_TIME_TO_START_PROCESS)
2344 WORD height = PIXBUF_LINES_TO_PROCESS;
2346 HIDD_BM_GetImage(o,
2347 (UBYTE *)buf,
2348 msg->width * sizeof(ULONG),
2349 msg->x,
2351 msg->width,
2352 height,
2353 vHidd_StdPixFmt_ARGB32);
2356 switch(type)
2358 case 0: /* JAM1 */
2359 for(x = 0; x < msg->width; x++)
2361 ULONG destpix;
2362 LONG dst_red, dst_green, dst_blue, alpha;
2364 alpha = *pixarray++;
2366 destpix = xbuf[x];
2368 #if AROS_BIG_ENDIAN
2369 dst_red = (destpix & 0x00FF0000) >> 16;
2370 dst_green = (destpix & 0x0000FF00) >> 8;
2371 dst_blue = (destpix & 0x000000FF);
2372 #else
2373 dst_red = (destpix & 0x0000FF00) >> 8;
2374 dst_green = (destpix & 0x00FF0000) >> 16;
2375 dst_blue = (destpix & 0xFF000000) >> 24;
2376 #endif
2378 dst_red += do_alpha(alpha, a_red - dst_red);
2379 dst_green += do_alpha(alpha, a_green - dst_green);
2380 dst_blue += do_alpha(alpha, a_blue - dst_blue);
2382 #if AROS_BIG_ENDIAN
2383 destpix = (dst_red << 16) + (dst_green << 8) + (dst_blue);
2384 #else
2385 destpix = (dst_blue << 24) + (dst_green << 16) + (dst_red << 8);
2386 #endif
2388 xbuf[x] = destpix;
2390 } /* for(x = 0; x < msg->width; x++) */
2391 break;
2393 case 1: /* JAM1 | INVERSVID */
2394 for(x = 0; x < msg->width; x++)
2396 ULONG destpix;
2397 LONG dst_red, dst_green, dst_blue, alpha;
2399 alpha = (*pixarray++) ^ 255;
2401 destpix = xbuf[x];
2403 #if AROS_BIG_ENDIAN
2404 dst_red = (destpix & 0x00FF0000) >> 16;
2405 dst_green = (destpix & 0x0000FF00) >> 8;
2406 dst_blue = (destpix & 0x000000FF);
2407 #else
2408 dst_red = (destpix & 0x0000FF00) >> 8;
2409 dst_green = (destpix & 0x00FF0000) >> 16;
2410 dst_blue = (destpix & 0xFF000000) >> 24;
2411 #endif
2413 dst_red += do_alpha(alpha, a_red - dst_red);
2414 dst_green += do_alpha(alpha, a_green - dst_green);
2415 dst_blue += do_alpha(alpha, a_blue - dst_blue);
2417 #if AROS_BIG_ENDIAN
2418 destpix = (dst_red << 16) + (dst_green << 8) + (dst_blue);
2419 #else
2420 destpix = (dst_blue << 24) + (dst_green << 16) + (dst_red << 8);
2421 #endif
2423 xbuf[x] = destpix;
2425 } /* for(x = 0; x < msg->width; x++) */
2426 break;
2428 case 2: /* COMPLEMENT */
2429 for(x = 0; x < msg->width; x++)
2431 ULONG destpix;
2432 UBYTE alpha;
2434 alpha = *pixarray++;
2436 destpix = xbuf[x];
2437 if (alpha >= 0x80) destpix = ~destpix;
2438 xbuf[x] = destpix;
2440 } /* for(x = 0; x < msg->width; x++) */
2441 break;
2443 case 3: /* COMPLEMENT | INVERSVID*/
2444 for(x = 0; x < msg->width; x++)
2446 ULONG destpix;
2447 UBYTE alpha;
2449 alpha = *pixarray++;
2451 destpix = xbuf[x];
2452 if (alpha < 0x80) destpix = ~destpix;
2453 xbuf[x] = destpix;
2455 } /* for(x = 0; x < msg->width; x++) */
2456 break;
2458 case 4: /* JAM2 */
2459 for(x = 0; x < msg->width; x++)
2461 ULONG destpix;
2462 LONG dst_red, dst_green, dst_blue, alpha;
2464 alpha = *pixarray++;
2466 dst_red = b_red + ((a_red - b_red) * alpha) / 256;
2467 dst_green = b_green + ((a_green - b_green) * alpha) / 256;
2468 dst_blue = b_blue + ((a_blue - b_blue) * alpha) / 256;
2470 #if AROS_BIG_ENDIAN
2471 destpix = (dst_red << 16) + (dst_green << 8) + (dst_blue);
2472 #else
2473 destpix = (dst_blue << 24) + (dst_green << 16) + (dst_red << 8);
2474 #endif
2476 xbuf[x] = destpix;
2478 } /* for(x = 0; x < msg->width; x++) */
2479 break;
2481 case 5: /* JAM2 | INVERSVID */
2482 for(x = 0; x < msg->width; x++)
2484 ULONG destpix;
2485 LONG dst_red, dst_green, dst_blue, alpha;
2487 alpha = (*pixarray++) ^ 255;
2489 dst_red = b_red + ((a_red - b_red) * alpha) / 256;
2490 dst_green = b_green + ((a_green - b_green) * alpha) / 256;
2491 dst_blue = b_blue + ((a_blue - b_blue) * alpha) / 256;
2493 #if AROS_BIG_ENDIAN
2494 destpix = (dst_red << 16) + (dst_green << 8) + (dst_blue);
2495 #else
2496 destpix = (dst_blue << 24) + (dst_green << 16) + (dst_red << 8);
2497 #endif
2499 xbuf[x] = destpix;
2501 } /* for(x = 0; x < msg->width; x++) */
2502 break;
2504 } /* switch(type) */
2506 if (PIXBUF_TIME_TO_END_PROCESS)
2508 LONG height = PIXBUF_LINES_TO_PROCESS;
2510 HIDD_BM_PutImage(o,
2511 msg->gc,
2512 (UBYTE *)buf,
2513 msg->width * sizeof(ULONG),
2514 msg->x,
2515 y - height + 1,
2516 msg->width,
2517 height,
2518 vHidd_StdPixFmt_ARGB32);
2520 xbuf = buf;
2522 else
2524 xbuf += msg->width;
2527 pixarray += msg->modulo - msg->width;
2529 PIXBUF_NEXT_LINE
2531 } /* for(y = msg->y; y < msg->y + msg->height; y++) */
2533 GC_DRMD(msg->gc) = old_drmd;
2535 PIXBUF_FREE(buf);
2537 } /* if (buf) */
2538 else
2543 ReturnVoid("BitMap::PutAlphaTemplate");
2546 /****************************************************************************************/
2548 VOID BM__Hidd_BitMap__PutPattern(OOP_Class *cl, OOP_Object *o,
2549 struct pHidd_BitMap_PutPattern *msg)
2551 WORD x, y;
2552 UBYTE *patarray;
2553 UBYTE *maskarray = 0;
2554 ULONG *buf, *xbuf, patmask, maskmask;
2555 OOP_Object *gc = msg->gc;
2556 struct HIDDBitMapData *data;
2557 WORD type = 0;
2558 PIXBUF_DECLARE_VARS
2560 data = OOP_INST_DATA(cl, o);
2562 EnterFunc(bug("BitMap::PutPattern(x=%d, y=%d, width=%d, height=%d)\n"
2563 , msg->x, msg->y, msg->width, msg->height));
2565 if (msg->width <= 0 || msg->height <= 0)
2566 return;
2568 if (msg->patterndepth > 1)
2570 type = 6;
2572 else
2574 if (GC_COLEXP(gc) == vHidd_GC_ColExp_Transparent)
2576 type = 0;
2578 else if (GC_DRMD(gc) == vHidd_GC_DrawMode_Invert)
2580 type = 2;
2582 else
2584 type = 4;
2587 if (msg->invertpattern) type++;
2590 patarray = msg->pattern;
2591 patmask = 0x8000 >> (msg->patternsrcx & 0xF);
2593 if ((maskarray = msg->mask))
2595 maskarray += (msg->masksrcx / 16) * 2;
2596 maskmask = 0x8000 >> (msg->masksrcx & 0xF);
2599 PIXBUF_ALLOC(buf, msg->width * sizeof(ULONG), msg->height);
2601 if (buf)
2603 HIDDT_DrawMode old_drmd = GC_DRMD(msg->gc);
2604 ULONG fg = GC_FG(msg->gc);
2605 ULONG bg = GC_BG(msg->gc);
2607 GC_DRMD(msg->gc) = vHidd_GC_DrawMode_Copy;
2609 xbuf = buf;
2611 for(y = msg->y; y < msg->y + msg->height; y++)
2613 ULONG pmask = patmask;
2614 ULONG mmask = maskmask;
2615 UWORD *parray = ((UWORD *)patarray) + ((y + msg->patternsrcy - msg->y) % msg->patternheight);
2616 UWORD patword = AROS_BE2WORD(*parray);
2617 UWORD *marray;
2618 UWORD maskword;
2620 if (maskarray)
2622 marray = (UWORD *)maskarray;
2623 maskword = AROS_BE2WORD(*marray);
2626 if (((type < 4) || maskarray) && PIXBUF_TIME_TO_START_PROCESS)
2628 WORD height = PIXBUF_LINES_TO_PROCESS;
2630 //kprintf(" GetImage at %d height %d\n", y - msg->y, height);
2632 HIDD_BM_GetImage(o,
2633 (UBYTE *)buf,
2634 msg->width * sizeof(ULONG),
2635 msg->x,
2637 msg->width,
2638 height,
2639 vHidd_StdPixFmt_Native32);
2643 switch(type)
2645 case 0: /* JAM1 */
2646 for(x = 0; x < msg->width; x++)
2648 if (!maskarray || (maskword & mmask))
2650 if (patword & pmask) xbuf[x] = fg;
2653 if (maskarray)
2655 mmask >>= 1;
2656 if (!mmask)
2658 mmask = 0x8000;
2659 marray++;
2660 maskword = AROS_BE2WORD(*marray);
2664 pmask >>= 1;
2665 if (!pmask) pmask = 0x8000;
2667 } /* for(x = 0; x < msg->width; x++) */
2668 break;
2670 case 1: /* JAM1 | INVERSVID */
2671 for(x = 0; x < msg->width; x++)
2673 if (!maskarray || (maskword & mmask))
2675 if (!(patword & pmask)) xbuf[x] = fg;
2678 if (maskarray)
2680 mmask >>= 1;
2681 if (!mmask)
2683 mmask = 0x8000;
2684 marray++;
2685 maskword = AROS_BE2WORD(*marray);
2689 pmask >>= 1;
2690 if (!pmask) pmask = 0x8000;
2692 } /* for(x = 0; x < msg->width; x++) */
2693 break;
2695 case 2: /* COMPLEMENT */
2696 for(x = 0; x < msg->width; x++)
2698 if (!maskarray || (maskword & mmask))
2700 if (patword & pmask) xbuf[x] = ~xbuf[x];
2703 if (maskarray)
2705 mmask >>= 1;
2706 if (!mmask)
2708 mmask = 0x8000;
2709 marray++;
2710 maskword = AROS_BE2WORD(*marray);
2714 pmask >>= 1;
2715 if (!pmask) pmask = 0x8000;
2717 } /* for(x = 0; x < msg->width; x++) */
2718 break;
2720 case 3: /* COMPLEMENT | INVERSVID*/
2721 for(x = 0; x < msg->width; x++)
2723 if (!maskarray || (maskword & mmask))
2725 if (!(patword & pmask)) xbuf[x] = ~xbuf[x];
2728 if (maskarray)
2730 mmask >>= 1;
2731 if (!mmask)
2733 mmask = 0x8000;
2734 marray++;
2735 maskword = AROS_BE2WORD(*marray);
2739 pmask >>= 1;
2740 if (!pmask) pmask = 0x8000;
2742 } /* for(x = 0; x < msg->width; x++) */
2743 break;
2745 case 4: /* JAM2 */
2746 for(x = 0; x < msg->width; x++)
2748 if (!maskarray || (maskword & mmask))
2750 xbuf[x] = (patword & pmask) ? fg : bg;
2753 if (maskarray)
2755 mmask >>= 1;
2756 if (!mmask)
2758 mmask = 0x8000;
2759 marray++;
2760 maskword = AROS_BE2WORD(*marray);
2764 pmask >>= 1;
2765 if (!pmask) pmask = 0x8000;
2767 } /* for(x = 0; x < msg->width; x++) */
2768 break;
2770 case 5: /* JAM2 | INVERSVID */
2771 for(x = 0; x < msg->width; x++)
2773 if (!maskarray || (maskword & mmask))
2775 xbuf[x] = (patword & pmask) ? bg : fg;
2778 if (maskarray)
2780 mmask >>= 1;
2781 if (!mmask)
2783 mmask = 0x8000;
2784 marray++;
2785 maskword = AROS_BE2WORD(*marray);
2789 pmask >>= 1;
2790 if (!pmask) pmask = 0x8000;
2792 } /* for(x = 0; x < msg->width; x++) */
2793 break;
2795 case 6: /* multi color pattern */
2796 for(x = 0; x < msg->width; x++)
2798 if (!maskarray || (maskword & mmask))
2800 WORD plane;
2801 ULONG pixel = (patword & pmask) ? 1 : 0;
2803 for(plane = 1; plane < msg->patterndepth; plane++)
2805 UWORD *_parray = parray + plane * msg->patternheight;
2806 UWORD _patword = AROS_BE2WORD(*_parray);
2808 if (_patword & pmask) pixel |= 1L << plane;
2811 if (msg->patternlut) pixel = msg->patternlut->pixels[pixel];
2813 xbuf[x] = pixel;
2816 if (maskarray)
2818 mmask >>= 1;
2819 if (!mmask)
2821 mmask = 0x8000;
2822 marray++;
2823 maskword = AROS_BE2WORD(*marray);
2827 pmask >>= 1;
2828 if (!pmask) pmask = 0x8000;
2830 } /* for(x = 0; x < msg->width; x++) */
2831 break;
2833 } /* switch(type) */
2835 if (PIXBUF_TIME_TO_END_PROCESS)
2837 LONG height = PIXBUF_LINES_TO_PROCESS;
2839 //kprintf(" PutImage at %d height %d __height %d __bufy %d __worky %d\n",
2840 // y - height + 1 - msg->y, height, __height, __bufy, __worky);
2842 HIDD_BM_PutImage(o,
2843 msg->gc,
2844 (UBYTE *)buf,
2845 msg->width * sizeof(ULONG),
2846 msg->x,
2847 y - height + 1,
2848 msg->width,
2849 height,
2850 vHidd_StdPixFmt_Native32);
2851 xbuf = buf;
2853 else
2855 xbuf += msg->width;
2858 if (maskarray) maskarray += msg->maskmodulo;
2860 PIXBUF_NEXT_LINE;
2862 } /* for(y = msg->y; y < msg->y + msg->height; y++) */
2864 GC_DRMD(msg->gc) = old_drmd;
2866 PIXBUF_FREE(buf);
2868 } /* if (buf) */
2869 else
2874 ReturnVoid("BitMap::PutPattern");
2877 /****************************************************************************************/
2879 VOID BM__Hidd_BitMap__PutImageLUT(OOP_Class *cl, OOP_Object *o,
2880 struct pHidd_BitMap_PutImageLUT *msg)
2882 WORD x, y;
2883 UBYTE *pixarray = (UBYTE *)msg->pixels;
2884 HIDDT_PixelLUT *pixlut = msg->pixlut;
2885 HIDDT_Pixel *lut = pixlut ? pixlut->pixels : NULL;
2886 HIDDT_Pixel *linebuf;
2887 struct HIDDBitMapData *data;
2888 OOP_Object *gc = msg->gc;
2890 data = OOP_INST_DATA(cl, o);
2892 EnterFunc(bug("BitMap::PutImageLUT(x=%d, y=%d, width=%d, height=%d)\n"
2893 , msg->x, msg->y, msg->width, msg->height));
2895 if (msg->width <= 0 || msg->height <= 0)
2896 return;
2898 linebuf = AllocVec(msg->width * sizeof(HIDDT_Pixel), MEMF_PUBLIC);
2900 for(y = 0; y < msg->height; y++)
2902 if (linebuf)
2904 if (lut)
2906 for(x = 0; x < msg->width; x++)
2908 linebuf[x] = lut[pixarray[x]];
2911 else
2913 for(x = 0; x < msg->width; x++)
2915 linebuf[x] = pixarray[x];
2918 pixarray += msg->modulo;
2920 HIDD_BM_PutImage(o,
2921 msg->gc,
2922 (UBYTE *)linebuf,
2924 msg->x,
2925 msg->y + y,
2926 msg->width,
2928 vHidd_StdPixFmt_Native32);
2930 } /* if (linebuf) */
2931 else
2933 ULONG old_fg;
2935 /* Preserve old fg pen */
2936 old_fg = GC_FG(gc);
2938 if (lut)
2940 for(x = 0; x < msg->width; x++)
2942 GC_FG(gc) = lut[pixarray[x]];
2943 HIDD_BM_DrawPixel(o, gc, msg->x + x, msg->y + y);
2946 else
2948 for(x = 0; x < msg->width; x++)
2950 GC_FG(gc) = pixarray[x];
2951 HIDD_BM_DrawPixel(o, gc, msg->x + x, msg->y + y);
2954 GC_FG(gc) = old_fg;
2956 pixarray += msg->modulo;
2958 } /* if (linebuf) else ... */
2960 } /* for(y = 0; y < msg->height; y++) */
2962 if (linebuf) FreeVec(linebuf);
2964 ReturnVoid("BitMap::PutImageLUT");
2967 VOID BM__Hidd_BitMap__PutTranspImageLUT(OOP_Class *cl, OOP_Object *o,
2968 struct pHidd_BitMap_PutTranspImageLUT *msg)
2970 WORD x, y;
2971 UBYTE *pixarray = (UBYTE *)msg->pixels;
2972 UBYTE transparent = msg->transparent;
2973 HIDDT_PixelLUT *pixlut = msg->pixlut;
2974 HIDDT_Pixel *lut = pixlut ? pixlut->pixels : NULL;
2975 HIDDT_Pixel *buf, *xbuf;
2976 struct HIDDBitMapData *data;
2977 PIXBUF_DECLARE_VARS
2979 data = OOP_INST_DATA(cl, o);
2981 EnterFunc(bug("BitMap::PutTranspImageLUT(x=%d, y=%d, width=%d, height=%d)\n"
2982 , msg->x, msg->y, msg->width, msg->height));
2984 if (msg->width <= 0 || msg->height <= 0)
2985 return;
2987 PIXBUF_ALLOC(buf, msg->width * sizeof(HIDDT_Pixel), msg->height);
2989 if (buf)
2991 HIDDT_DrawMode old_drmd = GC_DRMD(msg->gc);
2992 GC_DRMD(msg->gc) = vHidd_GC_DrawMode_Copy;
2994 xbuf = buf;
2996 for(y = msg->y; y < msg->y + msg->height; y++)
2998 if (PIXBUF_TIME_TO_START_PROCESS)
3000 WORD height = PIXBUF_LINES_TO_PROCESS;
3002 HIDD_BM_GetImage(o,
3003 (UBYTE *)buf,
3004 msg->width * sizeof(HIDDT_Pixel),
3005 msg->x,
3007 msg->width,
3008 height,
3009 vHidd_StdPixFmt_Native32);
3012 if (lut)
3014 for(x = 0; x < msg->width; x++)
3016 UBYTE pix = *pixarray++;
3018 if (pix != transparent)
3020 xbuf[x] = lut[pix];
3023 } /* for(x = 0; x < msg->width; x++) */
3025 else
3027 for(x = 0; x < msg->width; x++)
3029 UBYTE pix = *pixarray++;
3031 if (pix != transparent)
3033 xbuf[x] = pix;
3036 } /* for(x = 0; x < msg->width; x++) */
3040 if (PIXBUF_TIME_TO_END_PROCESS)
3042 LONG height = PIXBUF_LINES_TO_PROCESS;
3044 HIDD_BM_PutImage(o,
3045 msg->gc,
3046 (UBYTE *)buf,
3047 msg->width * sizeof(HIDDT_Pixel),
3048 msg->x,
3049 y - height + 1,
3050 msg->width,
3051 height,
3052 vHidd_StdPixFmt_Native32);
3053 xbuf = buf;
3055 else
3057 xbuf += msg->width;
3060 pixarray = ((UBYTE *)pixarray + msg->modulo - msg->width);
3062 PIXBUF_NEXT_LINE;
3065 } /* for(y = msg->y; y < msg->y + msg->height; y++) */
3067 GC_DRMD(msg->gc) = old_drmd;
3069 PIXBUF_FREE(buf);
3071 } /* if (buf) */
3073 ReturnVoid("BitMap::PutTranspImageLUT");
3076 /****************************************************************************************/
3078 VOID BM__Hidd_BitMap__GetImageLUT(OOP_Class *cl, OOP_Object *o,
3079 struct pHidd_BitMap_GetImageLUT *msg)
3081 WORD x, y;
3082 UBYTE *pixarray = (UBYTE *)msg->pixels;
3083 HIDDT_PixelLUT *pixlut = msg->pixlut;
3084 HIDDT_Pixel *lut = pixlut ? pixlut->pixels : NULL;
3085 HIDDT_Pixel *linebuf;
3086 struct HIDDBitMapData *data;
3088 data = OOP_INST_DATA(cl, o);
3090 EnterFunc(bug("BitMap::GetImageLUT(x=%d, y=%d, width=%d, height=%d)\n"
3091 , msg->x, msg->y, msg->width, msg->height));
3093 linebuf = AllocVec(msg->width * sizeof(HIDDT_Pixel), MEMF_PUBLIC);
3095 for(y = 0; y < msg->height; y++)
3097 if (linebuf)
3099 HIDD_BM_GetImage(o,
3100 (UBYTE *)linebuf,
3102 msg->x,
3103 msg->y + y,
3104 msg->width,
3106 vHidd_StdPixFmt_Native32);
3107 if (lut)
3109 #warning "This is wrong, but HIDD_BM_GetImageLUT on hi/truecolor screens does not really make sense anyway"
3110 for(x = 0; x < msg->width; x++)
3112 pixarray[x] = (UBYTE)linebuf[x];
3115 else
3117 for(x = 0; x < msg->width; x++)
3119 pixarray[x] = (UBYTE)linebuf[x];
3122 pixarray += msg->modulo;
3124 } /* if (linebuf) */
3125 else
3127 if (lut)
3129 #warning "This is wrong, but HIDD_BM_GetImageLUT on hi/truecolor screens does not really make sense anyway"
3130 for(x = 0; x < msg->width; x++)
3132 pixarray[x] = (UBYTE)HIDD_BM_GetPixel(o, msg->x + x, msg->y + y);
3135 else
3137 for(x = 0; x < msg->width; x++)
3139 pixarray[x] = (UBYTE)HIDD_BM_GetPixel(o, msg->x + x, msg->y + y);
3143 pixarray += msg->modulo;
3145 } /* if (linebuf) else ... */
3147 } /* for(y = 0; y < msg->height; y++) */
3149 if (linebuf) FreeVec(linebuf);
3151 ReturnVoid("BitMap::GetImageLUT");
3154 /****************************************************************************************/
3156 VOID BM__Hidd_BitMap__BlitColorExpansion(OOP_Class *cl, OOP_Object *o,
3157 struct pHidd_BitMap_BlitColorExpansion *msg)
3159 ULONG cemd;
3160 ULONG fg, bg;
3161 LONG x, y;
3163 OOP_Object *gc = msg->gc;
3165 EnterFunc(bug("BitMap::BlitColorExpansion(srcBM=%p, srcX=%d, srcY=%d, destX=%d, destY=%d, width=%d, height=%d)\n",
3166 msg->srcBitMap, msg->srcX, msg->srcY, msg->destX, msg->destY, msg->width, msg->height));
3168 cemd = GC_COLEXP(gc);
3169 fg = GC_FG(gc);
3170 bg = GC_BG(gc);
3172 /* bug("------------- Blit_ColExp: (%d, %d, %d, %d, %d, %d) cemd=%d, fg=%p, bg=%p -------------\n"
3173 , msg->srcX, msg->srcY, msg->destX, msg->destY, msg->width, msg->height
3174 , cemd, fg, bg);
3176 for (y = 0; y < msg->height; y ++)
3178 for (x = 0; x < msg->width; x ++)
3180 ULONG is_set;
3182 /* Pixel value is either 0 or 1 for BM of depth 1 */
3183 is_set = HIDD_BM_GetPixel(msg->srcBitMap, x + msg->srcX, y + msg->srcY);
3186 if (is_set)
3187 bug("#");
3188 else
3189 bug(" ");
3191 if (is_set)
3193 HIDD_BM_DrawPixel(o, gc, x + msg->destX, y + msg->destY);
3195 else
3197 if (cemd & vHidd_GC_ColExp_Opaque)
3199 /* Write bixel with BG pen */
3200 GC_FG(gc) = bg;
3201 HIDD_BM_DrawPixel(o, gc, x + msg->destX, y + msg->destY);
3202 /* Reset to FG pen */
3203 GC_FG(gc) = fg;
3206 } /* if () */
3208 } /* for (each x) */
3210 bug("\n");
3212 } /* for ( each y ) */
3214 ReturnVoid("BitMap::BlitColorExpansion");
3218 /****************************************************************************************/
3220 ULONG BM__Hidd_BitMap__BytesPerLine(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_BytesPerLine *msg)
3222 ULONG bpl;
3224 switch (msg->pixFmt)
3226 case vHidd_StdPixFmt_Native32:
3227 bpl = sizeof (HIDDT_Pixel) * msg->width;
3228 break;
3230 case vHidd_StdPixFmt_Native:
3232 struct HIDDBitMapData *data;
3234 data = OOP_INST_DATA(cl, o);
3236 bpl = ((HIDDT_PixelFormat *)data->prot.pixfmt)->bytes_per_pixel * msg->width;
3237 break;
3240 default:
3242 OOP_Object *pf;
3243 struct HIDDBitMapData *data;
3245 data = OOP_INST_DATA(cl, o);
3247 pf = HIDD_Gfx_GetPixFmt(data->gfxhidd, msg->pixFmt);
3249 if (NULL == pf)
3251 D(bug("!!! COULD NOT GET STD PIXFMT IN BitMap::BytesPerLine() !!!\n"));
3252 return 0;
3255 bpl = ((HIDDT_PixelFormat *)pf)->bytes_per_pixel * msg->width;
3256 break;
3260 return bpl;
3264 /****************************************************************************************/
3267 This makes it easier to create a subclass of the graphics hidd.
3268 It only allowd to use this method in the p_RootNew method of a
3269 bitmap subclass.
3272 /****************************************************************************************/
3274 VOID BM__Root__Set(OOP_Class *cl, OOP_Object *obj, struct pRoot_Set *msg)
3276 struct HIDDBitMapData *data = OOP_INST_DATA(cl, obj);
3277 struct TagItem *tag, *tstate;
3278 ULONG idx;
3280 /* EnterFunc(bug("BitMap::Set()\n"));
3282 tstate = msg->attrList;
3283 while((tag = NextTagItem(&tstate)))
3285 if(IS_BITMAP_ATTR(tag->ti_Tag, idx))
3287 switch(idx)
3289 case aoHidd_BitMap_Width:
3290 data->width = tag->ti_Data;
3291 break;
3293 case aoHidd_BitMap_Height:
3294 data->height = tag->ti_Data;
3295 break;
3297 #if 0
3298 case aoHidd_BitMap_ColorTab:
3299 data->colorTab = (APTR)tag->ti_Data;
3300 break;
3301 #endif
3303 default:
3304 D(bug("!!! TRYING TO SET NONSETTABLE BITMAP ATTR %d !!!\n", idx));
3305 break;
3311 return;
3314 /****************************************************************************************/
3316 OOP_Object *BM__Hidd_BitMap__SetColorMap(OOP_Class *cl, OOP_Object *o,
3317 struct pHidd_BitMap_SetColorMap *msg)
3319 struct HIDDBitMapData *data;
3320 OOP_Object *old;
3322 data = OOP_INST_DATA(cl, o);
3324 old = data->colmap;
3325 data->colmap = msg->colorMap;
3327 return old;
3330 /****************************************************************************************/
3332 HIDDT_Pixel BM__Hidd_BitMap__MapColor(OOP_Class *cl, OOP_Object *o,
3333 struct pHidd_BitMap_MapColor *msg)
3335 HIDDT_PixelFormat *pf = BM_PIXFMT(o);
3337 HIDDT_Pixel red = msg->color->red;
3338 HIDDT_Pixel green = msg->color->green;
3339 HIDDT_Pixel blue = msg->color->blue;
3340 HIDDT_Pixel alpha = msg->color->alpha;
3342 /* This code assumes that sizeof (HIDDT_Pixel is a multimple of sizeof(col->#?)
3343 which should be true for most (all ?) systems. (I have never heard
3344 of any system with for example 3 byte types.
3347 if (IS_TRUECOLOR(pf))
3349 if (HIDD_PF_SWAPPIXELBYTES(pf))
3351 #warning "BM__Hidd_BitMap__MapColor assuming that SwapPixelBytes flag only set for 2-byte/16-bit pixel formats"
3353 HIDDT_Pixel pixel = MAP_RGBA(red, green, blue, alpha, pf);
3355 msg->color->pixval = SWAPBYTES_WORD(pixel);
3357 else
3359 msg->color->pixval = MAP_RGBA(red, green, blue, alpha, pf);
3362 else
3364 struct HIDDBitMapData *data = OOP_INST_DATA(cl, o);
3365 HIDDT_Color *ctab;
3367 ctab = ((HIDDT_ColorLUT *)data->colmap)->colors;
3368 /* Search for the best match in the color table */
3369 #warning Implement this
3373 return msg->color->pixval;
3376 /****************************************************************************************/
3378 VOID BM__Hidd_BitMap__UnmapPixel(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_UnmapPixel *msg)
3381 HIDDT_PixelFormat *pf = BM_PIXFMT(o);
3383 if (IS_TRUECOLOR(pf))
3385 HIDDT_Pixel pixel = msg->pixel;
3387 if (HIDD_PF_SWAPPIXELBYTES(pf))
3389 #warning "bitmap_unmappixel assuming that SwapPixelBytes flag only set for 2-byte/16-bit pixel formats"
3390 pixel = SWAPBYTES_WORD(pixel);
3393 msg->color->red = RED_COMP (pixel, pf);
3394 msg->color->green = GREEN_COMP (pixel, pf);
3395 msg->color->blue = BLUE_COMP (pixel, pf);
3396 msg->color->alpha = ALPHA_COMP (pixel, pf);
3398 else
3400 struct HIDDBitMapData *data = OOP_INST_DATA(cl, o);
3401 HIDDT_ColorLUT *clut;
3403 clut = (HIDDT_ColorLUT *)data->colmap;
3407 #warning Use CLUT shift and CLUT mask here
3408 if (msg->pixel < 0 || msg->pixel >= clut->entries)
3409 return;
3411 *msg->color = clut->colors[msg->pixel];
3415 /* Unnecesart, but ... */
3416 msg->color->pixval = msg->pixel;
3419 /****************************************************************************************/
3421 BOOL BM__Hidd_BitMap__ObtainDirectAccess(OOP_Class *cl, OOP_Object *o,
3422 struct pHidd_BitMap_ObtainDirectAccess *msg)
3424 /* Default implementation of direct access funcs. Just return FALSE */
3425 return FALSE;
3428 /****************************************************************************************/
3430 VOID BM__Hidd_BitMap__ReleaseDirectAccess(OOP_Class *cl, OOP_Object *o,
3431 struct pHidd_BitMap_ReleaseDirectAccess *msg)
3433 D(bug("!!! BitMap BaseClasse ReleaseDirectAccess() called !!!\n"));
3434 D(bug("!!! This should never happen and is probably due to a buggy implementation in the subclass !!!\n"));
3436 return;
3439 /****************************************************************************************/
3441 VOID BM__Hidd_BitMap__BitMapScale(OOP_Class * cl, OOP_Object *o,
3442 struct pHidd_BitMap_BitMapScale * msg)
3444 struct BitScaleArgs *bsa = msg->bsa;
3445 ULONG *srcbuf, *dstbuf;
3446 LONG srcline = -1;
3447 UWORD *linepattern;
3448 ULONG count;
3449 UWORD ys = bsa->bsa_SrcY;
3450 ULONG xs = bsa->bsa_SrcX;
3451 ULONG dyd = bsa->bsa_DestHeight;
3452 ULONG dxd = bsa->bsa_DestWidth;
3453 LONG accuys = dyd;
3454 LONG accuxs = dxd;
3455 ULONG dxs = bsa->bsa_SrcWidth;
3456 ULONG dys = bsa->bsa_SrcHeight;
3457 LONG accuyd = - (dys >> 1);
3458 LONG accuxd = - (dxs >> 1);
3459 ULONG x;
3461 if ((srcbuf = AllocVec(bsa->bsa_SrcWidth * sizeof(ULONG), 0)) == NULL)
3462 return;
3464 if ((dstbuf = AllocVec(bsa->bsa_DestWidth * sizeof(ULONG), 0)) == NULL) {
3465 FreeVec(srcbuf);
3466 return;
3469 if ((linepattern = (UWORD *) AllocVec(bsa->bsa_DestWidth * sizeof(UWORD), 0)) == NULL) {
3470 FreeVec(dstbuf);
3471 FreeVec(srcbuf);
3472 return;
3475 count = 0;
3476 while (count < bsa->bsa_DestWidth) {
3477 accuxd += dxs;
3478 while (accuxd > accuxs) {
3479 xs++;
3480 accuxs += dxd;
3483 linepattern[count] = xs;
3485 count++;
3488 count = bsa->bsa_DestY;
3489 while (count < bsa->bsa_DestHeight + bsa->bsa_DestY) {
3490 accuyd += dys;
3491 while (accuyd > accuys) {
3492 ys++;
3493 accuys += dyd;
3496 if (srcline != ys) {
3497 HIDD_BM_GetImage(msg->src, (UBYTE *) srcbuf, bsa->bsa_SrcWidth * sizeof(ULONG), bsa->bsa_SrcX, bsa->bsa_SrcY + ys, bsa->bsa_SrcWidth, 1, vHidd_StdPixFmt_Native32);
3498 srcline = ys;
3500 for (x = 0; x < bsa->bsa_DestWidth; x++)
3501 dstbuf[x] = srcbuf[linepattern[x]];
3504 HIDD_BM_PutImage(msg->dst, msg->gc, (UBYTE *) dstbuf, bsa->bsa_DestWidth * sizeof(ULONG), bsa->bsa_DestX, bsa->bsa_DestY + count, bsa->bsa_DestWidth, 1, vHidd_StdPixFmt_Native32);
3506 count++;
3509 FreeVec(linepattern);
3511 FreeVec(dstbuf);
3512 FreeVec(srcbuf);
3515 HIDDT_RGBConversionFunction BM__Hidd_BitMap__SetRGBConversionFunction(OOP_Class * cl, OOP_Object *o,
3516 struct pHidd_BitMap_SetRGBConversionFunction * msg)
3518 HIDDT_RGBConversionFunction old;
3520 if ((msg->srcPixFmt < FIRST_RGB_STDPIXFMT) ||
3521 (msg->dstPixFmt < FIRST_RGB_STDPIXFMT) ||
3522 (msg->srcPixFmt > LAST_RGB_STDPIXFMT) ||
3523 (msg->dstPixFmt > LAST_RGB_STDPIXFMT))
3525 return (HIDDT_RGBConversionFunction)-1;
3527 else
3529 ObtainSemaphore(&CSD(cl)->rgbconvertfuncs_sem);
3530 old = CSD(cl)->rgbconvertfuncs[msg->srcPixFmt - FIRST_RGB_STDPIXFMT][msg->dstPixFmt - FIRST_RGB_STDPIXFMT];
3531 CSD(cl)->rgbconvertfuncs[msg->srcPixFmt - FIRST_RGB_STDPIXFMT][msg->dstPixFmt - FIRST_RGB_STDPIXFMT] = msg->function;
3532 ReleaseSemaphore(&CSD(cl)->rgbconvertfuncs_sem);
3534 return old;
3538 /****************************************************************************************/
3540 /* private ! */
3542 /****************************************************************************************/
3544 BOOL BM__Hidd_BitMap__SetBitMapTags(OOP_Class *cl, OOP_Object *o,
3545 struct pHidd_BitMap_SetBitMapTags *msg)
3547 struct HIDDBitMapData *data;
3548 OOP_Object *pf;
3549 IPTR attrs[num_Hidd_BitMap_Attrs];
3550 DECLARE_ATTRCHECK(bitmap);
3552 data = OOP_INST_DATA(cl, o);
3554 if (0 != OOP_ParseAttrs(msg->bitMapTags
3555 , attrs, num_Hidd_BitMap_Attrs
3556 , &ATTRCHECK(bitmap), HiddBitMapAttrBase))
3558 D(bug("!!! FAILED PARSING IN BitMap::SetBitMapTags !!!\n"));
3559 return FALSE;
3562 if (GOT_BM_ATTR(PixFmtTags))
3564 /* Allready a pixfmt registered ? */
3566 pf = HIDD_Gfx_RegisterPixFmt(data->gfxhidd, (struct TagItem *)attrs[AO(PixFmtTags)]);
3567 if (NULL == pf)
3568 return FALSE;
3570 if (data->pf_registered)
3571 HIDD_Gfx_ReleasePixFmt(data->gfxhidd, data->prot.pixfmt);
3573 data->prot.pixfmt = pf;
3577 if (GOT_BM_ATTR(Width))
3578 data->width = attrs[AO(Width)];
3580 if (GOT_BM_ATTR(Height))
3581 data->height = attrs[AO(Height)];
3583 return TRUE;
3586 /****************************************************************************************/
3588 #ifndef AROS_CREATE_ROM
3589 # define STATIC_MID static OOP_MethodID mid
3590 #else
3591 # define STATIC_MID OOP_MethodID mid = 0
3592 #endif
3594 /****************************************************************************************/
3596 BOOL HIDD_BitMap_SetBitMapTags(OOP_Object *o, struct TagItem *bitMapTags)
3598 STATIC_MID;
3599 struct pHidd_BitMap_SetBitMapTags p, *msg = &p;
3601 if (!mid) mid = OOP_GetMethodID(IID_Hidd_BitMap, moHidd_BitMap_SetBitMapTags);
3603 p.mID = mid;
3605 p.bitMapTags = bitMapTags;
3607 return (BOOL)OOP_DoMethod(o, (OOP_Msg)msg);
3610 /****************************************************************************************/