2 Copyright © 1995-2018, The AROS Development Team. All rights reserved.
9 #include <aros/debug.h>
11 #include <proto/cybergraphics.h>
13 #include "cybergraphics_intern.h"
14 #include "gfxfuncsupport.h"
18 OOP_Object
*srcbm_obj
;
27 static ULONG
RenderHook(struct render_data
*data
, LONG srcx
, LONG srcy
,
28 OOP_Object
*dstbm_obj
, OOP_Object
*dst_gc
, struct Rectangle
*rect
,
29 struct GfxBase
*GfxBase
);
31 /* Work around an m68k GCC issue, with AROS_LH10 macros.
33 * Due to the AROS_LH10() macro using so many data registers,
34 * we get a register spill during certain optimization levels.
36 * This 'hack' thunks the register call to a stack call, and passes
37 * the bounds using an address register, so that optimization has more
38 * data registers to play with.
40 * NB: It must have global scope (not 'static') so that it doesn't fold
41 * into the regcall routine. On non-regcall systems, this will, at worst,
42 * convert to a 'JMP internal_ScalePixelArray' with no stack manipulation.
44 LONG
internal_ScalePixelArray(APTR srcRect
, UWORD SrcW
, UWORD SrcH
,
45 UWORD SrcMod
, struct RastPort
*RastPort
, struct dest_box
*dest_bounds
,
46 UBYTE SrcFormat
, struct Library
*CyberGfxBase
);
48 /*****************************************************************************
51 #include <proto/cybergraphics.h>
53 AROS_LH10(LONG
, ScalePixelArray
,
56 AROS_LHA(APTR
, srcRect
, A0
),
57 AROS_LHA(UWORD
, SrcW
, D0
),
58 AROS_LHA(UWORD
, SrcH
, D1
),
59 AROS_LHA(UWORD
, SrcMod
, D2
),
60 AROS_LHA(struct RastPort
*, RastPort
, A1
),
61 AROS_LHA(UWORD
, DestX
, D3
),
62 AROS_LHA(UWORD
, DestY
, D4
),
63 AROS_LHA(UWORD
, DestW
, D5
),
64 AROS_LHA(UWORD
, DestH
, D6
),
65 AROS_LHA(UBYTE
, SrcFormat
, D7
),
68 struct Library
*, CyberGfxBase
, 15, Cybergraphics
)
71 Fills all or part of a RastPort with a rectangular block of raw pixel
72 values. The source pixels are scaled to fit the destination area, i.e.
73 some pixels may be duplicated or dropped according to the need to
74 stretch or compress the source block.
77 srcRect - pointer to the pixel values.
78 SrcW, SrcH - width and height of the source rectangle (in pixels).
79 SrcMod - the number of bytes in each row of the source rectangle.
80 RastPort - the RastPort to write to.
81 DestX, DestY - top-lefthand corner of portion of destination RastPort
82 to write to (in pixels).
83 DestW, DestH - size of the destination rectangle (in pixels).
84 SrcFormat - the format of the source pixels. See WritePixelArray for
88 count - the number of pixels written to.
101 *****************************************************************************/
105 struct dest_box dest_bounds
;
107 dest_bounds
.x
= DestX
;
108 dest_bounds
.y
= DestY
;
109 dest_bounds
.w
= DestW
;
110 dest_bounds
.h
= DestH
;
112 return internal_ScalePixelArray(srcRect
, SrcW
, SrcH
, SrcMod
, RastPort
,
113 &dest_bounds
, SrcFormat
, CyberGfxBase
);
118 LONG
internal_ScalePixelArray(APTR srcRect
, UWORD SrcW
, UWORD SrcH
,
119 UWORD SrcMod
, struct RastPort
*RastPort
, struct dest_box
*dest_bounds
,
120 UBYTE SrcFormat
, struct Library
*CyberGfxBase
)
123 struct render_data data
;
125 OOP_Object
*gfx_hidd
, *tempbm_obj
, *tempbm2_obj
, *gc
;
126 struct BitScaleArgs scale_args
= {0};
127 struct TagItem bm_tags
[] =
129 {aHidd_BitMap_GfxHidd
, 0},
130 {aHidd_BitMap_Width
, SrcW
},
131 {aHidd_BitMap_Height
, SrcH
},
132 {aHidd_BitMap_StdPixFmt
, 0},
135 struct TagItem gc_tags
[] =
137 {aHidd_GC_DrawMode
, vHidd_GC_DrawMode_Copy
},
141 D(bug("ScalePixelArray(%p, %d, %d, %d, %p, %d, %d, %d, %d, %d)\n",
142 srcRect
, SrcW
, SrcH
, SrcMod
, RastPort
, dest_bounds
->x
, dest_bounds
->y
,
143 dest_bounds
->w
, dest_bounds
->h
, SrcFormat
));
145 if (SrcW
== 0 || SrcH
== 0 || dest_bounds
->w
== 0 || dest_bounds
->h
== 0)
148 /* This is AROS Cybergraphx - We only work wih Gfx Hidd bitmaps */
150 if (!IS_HIDD_BM(RastPort
->BitMap
))
152 D(bug("!!!!! Trying to use CGFX call on non-hidd bitmap in ScalePixelArray() !!!\n"));
156 /* Query the bitmaps Gfx Hidd, and create a suitable GC Object (graphics context) */
158 OOP_GetAttr(HIDD_BM_OBJ(RastPort
->BitMap
), aHidd_BitMap_GfxHidd
,
160 gc
= HIDD_Gfx_CreateObject(gfx_hidd
, GetCGFXBase(CyberGfxBase
)->basegc
, gc_tags
);
163 /* Create two temporary bitmap objects: one the size of the source area
164 and another the size of the destination area */
166 bm_tags
[0].ti_Data
= (IPTR
)gfx_hidd
;
167 bm_tags
[3].ti_Data
= GetHIDDRectFmt(SrcFormat
, RastPort
, CyberGfxBase
);
168 tempbm_obj
= HIDD_Gfx_CreateObject(gfx_hidd
, GetCGFXBase(CyberGfxBase
)->basebm
, bm_tags
);
171 bm_tags
[1].ti_Data
= dest_bounds
->w
;
172 bm_tags
[2].ti_Data
= dest_bounds
->h
;
174 // FIXME: This doesn't work (X11 and VESA). Should it?
175 bm_tags
[3].ti_Tag
= aHidd_BitMap_Friend
;
176 bm_tags
[3].ti_Data
= (IPTR
)HIDD_BM_OBJ(RastPort
->BitMap
);
178 tempbm2_obj
= HIDD_Gfx_CreateObject(gfx_hidd
, GetCGFXBase(CyberGfxBase
)->basebm
, bm_tags
);
181 /* Copy the source array to its temporary bitmap object */
183 HIDD_BM_PutImage(tempbm_obj
, gc
, srcRect
, SrcMod
, 0, 0, SrcW
, SrcH
,
184 vHidd_StdPixFmt_Native
);
186 /* Scale temporary source bitmap on to temporary destination bitmap */
188 scale_args
.bsa_SrcWidth
= SrcW
;
189 scale_args
.bsa_SrcHeight
= SrcH
;
190 scale_args
.bsa_DestWidth
= dest_bounds
->w
;
191 scale_args
.bsa_DestHeight
= dest_bounds
->h
;
192 HIDD_BM_BitMapScale(tempbm2_obj
, tempbm_obj
, tempbm2_obj
, &scale_args
,
195 /* Render temporary destination bitmap to destination bitmap */
197 data
.srcbm_obj
= tempbm2_obj
;
198 data
.gfx_hidd
= gfx_hidd
;
199 rr
.MinX
= dest_bounds
->x
;
200 rr
.MinY
= dest_bounds
->y
;
201 rr
.MaxX
= dest_bounds
->x
+ dest_bounds
->w
- 1;
202 rr
.MaxY
= dest_bounds
->y
+ dest_bounds
->h
- 1;
203 result
= DoRenderFunc(RastPort
, NULL
, &rr
, RenderHook
, &data
, TRUE
);
205 /* Discard temporary resources */
207 OOP_DisposeObject(tempbm2_obj
);
209 OOP_DisposeObject(tempbm_obj
);
211 OOP_DisposeObject(gc
);
215 } /* ScalePixelArray */
217 static ULONG
RenderHook(struct render_data
*data
, LONG srcx
, LONG srcy
,
218 OOP_Object
*dstbm_obj
, OOP_Object
*dst_gc
, struct Rectangle
*rect
,
219 struct GfxBase
*GfxBase
)
221 ULONG width
= rect
->MaxX
- rect
->MinX
+ 1;
222 ULONG height
= rect
->MaxY
- rect
->MinY
+ 1;
224 HIDD_Gfx_CopyBox(data
->gfx_hidd
, data
->srcbm_obj
, srcx
, srcy
, dstbm_obj
,
225 rect
->MinX
, rect
->MinY
, width
, height
, dst_gc
);
227 return width
* height
;