2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
8 #include <aros/debug.h>
9 #include <proto/graphics.h>
10 #include <proto/oop.h>
11 #include "graphics_intern.h"
12 #include "gfxfuncsupport.h"
13 #include <hardware/blit.h>
15 /* Nominal size of the pixel conversion buffer
18 #define NUMPIX 4096 /* Not that much room to spare */
23 struct bltmask_render_data
25 struct render_special_info rsi
;
27 OOP_Object
*srcbm_obj
;
29 HIDDT_ColorModel src_colmod
;
33 BOOL samebitmapformat
;
36 static ULONG
bltmask_render(APTR bltmask_rd
, LONG srcx
, LONG srcy
,
37 OOP_Object
*dstbm_obj
, OOP_Object
*dst_gc
,
38 LONG x1
, LONG y1
, LONG x2
, LONG y2
, struct GfxBase
*GfxBase
);
40 /*****************************************************************************
43 #include <clib/graphics_protos.h>
45 AROS_LH10(void, BltMaskBitMapRastPort
,
48 AROS_LHA(struct BitMap
*, srcBitMap
, A0
),
49 AROS_LHA(LONG
, xSrc
, D0
),
50 AROS_LHA(LONG
, ySrc
, D1
),
51 AROS_LHA(struct RastPort
*, destRP
, A1
),
52 AROS_LHA(LONG
, xDest
, D2
),
53 AROS_LHA(LONG
, yDest
, D3
),
54 AROS_LHA(LONG
, xSize
, D4
),
55 AROS_LHA(LONG
, ySize
, D5
),
56 AROS_LHA(ULONG
, minterm
, D6
),
57 AROS_LHA(PLANEPTR
, bltMask
, A2
),
60 struct GfxBase
*, GfxBase
, 106, Graphics
)
63 Copies a part of a bitmap to another bitmap with using a mask.
66 srcBitMap - Copy from this bitmap.
67 xSrc, ySrc - This is the upper left corner of the area to copy.
68 destRP - Destination RastPort.
69 xDest, yDest - Upper left corner where to place the copy
70 xSize, ySize - The size of the area to copy
71 minterm - How to copy. See BltBitMap() for an explanation.
72 bltMask - The mask bitplane must be of the same size as the source bitmap.
95 27-11-96 digulla automatically created from
96 graphics_lib.fd and clib/graphics_protos.h
98 *****************************************************************************/
102 struct bltmask_render_data brd
;
104 HIDDT_DrawMode old_drmd
;
108 struct TagItem gc_tags
[] =
110 { aHidd_GC_DrawMode
, 0UL },
114 EnterFunc(bug("BltMaskBitMapRastPort(%d %d %d, %d, %d, %d)\n"
115 , xSrc
, ySrc
, xDest
, yDest
, xSize
, ySize
));
122 if ((xSize
< 1) || (ySize
< 1)) return;
124 if (!OBTAIN_DRIVERDATA(destRP
, GfxBase
))
127 brd
.minterm
= minterm
;
128 brd
.srcbm_obj
= OBTAIN_HIDD_BM(srcBitMap
);
129 if (NULL
== brd
.srcbm_obj
)
131 RELEASE_DRIVERDATA(destRP
, GfxBase
);
135 brd
.srcbm
= srcBitMap
;
138 /* The mask has always the same size as the source bitmap */
139 brd
.mask_bpr
= 2 * WIDTH_TO_WORDS(GetBitMapAttr(srcBitMap
, BMA_WIDTH
));
141 OOP_GetAttr(brd
.srcbm_obj
, aHidd_BitMap_PixFmt
, (IPTR
*)&brd
.srcpf
);
145 OOP_GetAttr(brd
.srcpf
, aHidd_PixFmt_ColorModel
, &attr
);
146 brd
.src_colmod
= (HIDDT_ColorModel
)attr
;
149 gc
= GetDriverData(destRP
)->dd_GC
;
150 OOP_GetAttr(gc
, aHidd_GC_DrawMode
, &old_drmd
);
152 gc_tags
[0].ti_Data
= vHidd_GC_DrawMode_Copy
;
153 OOP_SetAttrs(gc
, gc_tags
);
157 rr
.MaxX
= xDest
+ xSize
- 1;
158 rr
.MaxY
= yDest
+ ySize
- 1;
163 do_render_func(destRP
, &src
, &rr
, bltmask_render
, &brd
, TRUE
, TRUE
, GfxBase
);
165 RELEASE_HIDD_BM(brd
.srcbm_obj
, srcBitMap
);
167 gc_tags
[0].ti_Data
= old_drmd
;
168 OOP_SetAttrs(gc
, gc_tags
);
170 RELEASE_DRIVERDATA(destRP
, GfxBase
);
172 ReturnVoid("BltBitMapRastPort");
176 } /* BltMaskBitMapRastPort */
178 /****************************************************************************************/
180 static ULONG
bltmask_render(APTR bltmask_rd
, LONG srcx
, LONG srcy
,
181 OOP_Object
*dstbm_obj
, OOP_Object
*dst_gc
,
182 LONG x1
, LONG y1
, LONG x2
, LONG y2
, struct GfxBase
*GfxBase
)
184 struct bltmask_render_data
*brd
;
186 HIDDT_ColorModel dest_colmod
;
187 HIDDT_Pixel
*pixtab
= NULL
;
188 ULONG x
, y
, width
, height
;
189 LONG lines_done
, lines_per_step
, doing_lines
;
190 BOOL pal_to_true
= FALSE
;
191 ULONG pixfmt
= vHidd_StdPixFmt_Native32
;
195 height
= y2
- y1
+ 1;
197 OOP_GetAttr(dstbm_obj
, aHidd_BitMap_PixFmt
, (IPTR
*)&dest_pf
);
201 OOP_GetAttr(dest_pf
, aHidd_PixFmt_ColorModel
, &attr
);
202 dest_colmod
= (HIDDT_ColorModel
)attr
;
205 brd
= (struct bltmask_render_data
*)bltmask_rd
;
206 if ((brd
->src_colmod
== vHidd_ColorModel_Palette
) && (dest_colmod
== vHidd_ColorModel_Palette
))
209 else if ((brd
->src_colmod
== vHidd_ColorModel_Palette
) && (dest_colmod
== vHidd_ColorModel_TrueColor
))
211 pixtab
= IS_HIDD_BM(brd
->srcbm
) ? HIDD_BM_PIXTAB(brd
->srcbm
) : NULL
;
212 if (!pixtab
) pixtab
= IS_HIDD_BM(brd
->rsi
.curbm
) ? HIDD_BM_PIXTAB(brd
->rsi
.curbm
) : NULL
;
216 D(bug("BltMaskBitMapRastPort could not retrieve pixel table for blit from palette to truecolor bitmap"));
217 return width
* height
;
222 else if ((brd
->src_colmod
== vHidd_ColorModel_TrueColor
) && (dest_colmod
== vHidd_ColorModel_TrueColor
))
224 if (brd
->srcpf
!= dest_pf
)
226 pixfmt
= vHidd_StdPixFmt_ARGB32
;
229 else if ((brd
->src_colmod
== vHidd_ColorModel_TrueColor
) && (dest_colmod
== vHidd_ColorModel_Palette
))
231 D(bug("BltMaskBitMapRastPort from truecolor bitmap to palette bitmap not supported!"));
232 return width
* height
;
235 /* Based on the NUMPIX advice, figure out how many
236 * lines per step we can allocate
238 lines_per_step
= NUMPIX
/ (width
* sizeof(HIDDT_Pixel
));
239 if (lines_per_step
== 0)
242 /* Allocate a temporary buffer */
243 srcbuf
= AllocMem(2 * lines_per_step
* width
* sizeof(HIDDT_Pixel
), MEMF_ANY
);
245 /* Try line-at-a-time if we can't allocate a big buffer */
246 if (!srcbuf
&& lines_per_step
> 1) {
248 srcbuf
= AllocMem(2 * lines_per_step
* width
* sizeof(HIDDT_Pixel
), MEMF_ANY
);
256 destbuf
+= lines_per_step
* width
* sizeof(HIDDT_Pixel
);
258 for(lines_done
= 0; lines_done
!= height
; lines_done
+= doing_lines
)
260 HIDDT_Pixel
*srcpixelbuf
;
261 HIDDT_Pixel
*destpixelbuf
;
264 doing_lines
= lines_per_step
;
265 if (lines_done
+ doing_lines
> height
) doing_lines
= height
- lines_done
;
267 HIDD_BM_GetImage(brd
->srcbm_obj
,
269 width
* sizeof(HIDDT_Pixel
),
270 srcx
, srcy
+ lines_done
,
274 HIDD_BM_GetImage(dstbm_obj
,
276 width
* sizeof(HIDDT_Pixel
),
281 mask
= &brd
->mask
[COORD_TO_BYTEIDX(0, srcy
+ lines_done
, brd
->mask_bpr
)];
283 srcpixelbuf
= (HIDDT_Pixel
*)srcbuf
;
284 destpixelbuf
= (HIDDT_Pixel
*)destbuf
;
288 case (ABC
|ABNC
|ANBC
): /* (ABC|ABNC|ANBC) if copy source and blit thru mask */
289 case 0xC0: /* compatibility with AOS3 */
292 for(y
= 0; y
< doing_lines
; y
++)
294 for(x
= 0; x
< width
; x
++)
296 if (mask
[XCOORD_TO_BYTEIDX(srcx
+ x
)] & XCOORD_TO_MASK(srcx
+ x
))
298 *destpixelbuf
= pixtab
[*srcpixelbuf
];
303 mask
+= brd
->mask_bpr
;
308 for(y
= 0; y
< doing_lines
; y
++)
310 for(x
= 0; x
< width
; x
++)
312 if (mask
[XCOORD_TO_BYTEIDX(srcx
+ x
)] & XCOORD_TO_MASK(srcx
+ x
))
314 *destpixelbuf
= *srcpixelbuf
;
319 mask
+= brd
->mask_bpr
;
324 case ANBC
: /* (ANBC) if invert source and blit thru mask */
325 D(bug("BltMaskBitMapRastPort does not support ANBC minterm yet"));
329 D(bug("BltMaskBitMapRastPort: minterm 0x%x not handled.\n", brd
->minterm
));
331 } /* switch(brd->minterm) */
333 HIDD_BM_PutImage(dstbm_obj
,
336 width
* sizeof(HIDDT_Pixel
),
341 } /* for(lines_done = 0; lines_done != height; lines_done += doing_lines) */
343 /* Free our temporary buffer */
344 FreeMem(srcbuf
, 2 * lines_per_step
* width
* sizeof(HIDDT_Pixel
));
346 } /* if (lines_per_step) */
349 /* urk :-( pixelbuffer too small to hold two lines) */
351 D(bug("BltMaskBitMapRastPort found pixelbuffer to be too small"));
354 return width
* height
;
357 /****************************************************************************************/