2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
5 Desc: Copy a rectangle in a bitmap to another place or another bitmap.
9 #include <aros/debug.h>
10 #include <exec/memory.h>
11 #include <graphics/gfx.h>
12 #include <proto/exec.h>
14 #include "graphics_intern.h"
15 #include "gfxfuncsupport.h"
18 static void copyonepixel (PLANEPTR src
, ULONG xsrc
, PLANEPTR dest
,
19 ULONG xdest
, ULONG minterm
);
21 /*****************************************************************************
24 #include <graphics/gfx.h>
25 #include <proto/graphics.h>
27 AROS_LH11(LONG
, BltBitMap
,
30 AROS_LHA(struct BitMap
*, srcBitMap
, A0
),
31 AROS_LHA(LONG
, xSrc
, D0
),
32 AROS_LHA(LONG
, ySrc
, D1
),
33 AROS_LHA(struct BitMap
*, destBitMap
, A1
),
34 AROS_LHA(LONG
, xDest
, D2
),
35 AROS_LHA(LONG
, yDest
, D3
),
36 AROS_LHA(LONG
, xSize
, D4
),
37 AROS_LHA(LONG
, ySize
, D5
),
38 AROS_LHA(ULONG
, minterm
, D6
),
39 AROS_LHA(ULONG
, mask
, D7
),
40 AROS_LHA(PLANEPTR
, tempA
, A2
),
43 struct GfxBase
*, GfxBase
, 5, Graphics
)
46 Moves a part of a bitmap around or into another bitmap.
49 srcBitMap - Copy from this bitmap.
50 xSrc, ySrc - This is the upper left corner of the area to copy.
51 destBitMap - Copy to this bitmap. May be the same as srcBitMap.
52 xDest, yDest - Upper left corner where to place the copy
53 xSize, ySize - The size of the area to copy
54 minterm - How to copy. Most useful values are 0x00C0 for a vanilla
55 copy, 0x0030 to invert the source and then copy or 0x0050
56 to ignore the source and just invert the destination. If
57 you want to calculate other values, then you must know that
58 channel A is set, if you are inside the rectangle, channel
59 B is the source and channel C is the destination of the
72 So 0x00C0 means: D is set if one is inside the rectangle
73 (A is set) and B (the source) is set and cleared otherwise.
75 To fill the rectangle, you would want to set D when A is
76 set, so the value is 0x00F0.
78 mask - Which planes should be copied. Typically, you should set
80 tempA - If the copy overlaps exactly to the left or right (i.e. the
81 scan line addresses overlap), and tempA is non-zero, it
82 points to enough chip accessible memory to hold a line of a
83 source for the blit (i.e. CHIP RAM). BltBitMap will allocate
84 (and free) the needed TempA if none is provided and one is
85 needed. Blit overlap is determined from the relation of
86 the first non-masked planes in the source and destination
90 The number of planes actually involved in the blit.
93 If a special hardware is available, this function will use it.
95 As a special case, plane pointers of destBitMap can contain NULL
96 or -1, which will act as if the plane was filled with 0's or 1's,
104 ClipBlit(), BltBitMapRastPort()
110 *****************************************************************************/
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_SPECIALFMT
|| destBitMap
->Flags
& BMF_SPECIALFMT
)
129 struct monitor_driverdata
*driver
, *dst_driver
;
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;
189 * Select a driver to call
191 * 1. If one of drivers is fakegfx.hidd, we must use it in order
192 * to de-masquerade fakefb objects.
193 * 2. If one of drivers is our default software bitmap driver,
194 * we use another one, which can be an accelerated video driver.
196 driver
= GET_BM_DRIVERDATA(srcBitMap
);
197 dst_driver
= GET_BM_DRIVERDATA(destBitMap
);
199 if (driver
== (struct monitor_driverdata
*)CDD(GfxBase
))
202 * If source bitmap is generic software one, we select destination bitmap.
203 * It can be either fakegfx or accelerated hardware driver.
207 else if (dst_driver
->flags
& DF_UseFakeGfx
)
210 * If destination bitmap is fakegfx bitmap, we use its driver.
211 * Source one might be not fakegfx.
216 * If both tests failed, we use source driver. We know that source it not a
217 * generic software driver, and destionation is not fakegfx. So, source
218 * can be either fakegfx or hardware driver.
221 tmp_gc
= obtain_cache_object(CDD(GfxBase
)->gc_cache
, GfxBase
);
224 OOP_Object
*srcbm_obj
;
226 srcbm_obj
= OBTAIN_HIDD_BM(srcBitMap
);
227 if (NULL
!= srcbm_obj
)
229 OOP_Object
*dstbm_obj
;
231 dstbm_obj
= OBTAIN_HIDD_BM(destBitMap
);
232 if (NULL
!= dstbm_obj
)
235 int_bltbitmap(srcBitMap
, srcbm_obj
237 , destBitMap
, dstbm_obj
244 update_bitmap(destBitMap
, dstbm_obj
, xDest
, yDest
, xSize
, ySize
, GfxBase
);
246 RELEASE_HIDD_BM(dstbm_obj
, destBitMap
);
249 RELEASE_HIDD_BM(srcbm_obj
, srcBitMap
);
251 release_cache_object(CDD(GfxBase
)->gc_cache
, tmp_gc
, GfxBase
);
254 /* FIXME: dummy return value of 8 planes */
263 PLANEPTR src
, dest
, temp
;
265 wSrc
= GetBitMapAttr( srcBitMap
, BMA_WIDTH
);
266 wDest
= GetBitMapAttr(destBitMap
, BMA_WIDTH
);
269 depth
= GetBitMapAttr ( srcBitMap
, BMA_DEPTH
);
270 x
= GetBitMapAttr (destBitMap
, BMA_DEPTH
);
289 /* Clip width and height for source and dest */
290 if (ySrc
+ ySize
> srcBitMap
->Rows
)
292 ySize
= srcBitMap
->Rows
- ySrc
;
295 if (yDest
+ ySize
> destBitMap
->Rows
)
297 ySize
= destBitMap
->Rows
- yDest
;
300 if ((ULONG
)(xSrc
+ xSize
) >= wSrc
)
305 if ((ULONG
)(xDest
+ xSize
) >= wDest
)
307 xSize
= wDest
- xDest
;
310 /* If the size is illegal or we need not copy anything, return */
311 if (ySize
<= 0 || xSize
<= 0 || !mask
)
317 for (plane
=0; plane
<depth
; plane
++)
319 /* Don't do anything if destination planeptr is NULL (means treat like
320 a plane with all zeros) or -1 (means treat like a plane with all ones) */
322 if ((destBitMap
->Planes
[plane
] != NULL
) && (destBitMap
->Planes
[plane
] != (PLANEPTR
)-1))
324 /* Copy this plane ? */
325 if ((1L << plane
) & mask
)
328 planecnt
++; /* count it */
330 for (y
=0; y
<(ULONG
)ySize
; y
++)
332 src
= srcBitMap
->Planes
[plane
] + (y
+ySrc
) * srcBitMap
->BytesPerRow
;
333 dest
= destBitMap
->Planes
[plane
] + (y
+yDest
)*destBitMap
->BytesPerRow
;
336 If the source address is less or equal to
337 the destination address
339 if ((src
<= dest
&& src
+srcBitMap
->BytesPerRow
> dest
)
340 || (dest
<= src
&& dest
+destBitMap
->BytesPerRow
> src
)
348 temp
= AllocMem (srcBitMap
->BytesPerRow
, MEMF_ANY
);
354 memmove (temp
, src
, srcBitMap
->BytesPerRow
);
356 for (x
=0; x
<(ULONG
)xSize
; x
++)
357 copyonepixel (temp
, x
+xSrc
, dest
, x
+xDest
, minterm
);
361 for (x
=0; x
<(ULONG
)xSize
; x
++)
362 copyonepixel (src
, x
+xSrc
, dest
, x
+xDest
, minterm
);
365 } /* for (y=0; y<ySize; y++) */
367 } /* if ((1L << plane) & mask) */
369 } /* if dest plane != NULL and dest plane != -1 */
371 } /* for (plane=0; plane<depth; plane ++) */
374 FreeMem (temp
, srcBitMap
->BytesPerRow
);
383 /****************************************************************************************/
385 static void copyonepixel (PLANEPTR src
, ULONG xsrc
, PLANEPTR dest
, ULONG xdest
,
397 } else if (src
== (PLANEPTR
)-1)
402 sBit
= 1L << (7 - (xsrc
& 0x07));
403 sSet
= (src
[sByte
] & sBit
) != 0;
406 /* dest PLANEPTR here will never be NULL or -1 */
408 dBit
= 1L << (7 - (xdest
& 0x07));
409 dSet
= (dest
[dByte
] & dBit
) != 0;
413 if (minterm
& 0x0010)
418 if (minterm
& 0x0020)
423 if (minterm
& 0x0040)
428 if (minterm
& 0x0080)
437 dest
[dByte
] &= ~dBit
;
440 /****************************************************************************************/