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
209 HIDD_BM_UpdateRect(dstbm_obj
, xDest
, yDest
, xSize
, ySize
);
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 /****************************************************************************************/