2 Copyright © 1995-2013, 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 D(bug("BltBitMap(%p, %d, %d, %p, %d, %d, %d, %d, %x)\n"
121 ,srcBitMap
, xSrc
, ySrc
, destBitMap
, xDest
, yDest
, xSize
, ySize
, minterm
));
123 if (IS_HIDD_BM(srcBitMap
) || IS_HIDD_BM(destBitMap
))
128 struct monitor_driverdata
*driver
, *dst_driver
;
131 EnterFunc(bug("driver_BltBitMap()\n"));
133 wSrc
= GetBitMapAttr( srcBitMap
, BMA_WIDTH
);
134 wDest
= GetBitMapAttr(destBitMap
, BMA_WIDTH
);
138 depth
= GetBitMapAttr ( srcBitMap
, BMA_DEPTH
);
139 x
= GetBitMapAttr (destBitMap
, BMA_DEPTH
);
141 if (x
< depth
) depth
= x
;
158 /* Clip width and height for source and dest */
159 if (ySrc
+ ySize
> srcBitMap
->Rows
)
161 ySize
= srcBitMap
->Rows
- ySrc
;
164 if (yDest
+ ySize
> destBitMap
->Rows
)
166 ySize
= destBitMap
->Rows
- yDest
;
169 if ((ULONG
)(xSrc
+ xSize
) >= wSrc
)
174 if ((ULONG
)(xDest
+ xSize
) >= wDest
)
176 xSize
= wDest
- xDest
;
179 /* If the size is illegal or we need not copy anything, return */
180 if (ySize
<= 0 || xSize
<= 0 || !mask
) return 0;
183 * Select a driver to call
185 * 1. If one of drivers is fakegfx.hidd, we must use it in order
186 * to de-masquerade fakefb objects.
187 * 2. If one of drivers is our default software bitmap driver,
188 * we use another one, which can be an accelerated video driver.
190 driver
= GET_BM_DRIVERDATA(srcBitMap
);
191 dst_driver
= GET_BM_DRIVERDATA(destBitMap
);
193 if (driver
== (struct monitor_driverdata
*)CDD(GfxBase
))
196 * If source bitmap is generic software one, we select destination bitmap.
197 * It can be either fakegfx or accelerated hardware driver.
201 else if (dst_driver
->flags
& DF_UseFakeGfx
)
204 * If destination bitmap is fakegfx bitmap, we use its driver.
205 * Source one might be not fakegfx.
210 * If both tests failed, we use source driver. We know that source it not a
211 * generic software driver, and destionation is not fakegfx. So, source
212 * can be either fakegfx or hardware driver.
215 tmp_gc
= obtain_cache_object(CDD(GfxBase
)->gc_cache
, GfxBase
);
218 OOP_Object
*srcbm_obj
;
220 srcbm_obj
= OBTAIN_HIDD_BM(srcBitMap
);
221 if (NULL
!= srcbm_obj
)
223 OOP_Object
*dstbm_obj
;
225 dstbm_obj
= OBTAIN_HIDD_BM(destBitMap
);
226 if (NULL
!= dstbm_obj
)
229 int_bltbitmap(srcBitMap
, srcbm_obj
231 , destBitMap
, dstbm_obj
238 update_bitmap(destBitMap
, dstbm_obj
, xDest
, yDest
, xSize
, ySize
, GfxBase
);
240 RELEASE_HIDD_BM(dstbm_obj
, destBitMap
);
243 RELEASE_HIDD_BM(srcbm_obj
, srcBitMap
);
245 release_cache_object(CDD(GfxBase
)->gc_cache
, tmp_gc
, GfxBase
);
248 /* FIXME: dummy return value of 8 planes */
257 PLANEPTR src
, dest
, temp
;
259 wSrc
= GetBitMapAttr( srcBitMap
, BMA_WIDTH
);
260 wDest
= GetBitMapAttr(destBitMap
, BMA_WIDTH
);
263 depth
= GetBitMapAttr ( srcBitMap
, BMA_DEPTH
);
264 x
= GetBitMapAttr (destBitMap
, BMA_DEPTH
);
283 /* Clip width and height for source and dest */
284 if (ySrc
+ ySize
> srcBitMap
->Rows
)
286 ySize
= srcBitMap
->Rows
- ySrc
;
289 if (yDest
+ ySize
> destBitMap
->Rows
)
291 ySize
= destBitMap
->Rows
- yDest
;
294 if ((ULONG
)(xSrc
+ xSize
) >= wSrc
)
299 if ((ULONG
)(xDest
+ xSize
) >= wDest
)
301 xSize
= wDest
- xDest
;
304 /* If the size is illegal or we need not copy anything, return */
305 if (ySize
<= 0 || xSize
<= 0 || !mask
)
311 for (plane
=0; plane
<depth
; plane
++)
313 /* Don't do anything if destination planeptr is NULL (means treat like
314 a plane with all zeros) or -1 (means treat like a plane with all ones) */
316 if ((destBitMap
->Planes
[plane
] != NULL
) && (destBitMap
->Planes
[plane
] != (PLANEPTR
)-1))
318 /* Copy this plane ? */
319 if ((1L << plane
) & mask
)
322 planecnt
++; /* count it */
324 for (y
=0; y
<(ULONG
)ySize
; y
++)
326 src
= srcBitMap
->Planes
[plane
] + (y
+ySrc
) * srcBitMap
->BytesPerRow
;
327 dest
= destBitMap
->Planes
[plane
] + (y
+yDest
)*destBitMap
->BytesPerRow
;
330 If the source address is less or equal to
331 the destination address
333 if ((src
<= dest
&& src
+srcBitMap
->BytesPerRow
> dest
)
334 || (dest
<= src
&& dest
+destBitMap
->BytesPerRow
> src
)
342 temp
= AllocMem (srcBitMap
->BytesPerRow
, MEMF_ANY
);
348 memmove (temp
, src
, srcBitMap
->BytesPerRow
);
350 for (x
=0; x
<(ULONG
)xSize
; x
++)
351 copyonepixel (temp
, x
+xSrc
, dest
, x
+xDest
, minterm
);
355 for (x
=0; x
<(ULONG
)xSize
; x
++)
356 copyonepixel (src
, x
+xSrc
, dest
, x
+xDest
, minterm
);
359 } /* for (y=0; y<ySize; y++) */
361 } /* if ((1L << plane) & mask) */
363 } /* if dest plane != NULL and dest plane != -1 */
365 } /* for (plane=0; plane<depth; plane ++) */
368 FreeMem (temp
, srcBitMap
->BytesPerRow
);
377 /****************************************************************************************/
379 static void copyonepixel (PLANEPTR src
, ULONG xsrc
, PLANEPTR dest
, ULONG xdest
,
391 } else if (src
== (PLANEPTR
)-1)
396 sBit
= 1L << (7 - (xsrc
& 0x07));
397 sSet
= (src
[sByte
] & sBit
) != 0;
400 /* dest PLANEPTR here will never be NULL or -1 */
402 dBit
= 1L << (7 - (xdest
& 0x07));
403 dSet
= (dest
[dByte
] & dBit
) != 0;
407 if (minterm
& 0x0010)
412 if (minterm
& 0x0020)
417 if (minterm
& 0x0040)
422 if (minterm
& 0x0080)
431 dest
[dByte
] &= ~dBit
;
434 /****************************************************************************************/