reactos/win32ss/drivers/displays/vga/objects/lineto.c
Hermès Bélusca-Maïto 9393fc320e
[FORMATTING] Remove trailing whitespace. Addendum to 34593d93.
Excluded: 3rd-party code (incl. wine) and most of the win32ss.
2021-09-13 03:52:22 +02:00

406 lines
10 KiB
C

/*
* PROJECT: ReactOS VGA display driver
* LICENSE: GPL - See COPYING in the top level directory
* FILE: win32ss/drivers/displays/vga/objects/lineto.c
* PURPOSE:
* PROGRAMMERS: Copyright (C) 1998-2003 ReactOS Team
*/
#include <vgaddi.h>
/*
* Draw a line from top-left to bottom-right
*/
static void FASTCALL
vgaNWtoSE(
IN CLIPOBJ* Clip,
IN BRUSHOBJ* Brush,
IN LONG x,
IN LONG y,
IN LONG deltax,
IN LONG deltay)
{
int i;
int error;
BOOLEAN EnumMore;
PRECTL ClipRect;
RECT_ENUM RectEnum;
ULONG Pixel = Brush->iSolidColor;
LONG delta;
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0);
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
ClipRect = RectEnum.arcl;
delta = max(deltax, deltay);
i = 0;
error = delta / 2;
while (i < delta && (ClipRect < RectEnum.arcl + RectEnum.c || EnumMore))
{
while ((ClipRect < RectEnum.arcl + RectEnum.c /* there's still a current clip rect */
&& (ClipRect->bottom <= y /* but it's above us */
|| (ClipRect->top <= y && ClipRect->right <= x))) /* or to the left of us */
|| EnumMore) /* no current clip rect, but rects left */
{
/* Skip to the next clip rect */
if (RectEnum.arcl + RectEnum.c <= ClipRect)
{
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
ClipRect = RectEnum.arcl;
}
else
{
ClipRect++;
}
}
if ( ClipRect < RectEnum.arcl + RectEnum.c ) /* If there's no current clip rect we're done */
{
if (ClipRect->left <= x && ClipRect->top <= y)
vgaPutPixel ( x, y, Pixel );
if ( deltax < deltay )
{
y++;
error += deltax;
if ( error >= deltay )
{
x++;
error -= deltay;
}
}
else
{
x++;
error += deltay;
if ( error >= deltax )
{
y++;
error -= deltax;
}
}
i++;
}
}
}
static void FASTCALL
vgaSWtoNE(
IN CLIPOBJ* Clip,
IN BRUSHOBJ* Brush,
IN LONG x,
IN LONG y,
IN LONG deltax,
IN LONG deltay)
{
int i;
int error;
BOOLEAN EnumMore;
PRECTL ClipRect;
RECT_ENUM RectEnum;
ULONG Pixel = Brush->iSolidColor;
LONG delta;
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTUP, 0);
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
ClipRect = RectEnum.arcl;
delta = max(deltax, deltay);
i = 0;
error = delta / 2;
while (i < delta && (ClipRect < RectEnum.arcl + RectEnum.c || EnumMore))
{
while ((ClipRect < RectEnum.arcl + RectEnum.c
&& (y < ClipRect->top
|| (y < ClipRect->bottom && ClipRect->right <= x)))
|| EnumMore)
{
if (RectEnum.arcl + RectEnum.c <= ClipRect)
{
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
ClipRect = RectEnum.arcl;
}
else
{
ClipRect++;
}
}
if (ClipRect < RectEnum.arcl + RectEnum.c)
{
if (ClipRect->left <= x && y < ClipRect->bottom)
vgaPutPixel(x, y, Pixel);
if (deltax < deltay)
{
y--;
error = error + deltax;
if (deltay <= error)
{
x++;
error = error - deltay;
}
}
else
{
x++;
error = error + deltay;
if (deltax <= error)
{
y--;
error = error - deltax;
}
}
i++;
}
}
}
static void FASTCALL
vgaNEtoSW(
IN CLIPOBJ* Clip,
IN BRUSHOBJ* Brush,
IN LONG x,
IN LONG y,
IN LONG deltax,
IN LONG deltay)
{
int i;
int error;
BOOLEAN EnumMore;
PRECTL ClipRect;
RECT_ENUM RectEnum;
ULONG Pixel = Brush->iSolidColor;
LONG delta;
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_LEFTDOWN, 0);
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
ClipRect = RectEnum.arcl;
delta = max(deltax, deltay);
i = 0;
error = delta / 2;
while (i < delta && (ClipRect < RectEnum.arcl + RectEnum.c || EnumMore))
{
while ((ClipRect < RectEnum.arcl + RectEnum.c
&& (ClipRect->bottom <= y
|| (ClipRect->top <= y && x < ClipRect->left)))
|| EnumMore)
{
if (RectEnum.arcl + RectEnum.c <= ClipRect)
{
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
ClipRect = RectEnum.arcl;
}
else
{
ClipRect++;
}
}
if (ClipRect < RectEnum.arcl + RectEnum.c)
{
if (x < ClipRect->right && ClipRect->top <= y)
vgaPutPixel(x, y, Pixel);
if (deltax < deltay)
{
y++;
error = error + deltax;
if (deltay <= error)
{
x--;
error = error - deltay;
}
}
else
{
x--;
error = error + deltay;
if (deltax <= error)
{
y++;
error = error - deltax;
}
}
i++;
}
}
}
static void FASTCALL
vgaSEtoNW(
IN CLIPOBJ* Clip,
IN BRUSHOBJ* Brush,
IN LONG x,
IN LONG y,
IN LONG deltax,
IN LONG deltay)
{
int i;
int error;
BOOLEAN EnumMore;
PRECTL ClipRect;
RECT_ENUM RectEnum;
ULONG Pixel = Brush->iSolidColor;
LONG delta;
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_LEFTUP, 0);
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
ClipRect = RectEnum.arcl;
delta = max(deltax, deltay);
i = 0;
error = delta / 2;
while (i < delta && (ClipRect < RectEnum.arcl + RectEnum.c || EnumMore))
{
while ((ClipRect < RectEnum.arcl + RectEnum.c
&& (y < ClipRect->top
|| (y < ClipRect->bottom && x < ClipRect->left)))
|| EnumMore)
{
if (RectEnum.arcl + RectEnum.c <= ClipRect)
{
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
ClipRect = RectEnum.arcl;
}
else
{
ClipRect++;
}
}
if (ClipRect < RectEnum.arcl + RectEnum.c)
{
if (x < ClipRect->right && y < ClipRect->bottom)
vgaPutPixel(x, y, Pixel);
if (deltax < deltay)
{
y--;
error = error + deltax;
if (deltay <= error)
{
x--;
error = error - deltay;
}
}
else
{
x--;
error = error + deltay;
if (deltax <= error)
{
y--;
error = error - deltax;
}
}
i++;
}
}
}
/*
* FIXME: Use Mix to perform ROPs
* FIXME: Non-solid Brush
*/
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)
{
LONG x, y, deltax, deltay, xchange, ychange, hx, vy;
ULONG i;
ULONG Pixel = Brush->iSolidColor;
RECT_ENUM RectEnum;
BOOL EnumMore;
x = x1;
y = y1;
deltax = x2 - x1;
deltay = y2 - y1;
if (deltax < 0)
{
xchange = -1;
deltax = - deltax;
hx = x2+1;
//x--;
}
else
{
xchange = 1;
hx = x1;
}
if (deltay < 0)
{
ychange = -1;
deltay = - deltay;
vy = y2+1;
//y--;
}
else
{
ychange = 1;
vy = y1;
}
if (y1 == y2)
{
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0);
do
{
EnumMore = CLIPOBJ_bEnum(Clip, sizeof(RectEnum), (PVOID) &RectEnum);
for (i = 0; i < RectEnum.c && RectEnum.arcl[i].top <= y1; i++)
{
if (y1 < RectEnum.arcl[i].bottom &&
RectEnum.arcl[i].left <= hx + deltax &&
hx < RectEnum.arcl[i].right)
{
vgaHLine(max(hx, RectEnum.arcl[i].left), y1,
min(hx + deltax, RectEnum.arcl[i].right)
-max(hx, RectEnum.arcl[i].left), Pixel);
}
}
} while (EnumMore);
}
else if (x1 == x2)
{
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0);
do
{
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
for (i = 0; i < RectEnum.c; i++)
{
if (RectEnum.arcl[i].left <= x1 &&
x1 < RectEnum.arcl[i].right &&
RectEnum.arcl[i].top <= vy + deltay &&
vy < RectEnum.arcl[i].bottom)
{
vgaVLine(x1,
max(vy, RectEnum.arcl[i].top),
min(vy + deltay, RectEnum.arcl[i].bottom)
- max(vy, RectEnum.arcl[i].top),
Pixel);
}
}
} while (EnumMore);
}
else
{
if (0 < xchange)
{
if (0 < ychange)
vgaNWtoSE(Clip, Brush, x, y, deltax, deltay);
else
vgaSWtoNE(Clip, Brush, x, y, deltax, deltay);
}
else
{
if (0 < ychange)
vgaNEtoSW(Clip, Brush, x, y, deltax, deltay);
else
vgaSEtoNW(Clip, Brush, x, y, deltax, deltay);
}
}
return TRUE;
}
/* EOF */