1*c2c66affSColin Finck /*
2*c2c66affSColin Finck * PROJECT: ReactOS VGA display driver
3*c2c66affSColin Finck * LICENSE: GPL - See COPYING in the top level directory
4*c2c66affSColin Finck * FILE: win32ss/drivers/displays/vga/objects/lineto.c
5*c2c66affSColin Finck * PURPOSE:
6*c2c66affSColin Finck * PROGRAMMERS: Copyright (C) 1998-2003 ReactOS Team
7*c2c66affSColin Finck */
8*c2c66affSColin Finck
9*c2c66affSColin Finck #include <vgaddi.h>
10*c2c66affSColin Finck
11*c2c66affSColin Finck /*
12*c2c66affSColin Finck * Draw a line from top-left to bottom-right
13*c2c66affSColin Finck */
14*c2c66affSColin Finck static void FASTCALL
vgaNWtoSE(IN CLIPOBJ * Clip,IN BRUSHOBJ * Brush,IN LONG x,IN LONG y,IN LONG deltax,IN LONG deltay)15*c2c66affSColin Finck vgaNWtoSE(
16*c2c66affSColin Finck IN CLIPOBJ* Clip,
17*c2c66affSColin Finck IN BRUSHOBJ* Brush,
18*c2c66affSColin Finck IN LONG x,
19*c2c66affSColin Finck IN LONG y,
20*c2c66affSColin Finck IN LONG deltax,
21*c2c66affSColin Finck IN LONG deltay)
22*c2c66affSColin Finck {
23*c2c66affSColin Finck int i;
24*c2c66affSColin Finck int error;
25*c2c66affSColin Finck BOOLEAN EnumMore;
26*c2c66affSColin Finck PRECTL ClipRect;
27*c2c66affSColin Finck RECT_ENUM RectEnum;
28*c2c66affSColin Finck ULONG Pixel = Brush->iSolidColor;
29*c2c66affSColin Finck LONG delta;
30*c2c66affSColin Finck
31*c2c66affSColin Finck CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0);
32*c2c66affSColin Finck EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
33*c2c66affSColin Finck ClipRect = RectEnum.arcl;
34*c2c66affSColin Finck delta = max(deltax, deltay);
35*c2c66affSColin Finck i = 0;
36*c2c66affSColin Finck error = delta / 2;
37*c2c66affSColin Finck while (i < delta && (ClipRect < RectEnum.arcl + RectEnum.c || EnumMore))
38*c2c66affSColin Finck {
39*c2c66affSColin Finck while ((ClipRect < RectEnum.arcl + RectEnum.c /* there's still a current clip rect */
40*c2c66affSColin Finck && (ClipRect->bottom <= y /* but it's above us */
41*c2c66affSColin Finck || (ClipRect->top <= y && ClipRect->right <= x))) /* or to the left of us */
42*c2c66affSColin Finck || EnumMore) /* no current clip rect, but rects left */
43*c2c66affSColin Finck {
44*c2c66affSColin Finck /* Skip to the next clip rect */
45*c2c66affSColin Finck if (RectEnum.arcl + RectEnum.c <= ClipRect)
46*c2c66affSColin Finck {
47*c2c66affSColin Finck EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
48*c2c66affSColin Finck ClipRect = RectEnum.arcl;
49*c2c66affSColin Finck }
50*c2c66affSColin Finck else
51*c2c66affSColin Finck {
52*c2c66affSColin Finck ClipRect++;
53*c2c66affSColin Finck }
54*c2c66affSColin Finck }
55*c2c66affSColin Finck if ( ClipRect < RectEnum.arcl + RectEnum.c ) /* If there's no current clip rect we're done */
56*c2c66affSColin Finck {
57*c2c66affSColin Finck if (ClipRect->left <= x && ClipRect->top <= y)
58*c2c66affSColin Finck vgaPutPixel ( x, y, Pixel );
59*c2c66affSColin Finck if ( deltax < deltay )
60*c2c66affSColin Finck {
61*c2c66affSColin Finck y++;
62*c2c66affSColin Finck error += deltax;
63*c2c66affSColin Finck if ( error >= deltay )
64*c2c66affSColin Finck {
65*c2c66affSColin Finck x++;
66*c2c66affSColin Finck error -= deltay;
67*c2c66affSColin Finck }
68*c2c66affSColin Finck }
69*c2c66affSColin Finck else
70*c2c66affSColin Finck {
71*c2c66affSColin Finck x++;
72*c2c66affSColin Finck error += deltay;
73*c2c66affSColin Finck if ( error >= deltax )
74*c2c66affSColin Finck {
75*c2c66affSColin Finck y++;
76*c2c66affSColin Finck error -= deltax;
77*c2c66affSColin Finck }
78*c2c66affSColin Finck }
79*c2c66affSColin Finck i++;
80*c2c66affSColin Finck }
81*c2c66affSColin Finck }
82*c2c66affSColin Finck }
83*c2c66affSColin Finck
84*c2c66affSColin Finck static void FASTCALL
vgaSWtoNE(IN CLIPOBJ * Clip,IN BRUSHOBJ * Brush,IN LONG x,IN LONG y,IN LONG deltax,IN LONG deltay)85*c2c66affSColin Finck vgaSWtoNE(
86*c2c66affSColin Finck IN CLIPOBJ* Clip,
87*c2c66affSColin Finck IN BRUSHOBJ* Brush,
88*c2c66affSColin Finck IN LONG x,
89*c2c66affSColin Finck IN LONG y,
90*c2c66affSColin Finck IN LONG deltax,
91*c2c66affSColin Finck IN LONG deltay)
92*c2c66affSColin Finck {
93*c2c66affSColin Finck int i;
94*c2c66affSColin Finck int error;
95*c2c66affSColin Finck BOOLEAN EnumMore;
96*c2c66affSColin Finck PRECTL ClipRect;
97*c2c66affSColin Finck RECT_ENUM RectEnum;
98*c2c66affSColin Finck ULONG Pixel = Brush->iSolidColor;
99*c2c66affSColin Finck LONG delta;
100*c2c66affSColin Finck
101*c2c66affSColin Finck CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTUP, 0);
102*c2c66affSColin Finck EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
103*c2c66affSColin Finck ClipRect = RectEnum.arcl;
104*c2c66affSColin Finck delta = max(deltax, deltay);
105*c2c66affSColin Finck i = 0;
106*c2c66affSColin Finck error = delta / 2;
107*c2c66affSColin Finck while (i < delta && (ClipRect < RectEnum.arcl + RectEnum.c || EnumMore))
108*c2c66affSColin Finck {
109*c2c66affSColin Finck while ((ClipRect < RectEnum.arcl + RectEnum.c
110*c2c66affSColin Finck && (y < ClipRect->top
111*c2c66affSColin Finck || (y < ClipRect->bottom && ClipRect->right <= x)))
112*c2c66affSColin Finck || EnumMore)
113*c2c66affSColin Finck {
114*c2c66affSColin Finck if (RectEnum.arcl + RectEnum.c <= ClipRect)
115*c2c66affSColin Finck {
116*c2c66affSColin Finck EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
117*c2c66affSColin Finck ClipRect = RectEnum.arcl;
118*c2c66affSColin Finck }
119*c2c66affSColin Finck else
120*c2c66affSColin Finck {
121*c2c66affSColin Finck ClipRect++;
122*c2c66affSColin Finck }
123*c2c66affSColin Finck }
124*c2c66affSColin Finck if (ClipRect < RectEnum.arcl + RectEnum.c)
125*c2c66affSColin Finck {
126*c2c66affSColin Finck if (ClipRect->left <= x && y < ClipRect->bottom)
127*c2c66affSColin Finck vgaPutPixel(x, y, Pixel);
128*c2c66affSColin Finck if (deltax < deltay)
129*c2c66affSColin Finck {
130*c2c66affSColin Finck y--;
131*c2c66affSColin Finck error = error + deltax;
132*c2c66affSColin Finck if (deltay <= error)
133*c2c66affSColin Finck {
134*c2c66affSColin Finck x++;
135*c2c66affSColin Finck error = error - deltay;
136*c2c66affSColin Finck }
137*c2c66affSColin Finck }
138*c2c66affSColin Finck else
139*c2c66affSColin Finck {
140*c2c66affSColin Finck x++;
141*c2c66affSColin Finck error = error + deltay;
142*c2c66affSColin Finck if (deltax <= error)
143*c2c66affSColin Finck {
144*c2c66affSColin Finck y--;
145*c2c66affSColin Finck error = error - deltax;
146*c2c66affSColin Finck }
147*c2c66affSColin Finck }
148*c2c66affSColin Finck i++;
149*c2c66affSColin Finck }
150*c2c66affSColin Finck }
151*c2c66affSColin Finck }
152*c2c66affSColin Finck
153*c2c66affSColin Finck static void FASTCALL
vgaNEtoSW(IN CLIPOBJ * Clip,IN BRUSHOBJ * Brush,IN LONG x,IN LONG y,IN LONG deltax,IN LONG deltay)154*c2c66affSColin Finck vgaNEtoSW(
155*c2c66affSColin Finck IN CLIPOBJ* Clip,
156*c2c66affSColin Finck IN BRUSHOBJ* Brush,
157*c2c66affSColin Finck IN LONG x,
158*c2c66affSColin Finck IN LONG y,
159*c2c66affSColin Finck IN LONG deltax,
160*c2c66affSColin Finck IN LONG deltay)
161*c2c66affSColin Finck {
162*c2c66affSColin Finck int i;
163*c2c66affSColin Finck int error;
164*c2c66affSColin Finck BOOLEAN EnumMore;
165*c2c66affSColin Finck PRECTL ClipRect;
166*c2c66affSColin Finck RECT_ENUM RectEnum;
167*c2c66affSColin Finck ULONG Pixel = Brush->iSolidColor;
168*c2c66affSColin Finck LONG delta;
169*c2c66affSColin Finck
170*c2c66affSColin Finck CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_LEFTDOWN, 0);
171*c2c66affSColin Finck EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
172*c2c66affSColin Finck ClipRect = RectEnum.arcl;
173*c2c66affSColin Finck delta = max(deltax, deltay);
174*c2c66affSColin Finck i = 0;
175*c2c66affSColin Finck error = delta / 2;
176*c2c66affSColin Finck while (i < delta && (ClipRect < RectEnum.arcl + RectEnum.c || EnumMore))
177*c2c66affSColin Finck {
178*c2c66affSColin Finck while ((ClipRect < RectEnum.arcl + RectEnum.c
179*c2c66affSColin Finck && (ClipRect->bottom <= y
180*c2c66affSColin Finck || (ClipRect->top <= y && x < ClipRect->left)))
181*c2c66affSColin Finck || EnumMore)
182*c2c66affSColin Finck {
183*c2c66affSColin Finck if (RectEnum.arcl + RectEnum.c <= ClipRect)
184*c2c66affSColin Finck {
185*c2c66affSColin Finck EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
186*c2c66affSColin Finck ClipRect = RectEnum.arcl;
187*c2c66affSColin Finck }
188*c2c66affSColin Finck else
189*c2c66affSColin Finck {
190*c2c66affSColin Finck ClipRect++;
191*c2c66affSColin Finck }
192*c2c66affSColin Finck }
193*c2c66affSColin Finck if (ClipRect < RectEnum.arcl + RectEnum.c)
194*c2c66affSColin Finck {
195*c2c66affSColin Finck if (x < ClipRect->right && ClipRect->top <= y)
196*c2c66affSColin Finck vgaPutPixel(x, y, Pixel);
197*c2c66affSColin Finck if (deltax < deltay)
198*c2c66affSColin Finck {
199*c2c66affSColin Finck y++;
200*c2c66affSColin Finck error = error + deltax;
201*c2c66affSColin Finck if (deltay <= error)
202*c2c66affSColin Finck {
203*c2c66affSColin Finck x--;
204*c2c66affSColin Finck error = error - deltay;
205*c2c66affSColin Finck }
206*c2c66affSColin Finck }
207*c2c66affSColin Finck else
208*c2c66affSColin Finck {
209*c2c66affSColin Finck x--;
210*c2c66affSColin Finck error = error + deltay;
211*c2c66affSColin Finck if (deltax <= error)
212*c2c66affSColin Finck {
213*c2c66affSColin Finck y++;
214*c2c66affSColin Finck error = error - deltax;
215*c2c66affSColin Finck }
216*c2c66affSColin Finck }
217*c2c66affSColin Finck i++;
218*c2c66affSColin Finck }
219*c2c66affSColin Finck }
220*c2c66affSColin Finck }
221*c2c66affSColin Finck
222*c2c66affSColin Finck static void FASTCALL
vgaSEtoNW(IN CLIPOBJ * Clip,IN BRUSHOBJ * Brush,IN LONG x,IN LONG y,IN LONG deltax,IN LONG deltay)223*c2c66affSColin Finck vgaSEtoNW(
224*c2c66affSColin Finck IN CLIPOBJ* Clip,
225*c2c66affSColin Finck IN BRUSHOBJ* Brush,
226*c2c66affSColin Finck IN LONG x,
227*c2c66affSColin Finck IN LONG y,
228*c2c66affSColin Finck IN LONG deltax,
229*c2c66affSColin Finck IN LONG deltay)
230*c2c66affSColin Finck {
231*c2c66affSColin Finck int i;
232*c2c66affSColin Finck int error;
233*c2c66affSColin Finck BOOLEAN EnumMore;
234*c2c66affSColin Finck PRECTL ClipRect;
235*c2c66affSColin Finck RECT_ENUM RectEnum;
236*c2c66affSColin Finck ULONG Pixel = Brush->iSolidColor;
237*c2c66affSColin Finck LONG delta;
238*c2c66affSColin Finck
239*c2c66affSColin Finck CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_LEFTUP, 0);
240*c2c66affSColin Finck EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
241*c2c66affSColin Finck ClipRect = RectEnum.arcl;
242*c2c66affSColin Finck delta = max(deltax, deltay);
243*c2c66affSColin Finck i = 0;
244*c2c66affSColin Finck error = delta / 2;
245*c2c66affSColin Finck while (i < delta && (ClipRect < RectEnum.arcl + RectEnum.c || EnumMore))
246*c2c66affSColin Finck {
247*c2c66affSColin Finck while ((ClipRect < RectEnum.arcl + RectEnum.c
248*c2c66affSColin Finck && (y < ClipRect->top
249*c2c66affSColin Finck || (y < ClipRect->bottom && x < ClipRect->left)))
250*c2c66affSColin Finck || EnumMore)
251*c2c66affSColin Finck {
252*c2c66affSColin Finck if (RectEnum.arcl + RectEnum.c <= ClipRect)
253*c2c66affSColin Finck {
254*c2c66affSColin Finck EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
255*c2c66affSColin Finck ClipRect = RectEnum.arcl;
256*c2c66affSColin Finck }
257*c2c66affSColin Finck else
258*c2c66affSColin Finck {
259*c2c66affSColin Finck ClipRect++;
260*c2c66affSColin Finck }
261*c2c66affSColin Finck }
262*c2c66affSColin Finck if (ClipRect < RectEnum.arcl + RectEnum.c)
263*c2c66affSColin Finck {
264*c2c66affSColin Finck if (x < ClipRect->right && y < ClipRect->bottom)
265*c2c66affSColin Finck vgaPutPixel(x, y, Pixel);
266*c2c66affSColin Finck if (deltax < deltay)
267*c2c66affSColin Finck {
268*c2c66affSColin Finck y--;
269*c2c66affSColin Finck error = error + deltax;
270*c2c66affSColin Finck if (deltay <= error)
271*c2c66affSColin Finck {
272*c2c66affSColin Finck x--;
273*c2c66affSColin Finck error = error - deltay;
274*c2c66affSColin Finck }
275*c2c66affSColin Finck }
276*c2c66affSColin Finck else
277*c2c66affSColin Finck {
278*c2c66affSColin Finck x--;
279*c2c66affSColin Finck error = error + deltay;
280*c2c66affSColin Finck if (deltax <= error)
281*c2c66affSColin Finck {
282*c2c66affSColin Finck y--;
283*c2c66affSColin Finck error = error - deltax;
284*c2c66affSColin Finck }
285*c2c66affSColin Finck }
286*c2c66affSColin Finck i++;
287*c2c66affSColin Finck }
288*c2c66affSColin Finck }
289*c2c66affSColin Finck }
290*c2c66affSColin Finck
291*c2c66affSColin Finck /*
292*c2c66affSColin Finck * FIXME: Use Mix to perform ROPs
293*c2c66affSColin Finck * FIXME: Non-solid Brush
294*c2c66affSColin Finck */
295*c2c66affSColin Finck BOOL APIENTRY
DrvLineTo(IN SURFOBJ * DestObj,IN CLIPOBJ * Clip,IN BRUSHOBJ * Brush,IN LONG x1,IN LONG y1,IN LONG x2,IN LONG y2,IN RECTL * RectBounds,IN MIX mix)296*c2c66affSColin Finck DrvLineTo(
297*c2c66affSColin Finck IN SURFOBJ *DestObj,
298*c2c66affSColin Finck IN CLIPOBJ *Clip,
299*c2c66affSColin Finck IN BRUSHOBJ *Brush,
300*c2c66affSColin Finck IN LONG x1,
301*c2c66affSColin Finck IN LONG y1,
302*c2c66affSColin Finck IN LONG x2,
303*c2c66affSColin Finck IN LONG y2,
304*c2c66affSColin Finck IN RECTL *RectBounds,
305*c2c66affSColin Finck IN MIX mix)
306*c2c66affSColin Finck {
307*c2c66affSColin Finck LONG x, y, deltax, deltay, xchange, ychange, hx, vy;
308*c2c66affSColin Finck ULONG i;
309*c2c66affSColin Finck ULONG Pixel = Brush->iSolidColor;
310*c2c66affSColin Finck RECT_ENUM RectEnum;
311*c2c66affSColin Finck BOOL EnumMore;
312*c2c66affSColin Finck
313*c2c66affSColin Finck x = x1;
314*c2c66affSColin Finck y = y1;
315*c2c66affSColin Finck deltax = x2 - x1;
316*c2c66affSColin Finck deltay = y2 - y1;
317*c2c66affSColin Finck
318*c2c66affSColin Finck if (deltax < 0)
319*c2c66affSColin Finck {
320*c2c66affSColin Finck xchange = -1;
321*c2c66affSColin Finck deltax = - deltax;
322*c2c66affSColin Finck hx = x2+1;
323*c2c66affSColin Finck //x--;
324*c2c66affSColin Finck }
325*c2c66affSColin Finck else
326*c2c66affSColin Finck {
327*c2c66affSColin Finck xchange = 1;
328*c2c66affSColin Finck hx = x1;
329*c2c66affSColin Finck }
330*c2c66affSColin Finck
331*c2c66affSColin Finck if (deltay < 0)
332*c2c66affSColin Finck {
333*c2c66affSColin Finck ychange = -1;
334*c2c66affSColin Finck deltay = - deltay;
335*c2c66affSColin Finck vy = y2+1;
336*c2c66affSColin Finck //y--;
337*c2c66affSColin Finck }
338*c2c66affSColin Finck else
339*c2c66affSColin Finck {
340*c2c66affSColin Finck ychange = 1;
341*c2c66affSColin Finck vy = y1;
342*c2c66affSColin Finck }
343*c2c66affSColin Finck
344*c2c66affSColin Finck if (y1 == y2)
345*c2c66affSColin Finck {
346*c2c66affSColin Finck CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0);
347*c2c66affSColin Finck do
348*c2c66affSColin Finck {
349*c2c66affSColin Finck EnumMore = CLIPOBJ_bEnum(Clip, sizeof(RectEnum), (PVOID) &RectEnum);
350*c2c66affSColin Finck for (i = 0; i < RectEnum.c && RectEnum.arcl[i].top <= y1; i++)
351*c2c66affSColin Finck {
352*c2c66affSColin Finck if (y1 < RectEnum.arcl[i].bottom &&
353*c2c66affSColin Finck RectEnum.arcl[i].left <= hx + deltax &&
354*c2c66affSColin Finck hx < RectEnum.arcl[i].right)
355*c2c66affSColin Finck {
356*c2c66affSColin Finck vgaHLine(max(hx, RectEnum.arcl[i].left), y1,
357*c2c66affSColin Finck min(hx + deltax, RectEnum.arcl[i].right)
358*c2c66affSColin Finck -max(hx, RectEnum.arcl[i].left), Pixel);
359*c2c66affSColin Finck }
360*c2c66affSColin Finck }
361*c2c66affSColin Finck } while (EnumMore);
362*c2c66affSColin Finck }
363*c2c66affSColin Finck else if (x1 == x2)
364*c2c66affSColin Finck {
365*c2c66affSColin Finck CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0);
366*c2c66affSColin Finck do
367*c2c66affSColin Finck {
368*c2c66affSColin Finck EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
369*c2c66affSColin Finck for (i = 0; i < RectEnum.c; i++)
370*c2c66affSColin Finck {
371*c2c66affSColin Finck if (RectEnum.arcl[i].left <= x1 &&
372*c2c66affSColin Finck x1 < RectEnum.arcl[i].right &&
373*c2c66affSColin Finck RectEnum.arcl[i].top <= vy + deltay &&
374*c2c66affSColin Finck vy < RectEnum.arcl[i].bottom)
375*c2c66affSColin Finck {
376*c2c66affSColin Finck vgaVLine(x1,
377*c2c66affSColin Finck max(vy, RectEnum.arcl[i].top),
378*c2c66affSColin Finck min(vy + deltay, RectEnum.arcl[i].bottom)
379*c2c66affSColin Finck - max(vy, RectEnum.arcl[i].top),
380*c2c66affSColin Finck Pixel);
381*c2c66affSColin Finck }
382*c2c66affSColin Finck }
383*c2c66affSColin Finck } while (EnumMore);
384*c2c66affSColin Finck }
385*c2c66affSColin Finck else
386*c2c66affSColin Finck {
387*c2c66affSColin Finck if (0 < xchange)
388*c2c66affSColin Finck {
389*c2c66affSColin Finck if (0 < ychange)
390*c2c66affSColin Finck vgaNWtoSE(Clip, Brush, x, y, deltax, deltay);
391*c2c66affSColin Finck else
392*c2c66affSColin Finck vgaSWtoNE(Clip, Brush, x, y, deltax, deltay);
393*c2c66affSColin Finck }
394*c2c66affSColin Finck else
395*c2c66affSColin Finck {
396*c2c66affSColin Finck if (0 < ychange)
397*c2c66affSColin Finck vgaNEtoSW(Clip, Brush, x, y, deltax, deltay);
398*c2c66affSColin Finck else
399*c2c66affSColin Finck vgaSEtoNW(Clip, Brush, x, y, deltax, deltay);
400*c2c66affSColin Finck }
401*c2c66affSColin Finck }
402*c2c66affSColin Finck
403*c2c66affSColin Finck return TRUE;
404*c2c66affSColin Finck }
405*c2c66affSColin Finck
406*c2c66affSColin Finck /* EOF */
407