r4493@vps: verhaegs | 2007-04-19 14:44:00 -0400
[AROS.git] / rom / graphics / draw.c
blob70d980af599161c98e53628ed6d474836959e38b
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Graphics function Draw()
6 Lang: english
7 */
9 #include <aros/debug.h>
10 #include <clib/macros.h>
11 #include <graphics/rastport.h>
12 #include <proto/graphics.h>
13 #include <proto/oop.h>
14 #include "gfxfuncsupport.h"
15 #include "graphics_intern.h"
16 #include "intregions.h"
17 #include <stdlib.h>
19 /*****************************************************************************
21 NAME */
23 AROS_LH3(void, Draw,
25 /* SYNOPSIS */
26 AROS_LHA(struct RastPort *, rp, A1),
27 AROS_LHA(LONG , x, D0),
28 AROS_LHA(LONG , y, D1),
30 /* LOCATION */
31 struct GfxBase *, GfxBase, 41, Graphics)
33 /* FUNCTION
34 Draw a line from the current pen position to the given coordinate.
36 INPUTS
37 rp - destination RastPort.
38 x,y - line end coordinate.
40 RESULT
42 NOTES
43 Not yet implemented:
45 - handle layer->Scroll_X/Scroll_Y.
47 - handle FRST_DOT which indicates whether to draw
48 or to don't draw first pixel of line. Important
49 for COMPLEMENT drawmode.
51 EXAMPLE
53 BUGS
55 SEE ALSO
57 INTERNALS
59 HISTORY
60 29-10-95 digulla automatically created from
61 graphics_lib.fd and clib/graphics_protos.h
63 *****************************************************************************/
65 AROS_LIBFUNC_INIT
66 AROS_LIBBASE_EXT_DECL(struct GfxBase *,GfxBase)
69 struct Rectangle rr;
70 OOP_Object *gc;
71 struct Layer *L = rp->Layer;
72 struct BitMap *bm = rp->BitMap;
73 struct Rectangle rp_clip_rectangle;
74 BOOL have_rp_cliprectangle;
75 LONG dx, dy;
76 LONG x1, y1;
78 if (!OBTAIN_DRIVERDATA(rp, GfxBase))
79 return;
81 FIX_GFXCOORD(x);
82 FIX_GFXCOORD(y);
84 x1 = rp->cp_x;
85 y1 = rp->cp_y;
87 gc = GetDriverData(rp)->dd_GC;
89 if (x1 > x)
91 rr.MinX = x;
92 rr.MaxX = x1;
94 else
96 rr.MinX = x1;
97 rr.MaxX = x;
100 if (y1 > y)
102 rr.MinY = y;
103 rr.MaxY = y1;
105 else
107 rr.MinY = y1;
108 rr.MaxY = y;
112 UWORD lineptrn = rp->LinePtrn;
114 if (rp->DrawMode & INVERSVID) lineptrn = ~lineptrn;
117 struct TagItem gctags[] =
119 {aHidd_GC_LinePattern , lineptrn },
120 {aHidd_GC_LinePatternCnt, rp->linpatcnt },
121 {TAG_DONE }
124 OOP_SetAttrs( gc, gctags);
129 if (NULL == L)
131 /* No layer, probably a screen, but may be a user inited bitmap */
132 OOP_Object *bm_obj;
134 bm_obj = OBTAIN_HIDD_BM(bm);
135 if (bm_obj)
137 /* No need for clipping */
138 HIDD_BM_DrawLine(bm_obj, gc, x1, y1, x, y);
140 RELEASE_HIDD_BM(bm_obj, bm);
144 else
146 struct ClipRect *CR;
147 WORD xrel;
148 WORD yrel;
149 struct Rectangle torender, intersect;
150 OOP_Object *bm_obj;
152 LockLayerRom(L);
154 x1 -= L->Scroll_X;
155 y1 -= L->Scroll_Y;
156 x -= L->Scroll_X;
157 y -= L->Scroll_Y;
159 have_rp_cliprectangle = GetRPClipRectangleForLayer(rp, L, &rp_clip_rectangle, GfxBase);
161 xrel = L->bounds.MinX;
162 yrel = L->bounds.MinY;
164 torender.MinX = rr.MinX + xrel - L->Scroll_X;
165 torender.MinY = rr.MinY + yrel - L->Scroll_Y;
166 torender.MaxX = rr.MaxX + xrel - L->Scroll_X;
167 torender.MaxY = rr.MaxY + yrel - L->Scroll_Y;
169 CR = L->ClipRect;
171 for (;NULL != CR; CR = CR->Next)
173 D(bug("Cliprect (%d, %d, %d, %d), lobs=%p\n",
174 CR->bounds.MinX, CR->bounds.MinY, CR->bounds.MaxX, CR->bounds.MaxY,
175 CR->lobs));
177 /* Does this cliprect intersect with area to rectfill ? */
178 if (_AndRectRect(&CR->bounds, &torender, &intersect))
180 if (!have_rp_cliprectangle || _AndRectRect(&rp_clip_rectangle, &intersect, &intersect))
182 if (NULL == CR->lobs)
184 /* Set clip rectangle */
185 HIDD_GC_SetClipRect(gc
186 , intersect.MinX
187 , intersect.MinY
188 , intersect.MaxX
189 , intersect.MaxY
192 bm_obj = OBTAIN_HIDD_BM(bm);
193 if (bm_obj)
195 HIDD_BM_DrawLine(bm_obj
196 , gc
197 , x1 + xrel
198 , y1 + yrel
199 , x + xrel
200 , y + yrel
203 RELEASE_HIDD_BM(bm_obj, bm);
206 HIDD_GC_UnsetClipRect(gc);
209 else
211 /* Render into offscreen cliprect bitmap */
212 if (L->Flags & LAYERSIMPLE)
213 continue;
214 else if (L->Flags & LAYERSUPER)
216 D(bug("do_render_func(): Superbitmap not handled yet\n"));
218 else
220 LONG bm_rel_minx, bm_rel_miny, bm_rel_maxx, bm_rel_maxy;
221 LONG layer_rel_x, layer_rel_y;
223 layer_rel_x = intersect.MinX - xrel;
224 layer_rel_y = intersect.MinY - yrel;
227 bm_rel_minx = intersect.MinX - CR->bounds.MinX;
228 bm_rel_miny = intersect.MinY - CR->bounds.MinY;
229 bm_rel_maxx = intersect.MaxX - CR->bounds.MinX;
230 bm_rel_maxy = intersect.MaxY - CR->bounds.MinY;
232 HIDD_GC_SetClipRect(gc
233 , bm_rel_minx + ALIGN_OFFSET(CR->bounds.MinX)
234 , bm_rel_miny
235 , bm_rel_maxx + ALIGN_OFFSET(CR->bounds.MinX)
236 , bm_rel_maxy
239 bm_obj = OBTAIN_HIDD_BM(CR->BitMap);
240 if (bm_obj)
242 HIDD_BM_DrawLine(bm_obj
243 , gc
244 , bm_rel_minx - (layer_rel_x - x1) + ALIGN_OFFSET(CR->bounds.MinX)
245 , bm_rel_miny - (layer_rel_y - y1)
246 , bm_rel_minx - (layer_rel_x - x) + ALIGN_OFFSET(CR->bounds.MinX)
247 , bm_rel_miny - (layer_rel_y - y)
250 RELEASE_HIDD_BM(bm_obj, CR->BitMap);
252 HIDD_GC_UnsetClipRect(gc);
255 } /* if (CR->lobs == NULL) */
257 } /* if it also intersects with possible rastport clip rectangle */
259 } /* if (cliprect intersects with area to render into) */
261 } /* for (each cliprect in the layer) */
263 UnlockLayerRom(L);
265 } /* if (rp->Layer) */
267 dx = abs(x1 - x);
268 dy = abs(y1 - y);
269 if (dy > dx) dx = dy;
271 rp->linpatcnt = ((LONG)rp->linpatcnt - dx) & 15;
273 rp->cp_x = x;
274 rp->cp_y = y;
276 RELEASE_DRIVERDATA(rp, GfxBase);
278 AROS_LIBFUNC_EXIT
280 } /* Draw */