2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 Desc: Copy a rectangle in a bitmap to another place or another bitmap.
8 #include <aros/debug.h>
10 #include <exec/memory.h>
11 #include <graphics/gfx.h>
12 #include <proto/exec.h>
13 #include "graphics_intern.h"
14 #include "gfxfuncsupport.h"
17 static void copyonepixel (PLANEPTR src
, ULONG xsrc
, PLANEPTR dest
,
18 ULONG xdest
, ULONG minterm
);
20 /*****************************************************************************
23 #include <graphics/gfx.h>
24 #include <proto/graphics.h>
26 AROS_LH11(LONG
, BltBitMap
,
29 AROS_LHA(struct BitMap
*, srcBitMap
, A0
),
30 AROS_LHA(LONG
, xSrc
, D0
),
31 AROS_LHA(LONG
, ySrc
, D1
),
32 AROS_LHA(struct BitMap
*, destBitMap
, A1
),
33 AROS_LHA(LONG
, xDest
, D2
),
34 AROS_LHA(LONG
, yDest
, D3
),
35 AROS_LHA(LONG
, xSize
, D4
),
36 AROS_LHA(LONG
, ySize
, D5
),
37 AROS_LHA(ULONG
, minterm
, D6
),
38 AROS_LHA(ULONG
, mask
, D7
),
39 AROS_LHA(PLANEPTR
, tempA
, A2
),
42 struct GfxBase
*, GfxBase
, 5, Graphics
)
45 Moves a part of a bitmap around or into another bitmaps.
48 srcBitMap - Copy from this bitmap.
49 xSrc, ySrc - This is the upper left corner of the area to copy.
50 destBitMap - Copy to this bitmap. May be the same as srcBitMap.
51 xDest, yDest - Upper left corner where to place the copy
52 xSize, ySize - The size of the area to copy
53 minterm - How to copy. Most useful values are 0x00C0 for a vanilla
54 copy, 0x0030 to invert the source and then copy or 0x0050
55 to ignore the source and just invert the destination. If
56 you want to calculate other values, then you must know that
57 channel A is set, if you are inside the rectangle, channel
58 B is the source and channel C is the destination of the
71 So 0x00C0 means: D is set if one is inside the rectangle
72 (A is set) and B (the source) is set and cleared otherwise.
74 To fill the rectangle, you would want to set D when A is
75 set, so the value is 0x00F0.
77 mask - Which planes should be copied. Typically, you should set
79 tempA - If the copy overlaps exactly to the left or right (i.e. the
80 scan line addresses overlap), and tempA is non-zero, it
81 points to enough chip accessible memory to hold a line of a
82 source for the blit (i.e. CHIP RAM). BltBitMap will allocate
83 (and free) the needed TempA if none is provided and one is
84 needed. Blit overlap is determined from the relation of
85 the first non-masked planes in the source and destination
89 The number of planes actually involved in the blit.
92 If a special hardware is available, this function will use it.
94 As a special case, plane pointers of destBitMap can contain NULL
95 or -1, which will act as if the plane was filled with 0's or 1's,
103 ClipBlit(), BltBitMapRastPort()
109 *****************************************************************************/
112 AROS_LIBBASE_EXT_DECL(struct GfxBase
*,GfxBase
)
120 /* nlorentz: Also check for BMF_AROS_DISPLAYED flag which if set tells
121 that this is a HIDD bitmap and should be handled by the driver */
123 if ( srcBitMap
->pad
!= 0 || destBitMap
->pad
!= 0
124 || srcBitMap
->Flags
& BMF_AROS_HIDD
|| destBitMap
->Flags
& BMF_AROS_HIDD
)
132 EnterFunc(bug("driver_BltBitMap()\n"));
134 /* bug("BltBitMap(%p, %d, %d, %p, %d, %d, %d, %d, %x)\n"
135 ,srcBitMap, xSrc, ySrc, destBitMap, xDest, yDest, xSize, ySize, minterm);
139 wSrc
= GetBitMapAttr( srcBitMap
, BMA_WIDTH
);
140 wDest
= GetBitMapAttr(destBitMap
, BMA_WIDTH
);
144 depth
= GetBitMapAttr ( srcBitMap
, BMA_DEPTH
);
145 x
= GetBitMapAttr (destBitMap
, BMA_DEPTH
);
147 if (x
< depth
) depth
= x
;
164 /* Clip width and height for source and dest */
165 if (ySrc
+ ySize
> srcBitMap
->Rows
)
167 ySize
= srcBitMap
->Rows
- ySrc
;
170 if (yDest
+ ySize
> destBitMap
->Rows
)
172 ySize
= destBitMap
->Rows
- yDest
;
175 if ((ULONG
)(xSrc
+ xSize
) >= wSrc
)
180 if ((ULONG
)(xDest
+ xSize
) >= wDest
)
182 xSize
= wDest
- xDest
;
185 /* If the size is illegal or we need not copy anything, return */
186 if (ySize
<= 0 || xSize
<= 0 || !mask
) return 0;
188 tmp_gc
= obtain_cache_object(SDD(GfxBase
)->gc_cache
, GfxBase
);
191 OOP_Object
*srcbm_obj
;
193 srcbm_obj
= OBTAIN_HIDD_BM(srcBitMap
);
194 if (NULL
!= srcbm_obj
)
196 OOP_Object
*dstbm_obj
;
198 dstbm_obj
= OBTAIN_HIDD_BM(destBitMap
);
199 if (NULL
!= dstbm_obj
)
202 int_bltbitmap(srcBitMap
, srcbm_obj
204 , destBitMap
, dstbm_obj
211 RELEASE_HIDD_BM(dstbm_obj
, destBitMap
);
214 RELEASE_HIDD_BM(srcbm_obj
, srcBitMap
);
216 release_cache_object(SDD(GfxBase
)->gc_cache
, tmp_gc
, GfxBase
);
219 #warning: dummy return value
228 PLANEPTR src
, dest
, temp
;
230 wSrc
= GetBitMapAttr( srcBitMap
, BMA_WIDTH
);
231 wDest
= GetBitMapAttr(destBitMap
, BMA_WIDTH
);
234 depth
= GetBitMapAttr ( srcBitMap
, BMA_DEPTH
);
235 x
= GetBitMapAttr (destBitMap
, BMA_DEPTH
);
254 /* Clip width and height for source and dest */
255 if (ySrc
+ ySize
> srcBitMap
->Rows
)
257 ySize
= srcBitMap
->Rows
- ySrc
;
260 if (yDest
+ ySize
> destBitMap
->Rows
)
262 ySize
= destBitMap
->Rows
- yDest
;
265 if ((ULONG
)(xSrc
+ xSize
) >= wSrc
)
270 if ((ULONG
)(xDest
+ xSize
) >= wDest
)
272 xSize
= wDest
- xDest
;
275 /* If the size is illegal or we need not copy anything, return */
276 if (ySize
<= 0 || xSize
<= 0 || !mask
)
282 for (plane
=0; plane
<depth
; plane
++)
284 /* Don't do anything if destination planeptr is NULL (means treat like
285 a plane with all zeros) or -1 (means treat like a plane with all ones) */
287 if ((destBitMap
->Planes
[plane
] != NULL
) && (destBitMap
->Planes
[plane
] != (PLANEPTR
)-1))
289 /* Copy this plane ? */
290 if ((1L << plane
) & mask
)
293 planecnt
++; /* count it */
295 for (y
=0; y
<(ULONG
)ySize
; y
++)
297 src
= srcBitMap
->Planes
[plane
] + (y
+ySrc
) * srcBitMap
->BytesPerRow
;
298 dest
= destBitMap
->Planes
[plane
] + (y
+yDest
)*destBitMap
->BytesPerRow
;
301 If the source address is less or equal to
302 the destination address
304 if ((src
<= dest
&& src
+srcBitMap
->BytesPerRow
> dest
)
305 || (dest
<= src
&& dest
+destBitMap
->BytesPerRow
> src
)
313 temp
= AllocMem (srcBitMap
->BytesPerRow
, MEMF_ANY
);
319 memmove (temp
, src
, srcBitMap
->BytesPerRow
);
321 for (x
=0; x
<(ULONG
)xSize
; x
++)
322 copyonepixel (temp
, x
+xSrc
, dest
, x
+xDest
, minterm
);
326 for (x
=0; x
<(ULONG
)xSize
; x
++)
327 copyonepixel (src
, x
+xSrc
, dest
, x
+xDest
, minterm
);
330 } /* for (y=0; y<ySize; y++) */
332 } /* if ((1L << plane) & mask) */
334 } /* if dest plane != NULL and dest plane != -1 */
336 } /* for (plane=0; plane<depth; plane ++) */
339 FreeMem (temp
, srcBitMap
->BytesPerRow
);
348 /****************************************************************************************/
350 static void copyonepixel (PLANEPTR src
, ULONG xsrc
, PLANEPTR dest
, ULONG xdest
,
362 } else if (src
== (PLANEPTR
)-1)
367 sBit
= 1L << (7 - (xsrc
& 0x07));
368 sSet
= (src
[sByte
] & sBit
) != 0;
371 /* dest PLANEPTR here will never be NULL or -1 */
373 dBit
= 1L << (7 - (xdest
& 0x07));
374 dSet
= (dest
[dByte
] & dBit
) != 0;
378 if (minterm
& 0x0010)
383 if (minterm
& 0x0020)
388 if (minterm
& 0x0040)
393 if (minterm
& 0x0080)
402 dest
[dByte
] &= ~dBit
;
405 /****************************************************************************************/