2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 Desc: Graphics bitmap class implementation.
9 /****************************************************************************************/
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>
21 #include <graphics/text.h>
22 #include <graphics/scale.h>
24 #include <hidd/graphics.h>
26 #include "graphics_intern.h"
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:
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 \
81 #define PIXBUF_ALLOC(buf,bytesperline,height) \
83 __buflines = PIXBUFBYTES / (bytesperline); \
84 if (__buflines == 0) \
88 else if (__buflines > __height) \
90 __buflines = __height; \
92 buf = AllocVec((bytesperline) * __buflines, MEMF_PUBLIC); \
93 if (!buf && (__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 \
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
);
125 struct TagItem colmap_tags
[] =
127 { aHidd_ColorMap_NumEntries
, 16 },
130 struct HIDDBitMapData
*data
;
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
));
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
));
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
)));
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
)];
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"));
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
));
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
);
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
;
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"));
240 data
->width
= attrs
[AO(Width
)];
241 data
->height
= attrs
[AO(Height
)];
242 data
->prot
.pixfmt
= (OOP_Object
*)attrs
[AO(PixFmt
)];
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
)
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
)
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
)
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
)
303 dispose_mid
= OOP_GetMethodID(IID_Root
, moRoot_Dispose
);
305 OOP_CoerceMethod(cl
, obj
, (OOP_Msg
)&dispose_mid
);
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
);
345 EnterFunc(bug("BitMap::Get() attrID: %i storage: %p\n", msg
->attrID
, msg
->storage
));
347 if(IS_BITMAP_ATTR(msg
->attrID
, idx
))
351 case aoHidd_BitMap_Width
:
352 *msg
->storage
= data
->width
;
353 D(bug(" width: %i\n", data
->width
));
356 case aoHidd_BitMap_Height
:
357 *msg
->storage
= data
->height
;
360 case aoHidd_BitMap_Displayable
:
361 *msg
->storage
= (IPTR
) data
->displayable
;
364 case aoHidd_BitMap_PixFmt
:
365 *msg
->storage
= (IPTR
)data
->prot
.pixfmt
;
368 case aoHidd_BitMap_Friend
:
369 *msg
->storage
= (IPTR
)data
->friend;
372 case aoHidd_BitMap_ColorMap
:
373 *msg
->storage
= (IPTR
)data
->colmap
;
377 case aoHidd_BitMap_Depth
:
378 if (NULL
!= data
->prot
.pixfmt
)
380 *msg
->storage
= ((HIDDT_PixelFormat
*)data
->prot
.pixfmt
)->depth
;
384 *msg
->storage
= data
->reqdepth
;
390 case aoHidd_BitMap_GfxHidd
:
391 *msg
->storage
= (IPTR
)data
->gfxhidd
;
394 case aoHidd_BitMap_ModeID
:
395 *msg
->storage
= data
->modeid
;
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
;
409 D(bug("UNKNOWN ATTR IN BITMAP BASECLASS: %d\n", idx
));
410 OOP_DoSuperMethod(cl
, obj
, (OOP_Msg
) msg
);
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 },
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
)
456 /* Use the colormap class to set the colors */
457 return HIDD_CM_SetColors(data
->colmap
, msg
->colors
,
458 msg
->firstColor
, msg
->numColors
,
463 /*****************************************************************************************
468 moHidd_BitMap_DrawPixel
471 OOP_DoMethod(obj, WORD x, WORD y);
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.
480 (x,y) - coordinates of the pixel in hidd units
491 GROUP=HIDD_Gfx_Pixel, GROUP=HIDD_Gfx_SetAttributes
496 - Support for shapeplane.
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
;
506 HIDDT_Pixel writeMask
;
508 #if USE_FAST_PUTPIXEL
509 struct pHidd_BitMap_PutPixel p
;
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
518 data->colMask = 001111
522 writeMask = ~data->colMask & dest
526 dest = data->fg && dest = 010100
529 dest = dest & (writeMask | data->ColMask)
530 = 010100 & (100000 | 001111)
535 dest = dest | writeMask;
546 #if OPTIMIZE_DRAWPIXEL_FOR_COPY
547 if (vHidd_GC_DrawMode_Copy
== mode
&& GC_COLMASK(gc
) == ~0)
555 dest
= HIDD_BM_GetPixel(obj
, msg
->x
, msg
->y
);
556 writeMask
= ~GC_COLMASK(gc
) & dest
;
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
571 #if USE_FAST_PUTPIXEL
572 p
.mID
= CSD(cl
)->putpixel_mid
;
579 HIDD_BM_PutPixel(obj
, msg
->x
, msg
->y
, val
);
582 /* ReturnInt("BitMap::DrawPixel ", ULONG, 1); */ /* in quickmode return always 1 */
587 /*****************************************************************************************
595 OOP_DoMethod(obj, WORD x1, WORD y1, WORD x2, WORD y2);
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
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
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
;
634 UWORD maskLine
; /* for line pattern */
635 ULONG fg
; /* foreground pen */
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
));
645 doclip
= GC_DOCLIP(gc
);
646 opaque
= (GC_COLEXP(gc
) & vHidd_GC_ColExp_Opaque
) ? TRUE
: FALSE
;
649 maskLine
= 1 << GC_LINEPATCNT(gc
);
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
;
661 x1
= msg
->x1
; x2
= msg
->x2
;
664 if (msg
->y1
> msg
->y2
)
666 y1
= msg
->y2
; y2
= msg
->y1
;
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 */
693 Horizontal line drawing code.
697 /* Don't swap coordinates if x2 < x1! Because of linepattern! */
710 for(i
= x1
; i
!= x2
; i
+= dx
)
714 if (!doclip
|| !POINT_OUTSIDE_CLIP(gc
, i
, y
))
716 if(GC_LINEPAT(gc
) & maskLine
)
718 HIDD_BM_DrawPixel(obj
, gc
, i
, y
);
722 GC_FG(gc
) = GC_BG(gc
);
723 HIDD_BM_DrawPixel(obj
, gc
, i
, y
);
728 maskLine
= maskLine
>> 1;
729 if (!maskLine
) maskLine
= 1L << 15;
735 Vertical line drawing code.
739 /* Don't swap coordinates if y2 < y1! Because of linepattern! */
752 for(i
= y1
; i
!= y2
; i
+= dy
)
755 if (!doclip
|| !POINT_OUTSIDE_CLIP(gc
, x
, i
))
757 if(GC_LINEPAT(gc
) & maskLine
)
759 HIDD_BM_DrawPixel(obj
, gc
, x
, i
);
763 GC_FG(gc
) = GC_BG(gc
);
764 HIDD_BM_DrawPixel(obj
, gc
, x
, i
);
769 maskLine
= maskLine
>> 1;
770 if (!maskLine
) maskLine
= 1L << 15;
777 Generic line drawing code.
779 /* Calculate slope */
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 */
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 */
807 for(i
= 0; i
<= dx
; i
++)
810 if (!doclip
|| !POINT_OUTSIDE_CLIP(gc
, x
, y
))
812 if(GC_LINEPAT(gc
) & maskLine
)
814 HIDD_BM_DrawPixel(obj
, gc
, x
, y
);
818 GC_FG(gc
) = GC_BG(gc
);
819 HIDD_BM_DrawPixel(obj
, gc
, x
, y
);
844 maskLine
= maskLine
>> 1;
845 if (!maskLine
) maskLine
= 1L << 15;
850 ReturnVoid("BitMap::DrawLine ");
853 /*****************************************************************************************
861 OOP_DoMethod(obj, WORD minX, WORD minY, WORD maxX, WORD maxY);
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.
871 minX, minY - upper left corner of the rectangle in hidd units
872 maxX, maxY - lower right corner of the rectangle in hidd units
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
;
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 /*****************************************************************************************
920 OOP_DoMethod(obj, WORD minX, WORD minY, WORD maxX, WORD maxY);
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.
930 minX, minY - upper left corner of the rectangle in hidd units
931 maxX, maxY - lower right corner of the rectangle in hidd units
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
;
960 EnterFunc(bug("BitMap::FillRect()"));
962 linepat
= GC_LINEPAT(gc
);
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()
983 OOP_DoMethod(obj, WORD x, WORD y, UWORD rx, UWORD ry);
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.
991 x,y - center point in hidd units
992 rx,ry - ry and ry radius in hidd units
1001 Because of overflow the current code do not work with big
1002 values of rx and ry.
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 */
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
);
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 */
1066 if (d1
< 0) /* move straight up */
1071 else /* move up and left */
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 */
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
);
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
);
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
);
1115 x
--; /* always move left here */
1117 if (d2
< 0) /* move up and left */
1121 d2
= d2
+ t9
+ t5
- t8
;
1123 else /* move straight left */
1131 ReturnVoid("BitMap::DrawEllipse");
1134 /*****************************************************************************************
1136 BitMap::FillEllipse()
1142 OOP_DoMethod(obj, WORD x, WORD y, UWORD rx, UWORD ry);
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.
1150 x,y - center point in hidd units
1151 rx,ry - ry and ry radius in hidd units
1159 Because of overflow the current code do not work with big
1160 values of rx and ry.
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 */
1197 if (d1
< 0) /* move straight up */
1202 else /* move up and left */
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 */
1219 if (d2
< 0) /* move up and left */
1223 d2
= d2
+ t9
+ t5
- t8
;
1225 else /* move straight left */
1232 ReturnVoid("BitMap::FillEllipse");
1235 /*****************************************************************************************
1238 BitMap::DrawPolygon()
1244 OOP_DoMethod(obj, UWORD n, WORD coords[2*n]);
1247 Draws a hollow polygon from the list of coordinates in coords[].
1248 The function does not clip the polygon against the drawing area.
1251 n - number of coordinate pairs
1252 coords - array of n (x, y) coordinates in hidd units
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
;
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()
1298 OOP_DoMethod(obj, UWORD n, WORD coords[2*n]);
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.
1308 n - number of coordinate pairs
1309 coords - array of n (x, y) coordinates in hidd units
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 /*****************************************************************************************
1348 OOP_DoMethod(obj, WORD x, WORD y, STRPTR text, UWORD length);
1351 Draws the first length characters of text at (x, y).
1352 The function does not clip the text against the drawing area.
1355 x, y - Position to start drawing in hidd units. The x
1356 coordinate is relativ to the left side of the
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
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
;
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
;
1399 EnterFunc(bug("BitMap::DrawText()"));
1401 for(i
= 0; i
< msg
->length
; i
++)
1405 if((ch
< font
->tf_LoChar
) || (ch
> font
->tf_HiChar
))
1407 ch
= font
->tf_HiChar
- font
->tf_LoChar
+ 1;
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 */
1425 for(fy
= 0; fy
< font
->tf_YSize
; fy
++)
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
);
1441 if(font
->tf_Flags
& FPF_PROPORTIONAL
)
1443 xMem
= xMem
+ ((UWORD
*) font
->tf_CharSpace
)[ch
];
1447 xMem
= xMem
+ font
->tf_XSize
;
1451 ReturnVoid("BitMap::DrawText");
1454 /*****************************************************************************************
1456 BitMap::DrawFillText ()
1462 OOP_DoMethod(obj, WORD x, WORD y, STRPTR text, UWORD length);
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.
1470 x, y - Position to start drawing in hidd units. The x
1471 coordinate is relativ to the left side of the
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
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 /*****************************************************************************************
1514 OOP_DoMethod(obj, HIDDT_Span span);
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.
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 /*****************************************************************************************
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.
1584 *****************************************************************************************/
1586 VOID
BM__Hidd_BitMap__Clear(OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_BitMap_Clear
*msg
)
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
)
1612 struct HIDDBitMapData
*data
;
1615 data
= OOP_INST_DATA(cl
, o
);
1619 case vHidd_StdPixFmt_Native
:
1620 OOP_GetAttr(data
->prot
.pixfmt
, aHidd_PixFmt_BytesPerPixel
, &bpp
);
1623 case vHidd_StdPixFmt_Native32
:
1624 bpp
= sizeof (HIDDT_Pixel
);
1628 pf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, stdpf
);
1632 D(bug("!!! INVALID PIXFMT IN BitMap::PutImage(): %d !!!\n", stdpf
));
1636 OOP_GetAttr(pf
, aHidd_PixFmt_BytesPerPixel
, &bpp
);
1644 /****************************************************************************************/
1646 VOID
BM__Hidd_BitMap__GetImage(OOP_Class
*cl
, OOP_Object
*o
,
1647 struct pHidd_BitMap_GetImage
*msg
)
1650 UBYTE
*pixarray
= (UBYTE
*)msg
->pixels
;
1651 APTR ppixarray
= &pixarray
;
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
);
1664 D(bug("!!! INVALID PIXFMT IN BitMap::PutImage(): %d !!!\n", 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
);
1688 *((UWORD
*)pixarray
) = pix
;
1694 pixarray
[0] = (pix
>> 16) & 0xFF;
1695 pixarray
[1] = (pix
>> 8) & 0xFF;
1696 pixarray
[2] = pix
& 0xFF;
1698 pixarray
[0] = pix
& 0xFF;
1699 pixarray
[1] = (pix
>> 8) & 0xFF;
1700 pixarray
[2] = (pix
>> 16) & 0xFF;
1706 *(ULONG
*)pixarray
= pix
;
1713 pixarray
+= (msg
->modulo
- msg
->width
* bpp
);
1721 APTR buf
, srcPixels
;
1723 dstpf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, msg
->pixFmt
);
1725 buf
= srcPixels
= AllocVec(msg
->width
* sizeof(HIDDT_Pixel
), MEMF_PUBLIC
);
1728 for(y
= 0; y
< msg
->height
; y
++)
1737 vHidd_StdPixFmt_Native
);
1739 HIDD_BM_ConvertPixels(o
,
1741 (HIDDT_PixelFormat
*)data
->prot
.pixfmt
,
1744 (HIDDT_PixelFormat
*)dstpf
,
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
)
1767 UBYTE
*pixarray
= (UBYTE
*)msg
->pixels
;
1768 APTR ppixarray
= &pixarray
;
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)
1782 bpp
= getpixfmtbpp(cl
, o
, msg
->pixFmt
);
1785 D(bug("!!! INVALID PIXFMT IN BitMap::PutImage(): %d !!!\n", msg
->pixFmt
));
1791 case vHidd_StdPixFmt_Native
:
1792 case vHidd_StdPixFmt_Native32
:
1794 /* Preserve old fg pen */
1797 for (y
= 0; y
< msg
->height
; y
++)
1799 for (x
= 0; x
< msg
->width
; x
++)
1801 register HIDDT_Pixel pix
= 0;
1806 pix
= *((UBYTE
*)pixarray
);
1811 pix
= *((UWORD
*)pixarray
);
1817 pix
= ((UBYTE
*)pixarray
)[0] << 16;
1818 pix
|= ((UBYTE
*)pixarray
)[1] << 8;
1819 pix
|= ((UBYTE
*)pixarray
)[2];
1821 pix
= ((UBYTE
*)pixarray
)[2] << 16;
1822 pix
|= ((UBYTE
*)pixarray
)[1] << 8;
1823 pix
|= ((UBYTE
*)pixarray
)[0];
1829 pix
= *((ULONG
*)pixarray
); pixarray
+= 4;
1836 HIDD_BM_DrawPixel(o
, gc
, x
+ msg
->x
, y
+ msg
->y
);
1838 pixarray
+= (msg
->modulo
- msg
->width
* bpp
);
1847 APTR buf
, destPixels
;
1849 srcpf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, msg
->pixFmt
);
1851 buf
= destPixels
= AllocVec(msg
->width
* sizeof(HIDDT_Pixel
), MEMF_PUBLIC
);
1854 for(y
= 0; y
< msg
->height
; y
++)
1856 HIDD_BM_ConvertPixels(o
,
1858 (HIDDT_PixelFormat
*)srcpf
,
1861 (HIDDT_PixelFormat
*)data
->prot
.pixfmt
,
1875 vHidd_StdPixFmt_Native
);
1882 } /* switch(msg->pixFmt) */
1884 ReturnVoid("BitMap::PutImage");
1887 /****************************************************************************************/
1890 __attribute__((always_inline
, const)) do_alpha(int a
, int 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
)
1900 ULONG
*pixarray
= (ULONG
*)msg
->pixels
;
1902 struct HIDDBitMapData
*data
;
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)
1913 PIXBUF_ALLOC(buf
, msg
->width
* sizeof(ULONG
), msg
->height
);
1917 HIDDT_DrawMode old_drmd
= GC_DRMD(msg
->gc
);
1918 GC_DRMD(msg
->gc
) = vHidd_GC_DrawMode_Copy
;
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
;
1930 msg
->width
* sizeof(ULONG
),
1935 vHidd_StdPixFmt_ARGB32
);
1938 for(x
= 0; x
< msg
->width
; x
++)
1942 LONG src_red
, src_green
, src_blue
, src_alpha
;
1943 LONG dst_red
, dst_green
, dst_blue
;
1945 srcpix
= *pixarray
++;
1947 src_red
= (srcpix
& 0x00FF0000) >> 16;
1948 src_green
= (srcpix
& 0x0000FF00) >> 8;
1949 src_blue
= (srcpix
& 0x000000FF);
1950 src_alpha
= (srcpix
& 0xFF000000) >> 24;
1952 src_red
= (srcpix
& 0x0000FF00) >> 8;
1953 src_green
= (srcpix
& 0x00FF0000) >> 16;
1954 src_blue
= (srcpix
& 0xFF000000) >> 24;
1955 src_alpha
= (srcpix
& 0x000000FF);
1960 dst_red
= (destpix
& 0x00FF0000) >> 16;
1961 dst_green
= (destpix
& 0x0000FF00) >> 8;
1962 dst_blue
= (destpix
& 0x000000FF);
1964 dst_red
= (destpix
& 0x0000FF00) >> 8;
1965 dst_green
= (destpix
& 0x00FF0000) >> 16;
1966 dst_blue
= (destpix
& 0xFF000000) >> 24;
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
);
1974 destpix
&= 0xFF000000;
1975 destpix
|= (dst_red
<< 16) + (dst_green
<< 8) + (dst_blue
);
1977 destpix
&= 0x000000FF;
1978 destpix
|= (dst_blue
<< 24) + (dst_green
<< 16) + (dst_red
<< 8);
1983 } /* for(x = 0; x < msg->width; x++) */
1985 if (PIXBUF_TIME_TO_END_PROCESS
)
1987 LONG height
= PIXBUF_LINES_TO_PROCESS
;
1992 msg
->width
* sizeof(ULONG
),
1997 vHidd_StdPixFmt_ARGB32
);
2005 pixarray
= (ULONG
*)((UBYTE
*)pixarray
+ msg
->modulo
- msg
->width
* 4);
2010 } /* for(y = msg->y; y < msg->y + msg->height; y++) */
2012 GC_DRMD(msg
->gc
) = old_drmd
;
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
;
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
++;
2034 src_red
= (srcpix
& 0x00FF0000) >> 16;
2035 src_green
= (srcpix
& 0x0000FF00) >> 8;
2036 src_blue
= (srcpix
& 0x000000FF);
2037 src_alpha
= (srcpix
& 0xFF000000) >> 24;
2039 src_red
= (srcpix
& 0x0000FF00) >> 8;
2040 src_green
= (srcpix
& 0x00FF0000) >> 16;
2041 src_blue
= (srcpix
& 0xFF000000) >> 24;
2042 src_alpha
= (srcpix
& 0x000000FF);
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
)
2077 HIDDT_Pixel
*buf
, *xbuf
, bitmask
;
2078 OOP_Object
*gc
= msg
->gc
;
2079 struct HIDDBitMapData
*data
;
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)
2091 if (GC_COLEXP(gc
) == vHidd_GC_ColExp_Transparent
)
2095 else if (GC_DRMD(gc
) == vHidd_GC_DrawMode_Invert
)
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
);
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
;
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
;
2133 msg
->width
* sizeof(HIDDT_Pixel
),
2138 vHidd_StdPixFmt_Native32
);
2145 for(x
= 0; x
< msg
->width
; x
++)
2147 if (bitword
& mask
) xbuf
[x
] = fg
;
2154 bitword
= AROS_BE2WORD(*array
);
2157 } /* for(x = 0; x < msg->width; x++) */
2160 case 1: /* JAM1 | INVERSVID */
2161 for(x
= 0; x
< msg
->width
; x
++)
2163 if (!(bitword
& mask
)) xbuf
[x
] = fg
;
2170 bitword
= AROS_BE2WORD(*array
);
2173 } /* for(x = 0; x < msg->width; x++) */
2176 case 2: /* COMPLEMENT */
2177 for(x
= 0; x
< msg
->width
; x
++)
2179 if (bitword
& mask
) xbuf
[x
] = ~xbuf
[x
];
2186 bitword
= AROS_BE2WORD(*array
);
2188 } /* for(x = 0; x < msg->width; x++) */
2191 case 3: /* COMPLEMENT | INVERSVID*/
2192 for(x
= 0; x
< msg
->width
; x
++)
2194 if (!(bitword
& mask
)) xbuf
[x
] = ~xbuf
[x
];
2201 bitword
= AROS_BE2WORD(*array
);
2203 } /* for(x = 0; x < msg->width; x++) */
2207 for(x
= 0; x
< msg
->width
; x
++)
2209 xbuf
[x
] = (bitword
& mask
) ? fg
: bg
;
2216 bitword
= AROS_BE2WORD(*array
);
2219 } /* for(x = 0; x < msg->width; x++) */
2222 case 5: /* JAM2 | INVERSVID */
2223 for(x
= 0; x
< msg
->width
; x
++)
2225 xbuf
[x
] = (bitword
& mask
) ? bg
: fg
;
2232 bitword
= AROS_BE2WORD(*array
);
2234 } /* for(x = 0; x < msg->width; x++) */
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);
2249 msg
->width
* sizeof(HIDDT_Pixel
),
2254 vHidd_StdPixFmt_Native32
);
2262 bitarray
+= msg
->modulo
;
2266 } /* for(y = msg->y; y < msg->y + msg->height; y++) */
2268 GC_DRMD(msg
->gc
) = old_drmd
;
2278 ReturnVoid("BitMap::PutTemplate");
2281 /****************************************************************************************/
2283 VOID
BM__Hidd_BitMap__PutAlphaTemplate(OOP_Class
*cl
, OOP_Object
*o
,
2284 struct pHidd_BitMap_PutAlphaTemplate
*msg
)
2287 UBYTE
*pixarray
= msg
->alpha
;
2289 OOP_Object
*gc
= msg
->gc
;
2290 struct HIDDBitMapData
*data
;
2292 LONG a_red
, a_green
, a_blue
;
2293 LONG b_red
, b_green
, b_blue
;
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)
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
)
2315 else if (GC_DRMD(gc
) == vHidd_GC_DrawMode_Invert
)
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
);
2335 HIDDT_DrawMode old_drmd
= GC_DRMD(msg
->gc
);
2336 GC_DRMD(msg
->gc
) = vHidd_GC_DrawMode_Copy
;
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
;
2348 msg
->width
* sizeof(ULONG
),
2353 vHidd_StdPixFmt_ARGB32
);
2359 for(x
= 0; x
< msg
->width
; x
++)
2362 LONG dst_red
, dst_green
, dst_blue
, alpha
;
2364 alpha
= *pixarray
++;
2369 dst_red
= (destpix
& 0x00FF0000) >> 16;
2370 dst_green
= (destpix
& 0x0000FF00) >> 8;
2371 dst_blue
= (destpix
& 0x000000FF);
2373 dst_red
= (destpix
& 0x0000FF00) >> 8;
2374 dst_green
= (destpix
& 0x00FF0000) >> 16;
2375 dst_blue
= (destpix
& 0xFF000000) >> 24;
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
);
2383 destpix
= (dst_red
<< 16) + (dst_green
<< 8) + (dst_blue
);
2385 destpix
= (dst_blue
<< 24) + (dst_green
<< 16) + (dst_red
<< 8);
2390 } /* for(x = 0; x < msg->width; x++) */
2393 case 1: /* JAM1 | INVERSVID */
2394 for(x
= 0; x
< msg
->width
; x
++)
2397 LONG dst_red
, dst_green
, dst_blue
, alpha
;
2399 alpha
= (*pixarray
++) ^ 255;
2404 dst_red
= (destpix
& 0x00FF0000) >> 16;
2405 dst_green
= (destpix
& 0x0000FF00) >> 8;
2406 dst_blue
= (destpix
& 0x000000FF);
2408 dst_red
= (destpix
& 0x0000FF00) >> 8;
2409 dst_green
= (destpix
& 0x00FF0000) >> 16;
2410 dst_blue
= (destpix
& 0xFF000000) >> 24;
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
);
2418 destpix
= (dst_red
<< 16) + (dst_green
<< 8) + (dst_blue
);
2420 destpix
= (dst_blue
<< 24) + (dst_green
<< 16) + (dst_red
<< 8);
2425 } /* for(x = 0; x < msg->width; x++) */
2428 case 2: /* COMPLEMENT */
2429 for(x
= 0; x
< msg
->width
; x
++)
2434 alpha
= *pixarray
++;
2437 if (alpha
>= 0x80) destpix
= ~destpix
;
2440 } /* for(x = 0; x < msg->width; x++) */
2443 case 3: /* COMPLEMENT | INVERSVID*/
2444 for(x
= 0; x
< msg
->width
; x
++)
2449 alpha
= *pixarray
++;
2452 if (alpha
< 0x80) destpix
= ~destpix
;
2455 } /* for(x = 0; x < msg->width; x++) */
2459 for(x
= 0; x
< msg
->width
; x
++)
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;
2471 destpix
= (dst_red
<< 16) + (dst_green
<< 8) + (dst_blue
);
2473 destpix
= (dst_blue
<< 24) + (dst_green
<< 16) + (dst_red
<< 8);
2478 } /* for(x = 0; x < msg->width; x++) */
2481 case 5: /* JAM2 | INVERSVID */
2482 for(x
= 0; x
< msg
->width
; x
++)
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;
2494 destpix
= (dst_red
<< 16) + (dst_green
<< 8) + (dst_blue
);
2496 destpix
= (dst_blue
<< 24) + (dst_green
<< 16) + (dst_red
<< 8);
2501 } /* for(x = 0; x < msg->width; x++) */
2504 } /* switch(type) */
2506 if (PIXBUF_TIME_TO_END_PROCESS
)
2508 LONG height
= PIXBUF_LINES_TO_PROCESS
;
2513 msg
->width
* sizeof(ULONG
),
2518 vHidd_StdPixFmt_ARGB32
);
2527 pixarray
+= msg
->modulo
- msg
->width
;
2531 } /* for(y = msg->y; y < msg->y + msg->height; y++) */
2533 GC_DRMD(msg
->gc
) = old_drmd
;
2543 ReturnVoid("BitMap::PutAlphaTemplate");
2546 /****************************************************************************************/
2548 VOID
BM__Hidd_BitMap__PutPattern(OOP_Class
*cl
, OOP_Object
*o
,
2549 struct pHidd_BitMap_PutPattern
*msg
)
2553 UBYTE
*maskarray
= 0;
2554 ULONG
*buf
, *xbuf
, patmask
, maskmask
;
2555 OOP_Object
*gc
= msg
->gc
;
2556 struct HIDDBitMapData
*data
;
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)
2568 if (msg
->patterndepth
> 1)
2574 if (GC_COLEXP(gc
) == vHidd_GC_ColExp_Transparent
)
2578 else if (GC_DRMD(gc
) == vHidd_GC_DrawMode_Invert
)
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
);
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
;
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
);
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);
2634 msg
->width
* sizeof(ULONG
),
2639 vHidd_StdPixFmt_Native32
);
2646 for(x
= 0; x
< msg
->width
; x
++)
2648 if (!maskarray
|| (maskword
& mmask
))
2650 if (patword
& pmask
) xbuf
[x
] = fg
;
2660 maskword
= AROS_BE2WORD(*marray
);
2665 if (!pmask
) pmask
= 0x8000;
2667 } /* for(x = 0; x < msg->width; x++) */
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
;
2685 maskword
= AROS_BE2WORD(*marray
);
2690 if (!pmask
) pmask
= 0x8000;
2692 } /* for(x = 0; x < msg->width; x++) */
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
];
2710 maskword
= AROS_BE2WORD(*marray
);
2715 if (!pmask
) pmask
= 0x8000;
2717 } /* for(x = 0; x < msg->width; x++) */
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
];
2735 maskword
= AROS_BE2WORD(*marray
);
2740 if (!pmask
) pmask
= 0x8000;
2742 } /* for(x = 0; x < msg->width; x++) */
2746 for(x
= 0; x
< msg
->width
; x
++)
2748 if (!maskarray
|| (maskword
& mmask
))
2750 xbuf
[x
] = (patword
& pmask
) ? fg
: bg
;
2760 maskword
= AROS_BE2WORD(*marray
);
2765 if (!pmask
) pmask
= 0x8000;
2767 } /* for(x = 0; x < msg->width; x++) */
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
;
2785 maskword
= AROS_BE2WORD(*marray
);
2790 if (!pmask
) pmask
= 0x8000;
2792 } /* for(x = 0; x < msg->width; x++) */
2795 case 6: /* multi color pattern */
2796 for(x
= 0; x
< msg
->width
; x
++)
2798 if (!maskarray
|| (maskword
& mmask
))
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
];
2823 maskword
= AROS_BE2WORD(*marray
);
2828 if (!pmask
) pmask
= 0x8000;
2830 } /* for(x = 0; x < msg->width; x++) */
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);
2845 msg
->width
* sizeof(ULONG
),
2850 vHidd_StdPixFmt_Native32
);
2858 if (maskarray
) maskarray
+= msg
->maskmodulo
;
2862 } /* for(y = msg->y; y < msg->y + msg->height; y++) */
2864 GC_DRMD(msg
->gc
) = old_drmd
;
2874 ReturnVoid("BitMap::PutPattern");
2877 /****************************************************************************************/
2879 VOID
BM__Hidd_BitMap__PutImageLUT(OOP_Class
*cl
, OOP_Object
*o
,
2880 struct pHidd_BitMap_PutImageLUT
*msg
)
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)
2898 linebuf
= AllocVec(msg
->width
* sizeof(HIDDT_Pixel
), MEMF_PUBLIC
);
2900 for(y
= 0; y
< msg
->height
; y
++)
2906 for(x
= 0; x
< msg
->width
; x
++)
2908 linebuf
[x
] = lut
[pixarray
[x
]];
2913 for(x
= 0; x
< msg
->width
; x
++)
2915 linebuf
[x
] = pixarray
[x
];
2918 pixarray
+= msg
->modulo
;
2928 vHidd_StdPixFmt_Native32
);
2930 } /* if (linebuf) */
2935 /* Preserve old fg pen */
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
);
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
);
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
)
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
;
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)
2987 PIXBUF_ALLOC(buf
, msg
->width
* sizeof(HIDDT_Pixel
), msg
->height
);
2991 HIDDT_DrawMode old_drmd
= GC_DRMD(msg
->gc
);
2992 GC_DRMD(msg
->gc
) = vHidd_GC_DrawMode_Copy
;
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
;
3004 msg
->width
* sizeof(HIDDT_Pixel
),
3009 vHidd_StdPixFmt_Native32
);
3014 for(x
= 0; x
< msg
->width
; x
++)
3016 UBYTE pix
= *pixarray
++;
3018 if (pix
!= transparent
)
3023 } /* for(x = 0; x < msg->width; x++) */
3027 for(x
= 0; x
< msg
->width
; x
++)
3029 UBYTE pix
= *pixarray
++;
3031 if (pix
!= transparent
)
3036 } /* for(x = 0; x < msg->width; x++) */
3040 if (PIXBUF_TIME_TO_END_PROCESS
)
3042 LONG height
= PIXBUF_LINES_TO_PROCESS
;
3047 msg
->width
* sizeof(HIDDT_Pixel
),
3052 vHidd_StdPixFmt_Native32
);
3060 pixarray
= ((UBYTE
*)pixarray
+ msg
->modulo
- msg
->width
);
3065 } /* for(y = msg->y; y < msg->y + msg->height; y++) */
3067 GC_DRMD(msg
->gc
) = old_drmd
;
3073 ReturnVoid("BitMap::PutTranspImageLUT");
3076 /****************************************************************************************/
3078 VOID
BM__Hidd_BitMap__GetImageLUT(OOP_Class
*cl
, OOP_Object
*o
,
3079 struct pHidd_BitMap_GetImageLUT
*msg
)
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
++)
3106 vHidd_StdPixFmt_Native32
);
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
];
3117 for(x
= 0; x
< msg
->width
; x
++)
3119 pixarray
[x
] = (UBYTE
)linebuf
[x
];
3122 pixarray
+= msg
->modulo
;
3124 } /* if (linebuf) */
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
);
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
)
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
);
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
3176 for (y
= 0; y
< msg
->height
; y
++)
3178 for (x
= 0; x
< msg
->width
; x
++)
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
);
3193 HIDD_BM_DrawPixel(o
, gc
, x
+ msg
->destX
, y
+ msg
->destY
);
3197 if (cemd
& vHidd_GC_ColExp_Opaque
)
3199 /* Write bixel with BG pen */
3201 HIDD_BM_DrawPixel(o
, gc
, x
+ msg
->destX
, y
+ msg
->destY
);
3202 /* Reset to FG pen */
3208 } /* for (each x) */
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
)
3224 switch (msg
->pixFmt
)
3226 case vHidd_StdPixFmt_Native32
:
3227 bpl
= sizeof (HIDDT_Pixel
) * msg
->width
;
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
;
3243 struct HIDDBitMapData
*data
;
3245 data
= OOP_INST_DATA(cl
, o
);
3247 pf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, msg
->pixFmt
);
3251 D(bug("!!! COULD NOT GET STD PIXFMT IN BitMap::BytesPerLine() !!!\n"));
3255 bpl
= ((HIDDT_PixelFormat
*)pf
)->bytes_per_pixel
* msg
->width
;
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
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
;
3280 /* EnterFunc(bug("BitMap::Set()\n"));
3282 tstate
= msg
->attrList
;
3283 while((tag
= NextTagItem(&tstate
)))
3285 if(IS_BITMAP_ATTR(tag
->ti_Tag
, idx
))
3289 case aoHidd_BitMap_Width
:
3290 data
->width
= tag
->ti_Data
;
3293 case aoHidd_BitMap_Height
:
3294 data
->height
= tag
->ti_Data
;
3298 case aoHidd_BitMap_ColorTab
:
3299 data
->colorTab
= (APTR
)tag
->ti_Data
;
3304 D(bug("!!! TRYING TO SET NONSETTABLE BITMAP ATTR %d !!!\n", idx
));
3314 /****************************************************************************************/
3316 OOP_Object
*BM__Hidd_BitMap__SetColorMap(OOP_Class
*cl
, OOP_Object
*o
,
3317 struct pHidd_BitMap_SetColorMap
*msg
)
3319 struct HIDDBitMapData
*data
;
3322 data
= OOP_INST_DATA(cl
, o
);
3325 data
->colmap
= msg
->colorMap
;
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
);
3359 msg
->color
->pixval
= MAP_RGBA(red
, green
, blue
, alpha
, pf
);
3364 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
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
);
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
)
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 */
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"));
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
;
3449 UWORD ys
= bsa
->bsa_SrcY
;
3450 ULONG xs
= bsa
->bsa_SrcX
;
3451 ULONG dyd
= bsa
->bsa_DestHeight
;
3452 ULONG dxd
= bsa
->bsa_DestWidth
;
3455 ULONG dxs
= bsa
->bsa_SrcWidth
;
3456 ULONG dys
= bsa
->bsa_SrcHeight
;
3457 LONG accuyd
= - (dys
>> 1);
3458 LONG accuxd
= - (dxs
>> 1);
3461 if ((srcbuf
= AllocVec(bsa
->bsa_SrcWidth
* sizeof(ULONG
), 0)) == NULL
)
3464 if ((dstbuf
= AllocVec(bsa
->bsa_DestWidth
* sizeof(ULONG
), 0)) == NULL
) {
3469 if ((linepattern
= (UWORD
*) AllocVec(bsa
->bsa_DestWidth
* sizeof(UWORD
), 0)) == NULL
) {
3476 while (count
< bsa
->bsa_DestWidth
) {
3478 while (accuxd
> accuxs
) {
3483 linepattern
[count
] = xs
;
3488 count
= bsa
->bsa_DestY
;
3489 while (count
< bsa
->bsa_DestHeight
+ bsa
->bsa_DestY
) {
3491 while (accuyd
> accuys
) {
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
);
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
);
3509 FreeVec(linepattern
);
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;
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
);
3538 /****************************************************************************************/
3542 /****************************************************************************************/
3544 BOOL
BM__Hidd_BitMap__SetBitMapTags(OOP_Class
*cl
, OOP_Object
*o
,
3545 struct pHidd_BitMap_SetBitMapTags
*msg
)
3547 struct HIDDBitMapData
*data
;
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"));
3562 if (GOT_BM_ATTR(PixFmtTags
))
3564 /* Allready a pixfmt registered ? */
3566 pf
= HIDD_Gfx_RegisterPixFmt(data
->gfxhidd
, (struct TagItem
*)attrs
[AO(PixFmtTags
)]);
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
)];
3586 /****************************************************************************************/
3588 #ifndef AROS_CREATE_ROM
3589 # define STATIC_MID static OOP_MethodID mid
3591 # define STATIC_MID OOP_MethodID mid = 0
3594 /****************************************************************************************/
3596 BOOL
HIDD_BitMap_SetBitMapTags(OOP_Object
*o
, struct TagItem
*bitMapTags
)
3599 struct pHidd_BitMap_SetBitMapTags p
, *msg
= &p
;
3601 if (!mid
) mid
= OOP_GetMethodID(IID_Hidd_BitMap
, moHidd_BitMap_SetBitMapTags
);
3605 p
.bitMapTags
= bitMapTags
;
3607 return (BOOL
)OOP_DoMethod(o
, (OOP_Msg
)msg
);
3610 /****************************************************************************************/