2 Copyright © 1995-2007, 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 *****************************************************************************/
119 /* nlorentz: Also check for BMF_AROS_DISPLAYED flag which if set tells
120 that this is a HIDD bitmap and should be handled by the driver */
122 if ( srcBitMap
->pad
!= 0 || destBitMap
->pad
!= 0
123 || srcBitMap
->Flags
& BMF_AROS_HIDD
|| destBitMap
->Flags
& BMF_AROS_HIDD
)
131 EnterFunc(bug("driver_BltBitMap()\n"));
133 /* bug("BltBitMap(%p, %d, %d, %p, %d, %d, %d, %d, %x)\n"
134 ,srcBitMap, xSrc, ySrc, destBitMap, xDest, yDest, xSize, ySize, minterm);
138 wSrc
= GetBitMapAttr( srcBitMap
, BMA_WIDTH
);
139 wDest
= GetBitMapAttr(destBitMap
, BMA_WIDTH
);
143 depth
= GetBitMapAttr ( srcBitMap
, BMA_DEPTH
);
144 x
= GetBitMapAttr (destBitMap
, BMA_DEPTH
);
146 if (x
< depth
) depth
= x
;
163 /* Clip width and height for source and dest */
164 if (ySrc
+ ySize
> srcBitMap
->Rows
)
166 ySize
= srcBitMap
->Rows
- ySrc
;
169 if (yDest
+ ySize
> destBitMap
->Rows
)
171 ySize
= destBitMap
->Rows
- yDest
;
174 if ((ULONG
)(xSrc
+ xSize
) >= wSrc
)
179 if ((ULONG
)(xDest
+ xSize
) >= wDest
)
181 xSize
= wDest
- xDest
;
184 /* If the size is illegal or we need not copy anything, return */
185 if (ySize
<= 0 || xSize
<= 0 || !mask
) return 0;
187 tmp_gc
= obtain_cache_object(SDD(GfxBase
)->gc_cache
, GfxBase
);
190 OOP_Object
*srcbm_obj
;
192 srcbm_obj
= OBTAIN_HIDD_BM(srcBitMap
);
193 if (NULL
!= srcbm_obj
)
195 OOP_Object
*dstbm_obj
;
197 dstbm_obj
= OBTAIN_HIDD_BM(destBitMap
);
198 if (NULL
!= dstbm_obj
)
201 int_bltbitmap(srcBitMap
, srcbm_obj
203 , destBitMap
, dstbm_obj
210 RELEASE_HIDD_BM(dstbm_obj
, destBitMap
);
213 RELEASE_HIDD_BM(srcbm_obj
, srcBitMap
);
215 release_cache_object(SDD(GfxBase
)->gc_cache
, tmp_gc
, GfxBase
);
218 #warning: dummy return value
227 PLANEPTR src
, dest
, temp
;
229 wSrc
= GetBitMapAttr( srcBitMap
, BMA_WIDTH
);
230 wDest
= GetBitMapAttr(destBitMap
, BMA_WIDTH
);
233 depth
= GetBitMapAttr ( srcBitMap
, BMA_DEPTH
);
234 x
= GetBitMapAttr (destBitMap
, BMA_DEPTH
);
253 /* Clip width and height for source and dest */
254 if (ySrc
+ ySize
> srcBitMap
->Rows
)
256 ySize
= srcBitMap
->Rows
- ySrc
;
259 if (yDest
+ ySize
> destBitMap
->Rows
)
261 ySize
= destBitMap
->Rows
- yDest
;
264 if ((ULONG
)(xSrc
+ xSize
) >= wSrc
)
269 if ((ULONG
)(xDest
+ xSize
) >= wDest
)
271 xSize
= wDest
- xDest
;
274 /* If the size is illegal or we need not copy anything, return */
275 if (ySize
<= 0 || xSize
<= 0 || !mask
)
281 for (plane
=0; plane
<depth
; plane
++)
283 /* Don't do anything if destination planeptr is NULL (means treat like
284 a plane with all zeros) or -1 (means treat like a plane with all ones) */
286 if ((destBitMap
->Planes
[plane
] != NULL
) && (destBitMap
->Planes
[plane
] != (PLANEPTR
)-1))
288 /* Copy this plane ? */
289 if ((1L << plane
) & mask
)
292 planecnt
++; /* count it */
294 for (y
=0; y
<(ULONG
)ySize
; y
++)
296 src
= srcBitMap
->Planes
[plane
] + (y
+ySrc
) * srcBitMap
->BytesPerRow
;
297 dest
= destBitMap
->Planes
[plane
] + (y
+yDest
)*destBitMap
->BytesPerRow
;
300 If the source address is less or equal to
301 the destination address
303 if ((src
<= dest
&& src
+srcBitMap
->BytesPerRow
> dest
)
304 || (dest
<= src
&& dest
+destBitMap
->BytesPerRow
> src
)
312 temp
= AllocMem (srcBitMap
->BytesPerRow
, MEMF_ANY
);
318 memmove (temp
, src
, srcBitMap
->BytesPerRow
);
320 for (x
=0; x
<(ULONG
)xSize
; x
++)
321 copyonepixel (temp
, x
+xSrc
, dest
, x
+xDest
, minterm
);
325 for (x
=0; x
<(ULONG
)xSize
; x
++)
326 copyonepixel (src
, x
+xSrc
, dest
, x
+xDest
, minterm
);
329 } /* for (y=0; y<ySize; y++) */
331 } /* if ((1L << plane) & mask) */
333 } /* if dest plane != NULL and dest plane != -1 */
335 } /* for (plane=0; plane<depth; plane ++) */
338 FreeMem (temp
, srcBitMap
->BytesPerRow
);
347 /****************************************************************************************/
349 static void copyonepixel (PLANEPTR src
, ULONG xsrc
, PLANEPTR dest
, ULONG xdest
,
361 } else if (src
== (PLANEPTR
)-1)
366 sBit
= 1L << (7 - (xsrc
& 0x07));
367 sSet
= (src
[sByte
] & sBit
) != 0;
370 /* dest PLANEPTR here will never be NULL or -1 */
372 dBit
= 1L << (7 - (xdest
& 0x07));
373 dSet
= (dest
[dByte
] & dBit
) != 0;
377 if (minterm
& 0x0010)
382 if (minterm
& 0x0020)
387 if (minterm
& 0x0040)
392 if (minterm
& 0x0080)
401 dest
[dByte
] &= ~dBit
;
404 /****************************************************************************************/