lineto.c
来自「一个类似windows」· C语言 代码 · 共 415 行
C
415 行
/*
* ReactOS VGA driver
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: lineto.c 21260 2006-03-08 23:23:57Z audit $
*/
#include "../vgaddi.h"
#include "../vgavideo/vgavideo.h"
/*
* Draw a line from top-left to bottom-right
*/
static void FASTCALL
vgaNWtoSE(CLIPOBJ* Clip, BRUSHOBJ* Brush, LONG x, LONG y, LONG deltax, 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(CLIPOBJ* Clip, BRUSHOBJ* Brush, LONG x, LONG y, LONG deltax, 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(CLIPOBJ* Clip, BRUSHOBJ* Brush, LONG x, LONG y, LONG deltax, 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(CLIPOBJ* Clip, BRUSHOBJ* Brush, LONG x, LONG y, LONG deltax, 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 STDCALL
DrvLineTo(SURFOBJ *DestObj,
CLIPOBJ *Clip,
BRUSHOBJ *Brush,
LONG x1,
LONG y1,
LONG x2,
LONG y2,
RECTL *RectBounds,
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 */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?