r4493@vps: verhaegs | 2007-04-19 14:44:00 -0400
[AROS.git] / rom / graphics / bltmaskbitmaprastport.c
blobd99459efb4238aa1ea99cddba4aee5c8ef95ef94
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
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 struct bltmask_render_data
17 struct render_special_info rsi;
18 struct BitMap *srcbm;
19 OOP_Object *srcbm_obj;
20 OOP_Object *srcpf;
21 HIDDT_ColorModel src_colmod;
22 PLANEPTR mask;
23 ULONG mask_bpr;
24 ULONG minterm;
25 BOOL samebitmapformat;
28 static ULONG bltmask_render(APTR bltmask_rd, LONG srcx, LONG srcy,
29 OOP_Object *dstbm_obj, OOP_Object *dst_gc,
30 LONG x1, LONG y1, LONG x2, LONG y2, struct GfxBase *GfxBase);
32 /*****************************************************************************
34 NAME */
35 #include <clib/graphics_protos.h>
37 AROS_LH10(void, BltMaskBitMapRastPort,
39 /* SYNOPSIS */
40 AROS_LHA(struct BitMap *, srcBitMap, A0),
41 AROS_LHA(LONG , xSrc, D0),
42 AROS_LHA(LONG , ySrc, D1),
43 AROS_LHA(struct RastPort *, destRP, A1),
44 AROS_LHA(LONG , xDest, D2),
45 AROS_LHA(LONG , yDest, D3),
46 AROS_LHA(LONG , xSize, D4),
47 AROS_LHA(LONG , ySize, D5),
48 AROS_LHA(ULONG , minterm, D6),
49 AROS_LHA(PLANEPTR , bltMask, A2),
51 /* LOCATION */
52 struct GfxBase *, GfxBase, 106, Graphics)
54 /* FUNCTION
55 Copies a part of a bitmap to another bitmap with using a mask.
57 INPUTS
58 srcBitMap - Copy from this bitmap.
59 xSrc, ySrc - This is the upper left corner of the area to copy.
60 destRP - Destination RastPort.
61 xDest, yDest - Upper left corner where to place the copy
62 xSize, ySize - The size of the area to copy
63 minterm - How to copy. See BltBitMap() for an explanation.
64 bltMask - The mask bitplane must be of the same size as the source bitmap.
66 RESULT
67 TRUE.
69 NOTES
71 EXAMPLE
73 BUGS
75 SEE ALSO
76 ClipBlit()
78 INPUTS
80 RESULT
82 NOTES
84 INTERNALS
86 HISTORY
87 27-11-96 digulla automatically created from
88 graphics_lib.fd and clib/graphics_protos.h
90 *****************************************************************************/
92 AROS_LIBFUNC_INIT
93 AROS_LIBBASE_EXT_DECL(struct GfxBase *,GfxBase)
95 struct bltmask_render_data brd;
96 struct Rectangle rr;
97 HIDDT_DrawMode old_drmd;
98 OOP_Object *gc;
99 Point src;
101 struct TagItem gc_tags[] =
103 { aHidd_GC_DrawMode , 0UL },
104 { TAG_DONE }
107 EnterFunc(bug("BltMaskBitMapRastPort(%d %d %d, %d, %d, %d)\n"
108 , xSrc, ySrc, xDest, yDest, xSize, ySize));
110 FIX_GFXCOORD(xSrc);
111 FIX_GFXCOORD(ySrc);
112 FIX_GFXCOORD(xDest);
113 FIX_GFXCOORD(yDest);
115 if ((xSize < 1) || (ySize < 1)) return;
117 if (!OBTAIN_DRIVERDATA(destRP, GfxBase))
118 return;
120 brd.minterm = minterm;
121 brd.srcbm_obj = OBTAIN_HIDD_BM(srcBitMap);
122 if (NULL == brd.srcbm_obj)
124 RELEASE_DRIVERDATA(destRP, GfxBase);
125 return;
128 brd.srcbm = srcBitMap;
129 brd.mask = bltMask;
131 /* The mask has always the same size as the source bitmap */
132 brd.mask_bpr = 2 * WIDTH_TO_WORDS(GetBitMapAttr(srcBitMap, BMA_WIDTH));
134 OOP_GetAttr(brd.srcbm_obj, aHidd_BitMap_PixFmt, (IPTR *)&brd.srcpf);
136 IPTR attr;
138 OOP_GetAttr(brd.srcpf, aHidd_PixFmt_ColorModel, &attr);
139 brd.src_colmod = (HIDDT_ColorModel)attr;
142 gc = GetDriverData(destRP)->dd_GC;
143 OOP_GetAttr(gc, aHidd_GC_DrawMode, &old_drmd);
145 gc_tags[0].ti_Data = vHidd_GC_DrawMode_Copy;
146 OOP_SetAttrs(gc, gc_tags);
148 rr.MinX = xDest;
149 rr.MinY = yDest;
150 rr.MaxX = xDest + xSize - 1;
151 rr.MaxY = yDest + ySize - 1;
153 src.x = xSrc;
154 src.y = ySrc;
156 do_render_func(destRP, &src, &rr, bltmask_render, &brd, TRUE, GfxBase);
158 RELEASE_HIDD_BM(brd.srcbm_obj, srcBitMap);
160 gc_tags[0].ti_Data = old_drmd;
161 OOP_SetAttrs(gc, gc_tags);
163 RELEASE_DRIVERDATA(destRP, GfxBase);
165 ReturnVoid("BltBitMapRastPort");
167 AROS_LIBFUNC_EXIT
169 } /* BltMaskBitMapRastPort */
171 /****************************************************************************************/
173 static ULONG bltmask_render(APTR bltmask_rd, LONG srcx, LONG srcy,
174 OOP_Object *dstbm_obj, OOP_Object *dst_gc,
175 LONG x1, LONG y1, LONG x2, LONG y2, struct GfxBase *GfxBase)
177 struct bltmask_render_data *brd;
178 OOP_Object *dest_pf;
179 HIDDT_ColorModel dest_colmod;
180 HIDDT_Pixel *pixtab = NULL;
181 ULONG x, y, width, height;
182 LONG lines_done, lines_per_step, doing_lines;
183 BOOL pal_to_true = FALSE;
185 width = x2 - x1 + 1;
186 height = y2 - y1 + 1;
188 OOP_GetAttr(dstbm_obj, aHidd_BitMap_PixFmt, (IPTR *)&dest_pf);
190 IPTR attr;
192 OOP_GetAttr(dest_pf, aHidd_PixFmt_ColorModel, &attr);
193 dest_colmod = (HIDDT_ColorModel)attr;
196 brd = (struct bltmask_render_data *)bltmask_rd;
197 if ((brd->src_colmod == vHidd_ColorModel_Palette) && (dest_colmod == vHidd_ColorModel_Palette))
200 else if ((brd->src_colmod == vHidd_ColorModel_Palette) && (dest_colmod == vHidd_ColorModel_TrueColor))
202 pixtab = IS_HIDD_BM(brd->srcbm) ? HIDD_BM_PIXTAB(brd->srcbm) : NULL;
203 if (!pixtab) pixtab = IS_HIDD_BM(brd->rsi.curbm) ? HIDD_BM_PIXTAB(brd->rsi.curbm) : NULL;
205 if (!pixtab)
207 D(bug("BltMaskBitMapRastPort could not retrieve pixel table for blit from palette to truecolor bitmap"));
208 return width * height;
211 pal_to_true = TRUE;
213 else if ((brd->src_colmod == vHidd_ColorModel_TrueColor) && (dest_colmod == vHidd_ColorModel_TrueColor))
215 if (brd->srcpf != dest_pf)
217 D(bug("BltMaskBitMapRastPort not supporting blit between truecolor bitmaps of different formats yet"));
218 return width * height;
221 else if ((brd->src_colmod == vHidd_ColorModel_TrueColor) && (dest_colmod == vHidd_ColorModel_Palette))
223 D(bug("BltMaskBitMapRastPort from truecolor bitmap to palette bitmap not supported!"));
224 return width * height;
227 lines_per_step = (NUMPIX / (width * 2 * sizeof(HIDDT_Pixel)));
228 if (lines_per_step)
230 UBYTE *srcbuf, *destbuf;
232 LOCK_PIXBUF
234 srcbuf = (UBYTE *)PrivGBase(GfxBase)->pixel_buf;
235 destbuf = srcbuf;
236 destbuf += lines_per_step * width * sizeof(HIDDT_Pixel);
238 for(lines_done = 0; lines_done != height; lines_done += doing_lines)
240 HIDDT_Pixel *srcpixelbuf;
241 HIDDT_Pixel *destpixelbuf;
242 UBYTE *mask;
244 doing_lines = lines_per_step;
245 if (lines_done + doing_lines > height) doing_lines = height - lines_done;
247 HIDD_BM_GetImage(brd->srcbm_obj,
248 srcbuf,
249 width * sizeof(HIDDT_Pixel),
250 srcx, srcy + lines_done,
251 width, doing_lines,
252 vHidd_StdPixFmt_Native32);
254 HIDD_BM_GetImage(dstbm_obj,
255 destbuf,
256 width * sizeof(HIDDT_Pixel),
257 x1, y1 + lines_done,
258 width, doing_lines,
259 vHidd_StdPixFmt_Native32);
261 mask = &brd->mask[COORD_TO_BYTEIDX(0, srcy + lines_done, brd->mask_bpr)];
263 srcpixelbuf = (HIDDT_Pixel *)srcbuf;
264 destpixelbuf = (HIDDT_Pixel *)destbuf;
266 switch(brd->minterm)
268 case (ABC|ABNC|ANBC): /* (ABC|ABNC|ANBC) if copy source and blit thru mask */
269 if (pal_to_true)
271 for(y = 0; y < doing_lines; y++)
273 for(x = 0; x < width; x++)
275 if (mask[XCOORD_TO_BYTEIDX(srcx + x)] & XCOORD_TO_MASK(srcx + x))
277 *destpixelbuf = pixtab[*srcpixelbuf];
279 srcpixelbuf++;
280 destpixelbuf++;
282 mask += brd->mask_bpr;
285 else
287 for(y = 0; y < doing_lines; y++)
289 for(x = 0; x < width; x++)
291 if (mask[XCOORD_TO_BYTEIDX(srcx + x)] & XCOORD_TO_MASK(srcx + x))
293 *destpixelbuf = *srcpixelbuf;
295 srcpixelbuf++;
296 destpixelbuf++;
298 mask += brd->mask_bpr;
301 break;
303 case ANBC: /* (ANBC) if invert source and blit thru mask */
304 D(bug("BltMaskBitMapRastPort does not support ANBC minterm yet"));
305 break;
307 default:
308 D(bug("BltMaskBitMapRastPort: minterm 0x%x not handled.\n", brd->minterm));
309 break;
310 } /* switch(brd->minterm) */
312 HIDD_BM_PutImage(dstbm_obj,
313 dst_gc,
314 destbuf,
315 width * sizeof(HIDDT_Pixel),
316 x1, y1 + lines_done,
317 width, doing_lines,
318 vHidd_StdPixFmt_Native32);
320 } /* for(lines_done = 0; lines_done != height; lines_done += doing_lines) */
322 ULOCK_PIXBUF
324 } /* if (lines_per_step) */
325 else
327 /* urk :-( pixelbuffer too small to hold two lines) */
329 D(bug("BltMaskBitMapRastPort found pixelbuffer to be too small"));
332 return width * height;
335 /****************************************************************************************/