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
;
22 static ULONG
RenderHook(struct render_data
*data
, LONG srcx
, LONG srcy
,
23 OOP_Object
*dstbm_obj
, OOP_Object
*dst_gc
, struct Rectangle
*rect
,
24 struct GfxBase
*GfxBase
);
26 /* Work around an m68k GCC issue, with AROS_LH10 macros.
28 * Due to the AROS_LH10() macro using so many data registers,
29 * we get a register spill during certain optimization levels.
31 * This 'hack' thunks the register call to a stack call, and passes
32 * the bounds using an address register, so that optimization has more
33 * data registers to play with.
35 * NB: It must have global scope (not 'static') so that it doesn't fold
36 * into the regcall routine. On non-regcall systems, this will, at worst,
37 * convert to a 'JMP internal_ScalePixelArray' with no stack manipulation.
39 LONG
internal_ScalePixelArray(APTR srcRect
, UWORD SrcW
, UWORD SrcH
, UWORD SrcMod
, struct RastPort
*RastPort
, struct Rectangle
*DstBounds
, UBYTE SrcFormat
, struct Library
*CyberGfxBase
);
41 /*****************************************************************************
44 #include <proto/cybergraphics.h>
46 AROS_LH10(LONG
, ScalePixelArray
,
49 AROS_LHA(APTR
, srcRect
, A0
),
50 AROS_LHA(UWORD
, SrcW
, D0
),
51 AROS_LHA(UWORD
, SrcH
, D1
),
52 AROS_LHA(UWORD
, SrcMod
, D2
),
53 AROS_LHA(struct RastPort
*, RastPort
, A1
),
54 AROS_LHA(UWORD
, DestX
, D3
),
55 AROS_LHA(UWORD
, DestY
, D4
),
56 AROS_LHA(UWORD
, DestW
, D5
),
57 AROS_LHA(UWORD
, DestH
, D6
),
58 AROS_LHA(UBYTE
, SrcFormat
, D7
),
61 struct Library
*, CyberGfxBase
, 15, Cybergraphics
)
64 Fills all or part of a RastPort with a rectangular block of raw pixel
65 values. The source pixels are scaled to fit the destination area, i.e.
66 some pixels may be duplicated or dropped according to the need to
67 stretch or compress the source block.
70 srcRect - pointer to the pixel values.
71 SrcW, SrcH - width and height of the source rectangle (in pixels).
72 SrcMod - the number of bytes in each row of the source rectangle.
73 RastPort - the RastPort to write to.
74 DestX, DestY - top-lefthand corner of portion of destination RastPort
75 to write to (in pixels).
76 DestW, DestH - size of the destination rectangle (in pixels).
77 SrcFormat - the format of the source pixels. See WritePixelArray for
81 count - the number of pixels written to.
94 *****************************************************************************/
98 struct Rectangle DestBounds
;
100 DestBounds
.MinX
= DestX
;
101 DestBounds
.MinY
= DestY
;
102 DestBounds
.MaxX
= DestW
;
103 DestBounds
.MaxY
= DestH
;
105 return internal_ScalePixelArray(srcRect
, SrcW
, SrcH
, SrcMod
, RastPort
, &DestBounds
, SrcFormat
, CyberGfxBase
);
110 LONG
internal_ScalePixelArray(APTR srcRect
, UWORD SrcW
, UWORD SrcH
, UWORD SrcMod
, struct RastPort
*RastPort
, struct Rectangle
*DstBounds
, UBYTE SrcFormat
, struct Library
*CyberGfxBase
)
113 struct render_data data
;
115 OOP_Object
*gfx_hidd
, *tempbm_obj
, *tempbm2_obj
, *gc
;
116 struct BitScaleArgs scale_args
= {0};
117 struct TagItem bm_tags
[] =
119 {aHidd_BitMap_GfxHidd
, 0},
120 {aHidd_BitMap_Width
, SrcW
},
121 {aHidd_BitMap_Height
, SrcH
},
122 {aHidd_BitMap_StdPixFmt
, 0},
125 struct TagItem gc_tags
[] =
127 {aHidd_GC_DrawMode
, vHidd_GC_DrawMode_Copy
},
131 D(bug("ScalePixelArray(%p, %d, %d, %d, %p, %d, %d, %d, %d, %d)\n",
132 srcRect
, SrcW
, SrcH
, SrcMod
, RastPort
, DstBounds
->MinX
, DstBounds
->MinY
, DstBounds
->MaxX
, DstBounds
->MaxY
,
135 if (SrcW
== 0 || SrcH
== 0 || DstBounds
->MaxX
== 0 || DstBounds
->MaxY
== 0)
138 /* This is AROS Cybergraphx - We only work wih Gfx Hidd bitmaps */
140 if (!IS_HIDD_BM(RastPort
->BitMap
))
142 D(bug("!!!!! Trying to use CGFX call on non-hidd bitmap in ScalePixelArray() !!!\n"));
146 /* Query the bitmaps Gfx Hidd, and create a suitable GC Object (graphics context) */
148 OOP_GetAttr(HIDD_BM_OBJ(RastPort
->BitMap
), aHidd_BitMap_GfxHidd
,
150 gc
= HIDD_Gfx_CreateObject(gfx_hidd
, GetCGFXBase(CyberGfxBase
)->basegc
, gc_tags
);
153 /* Create two temporary bitmap objects: one the size of the source area
154 and another the size of the destination area */
156 bm_tags
[0].ti_Data
= (IPTR
)gfx_hidd
;
157 bm_tags
[3].ti_Data
= GetHIDDRectFmt(SrcFormat
, RastPort
, CyberGfxBase
);
158 tempbm_obj
= HIDD_Gfx_CreateObject(gfx_hidd
, GetCGFXBase(CyberGfxBase
)->basebm
, bm_tags
);
161 bm_tags
[1].ti_Data
= DstBounds
->MaxX
;
162 bm_tags
[2].ti_Data
= DstBounds
->MaxY
;
164 // FIXME: This doesn't work (X11 and VESA). Should it?
165 bm_tags
[3].ti_Tag
= aHidd_BitMap_Friend
;
166 bm_tags
[3].ti_Data
= (IPTR
)HIDD_BM_OBJ(RastPort
->BitMap
);
168 tempbm2_obj
= HIDD_Gfx_CreateObject(gfx_hidd
, GetCGFXBase(CyberGfxBase
)->basebm
, bm_tags
);
171 /* Copy the source array to its temporary bitmap object */
173 HIDD_BM_PutImage(tempbm_obj
, gc
, srcRect
, SrcMod
, 0, 0, SrcW
, SrcH
,
174 vHidd_StdPixFmt_Native
);
176 /* Scale temporary source bitmap on to temporary destination bitmap */
178 scale_args
.bsa_SrcWidth
= SrcW
;
179 scale_args
.bsa_SrcHeight
= SrcH
;
180 scale_args
.bsa_DestWidth
= DstBounds
->MaxX
;
181 scale_args
.bsa_DestHeight
= DstBounds
->MaxY
;
182 HIDD_BM_BitMapScale(tempbm2_obj
, tempbm_obj
, tempbm2_obj
, &scale_args
,
185 /* Render temporary destination bitmap to destination bitmap */
187 data
.srcbm_obj
= tempbm2_obj
;
188 data
.gfx_hidd
= gfx_hidd
;
189 rr
.MinX
= DstBounds
->MinX
;
190 rr
.MinY
= DstBounds
->MinY
;
191 rr
.MaxX
= DstBounds
->MinX
+ DstBounds
->MaxX
- 1;
192 rr
.MaxY
= DstBounds
->MinY
+ DstBounds
->MaxY
- 1;
193 result
= DoRenderFunc(RastPort
, NULL
, &rr
, RenderHook
, &data
, TRUE
);
196 * Discard temporary resources ...
199 OOP_DisposeObject(tempbm2_obj
);
201 OOP_DisposeObject(tempbm_obj
);
203 OOP_DisposeObject(gc
);
207 } /* ScalePixelArray */
209 static ULONG
RenderHook(struct render_data
*data
, LONG srcx
, LONG srcy
,
210 OOP_Object
*dstbm_obj
, OOP_Object
*dst_gc
, struct Rectangle
*rect
,
211 struct GfxBase
*GfxBase
)
213 ULONG width
= rect
->MaxX
- rect
->MinX
+ 1;
214 ULONG height
= rect
->MaxY
- rect
->MinY
+ 1;
216 HIDD_Gfx_CopyBox(data
->gfx_hidd
, data
->srcbm_obj
, srcx
, srcy
, dstbm_obj
,
217 rect
->MinX
, rect
->MinY
, width
, height
, dst_gc
);
219 return width
* height
;