mirror of
https://github.com/reactos/reactos.git
synced 2025-06-10 20:34:59 +00:00
Implement clipping of lines
svn path=/trunk/; revision=5111
This commit is contained in:
parent
98d338a1c4
commit
7e11593f8c
6 changed files with 873 additions and 209 deletions
|
@ -1,9 +1,297 @@
|
||||||
|
/*
|
||||||
|
* 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,v 1.12 2003/07/14 09:43:11 gvg Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
#include "../vgaddi.h"
|
#include "../vgaddi.h"
|
||||||
#include "../vgavideo/vgavideo.h"
|
#include "../vgavideo/vgavideo.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Draw a line from top-left to bottom-right
|
||||||
|
*/
|
||||||
|
static void FASTCALL
|
||||||
|
vgaNWtoSE(PCLIPOBJ Clip, PBRUSHOBJ 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, ENUM_RECT_LIMIT);
|
||||||
|
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
|
||||||
|
ClipRect = RectEnum.arcl;
|
||||||
|
delta = max(deltax, deltay);
|
||||||
|
i = 0;
|
||||||
|
error = 0;
|
||||||
|
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 = 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
|
||||||
|
vgaSWtoNE(PCLIPOBJ Clip, PBRUSHOBJ 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, ENUM_RECT_LIMIT);
|
||||||
|
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
|
||||||
|
ClipRect = RectEnum.arcl;
|
||||||
|
delta = max(deltax, deltay);
|
||||||
|
i = 0;
|
||||||
|
error = 0;
|
||||||
|
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(PCLIPOBJ Clip, PBRUSHOBJ 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, ENUM_RECT_LIMIT);
|
||||||
|
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
|
||||||
|
ClipRect = RectEnum.arcl;
|
||||||
|
delta = max(deltax, deltay);
|
||||||
|
i = 0;
|
||||||
|
error = 0;
|
||||||
|
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(PCLIPOBJ Clip, PBRUSHOBJ 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, ENUM_RECT_LIMIT);
|
||||||
|
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
|
||||||
|
ClipRect = RectEnum.arcl;
|
||||||
|
delta = max(deltax, deltay);
|
||||||
|
i = 0;
|
||||||
|
error = 0;
|
||||||
|
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
|
BOOL STDCALL
|
||||||
DrvLineTo(SURFOBJ *Surface,
|
DrvLineTo(SURFOBJ *DestObj,
|
||||||
CLIPOBJ *Clip,
|
CLIPOBJ *Clip,
|
||||||
BRUSHOBJ *Brush,
|
BRUSHOBJ *Brush,
|
||||||
LONG x1,
|
LONG x1,
|
||||||
|
@ -12,16 +300,12 @@ DrvLineTo(SURFOBJ *Surface,
|
||||||
LONG y2,
|
LONG y2,
|
||||||
RECTL *RectBounds,
|
RECTL *RectBounds,
|
||||||
MIX mix)
|
MIX mix)
|
||||||
|
|
||||||
// FIXME: Use ClipObj and RectBounds to clip the line where required
|
|
||||||
// FIXME: Use Mix to perform ROPs
|
|
||||||
|
|
||||||
{
|
{
|
||||||
LONG deltax, deltay, x, y, d, i, xchange, ychange, error, iSolidColor, hx, vy;
|
LONG x, y, deltax, deltay, i, xchange, ychange, hx, vy;
|
||||||
|
ULONG Pixel = Brush->iSolidColor;
|
||||||
iSolidColor = Brush->iSolidColor; // FIXME: Brush Realization...
|
RECTL DestRect;
|
||||||
|
RECT_ENUM RectEnum;
|
||||||
// FIXME: Implement clipping
|
BOOL EnumMore;
|
||||||
|
|
||||||
x = x1;
|
x = x1;
|
||||||
y = y1;
|
y = y1;
|
||||||
|
@ -30,73 +314,100 @@ DrvLineTo(SURFOBJ *Surface,
|
||||||
|
|
||||||
if (deltax < 0)
|
if (deltax < 0)
|
||||||
{
|
{
|
||||||
xchange = -1;
|
xchange = -1;
|
||||||
deltax = - deltax;
|
deltax = - deltax;
|
||||||
hx = x2;
|
hx = x2;
|
||||||
x--;
|
x--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
xchange = 1;
|
xchange = 1;
|
||||||
hx = x1;
|
hx = x1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deltay < 0)
|
if (deltay < 0)
|
||||||
{
|
{
|
||||||
ychange = -1;
|
ychange = -1;
|
||||||
deltay = - deltay;
|
deltay = - deltay;
|
||||||
vy = y2;
|
vy = y2;
|
||||||
y--;
|
y--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ychange = 1;
|
ychange = 1;
|
||||||
vy = y1;
|
vy = y1;
|
||||||
};
|
}
|
||||||
|
|
||||||
if (y1 == y2)
|
if (y1 == y2)
|
||||||
{
|
{
|
||||||
return vgaHLine(hx, y1, deltax, iSolidColor);
|
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, ENUM_RECT_LIMIT);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) 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);
|
||||||
}
|
}
|
||||||
if (x1 == x2)
|
else if (x1 == x2)
|
||||||
{
|
{
|
||||||
return vgaVLine(x1, vy, deltay, iSolidColor);
|
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, ENUM_RECT_LIMIT);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Using individual pixels to draw a line neither horizontal or vertical
|
return TRUE;
|
||||||
// Set up the VGA masking for individual pixels
|
|
||||||
|
|
||||||
error = 0;
|
|
||||||
|
|
||||||
if (deltax < deltay)
|
|
||||||
{
|
|
||||||
for (i = 0; i < deltay; i++)
|
|
||||||
{
|
|
||||||
vgaPutPixel(x, y, iSolidColor);
|
|
||||||
y = y + ychange;
|
|
||||||
error = error + deltax;
|
|
||||||
|
|
||||||
if (deltay <= error)
|
|
||||||
{
|
|
||||||
x = x + xchange;
|
|
||||||
error = error - deltay;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (i = 0; i < deltax; i++)
|
|
||||||
{
|
|
||||||
vgaPutPixel(x, y, iSolidColor);
|
|
||||||
x = x + xchange;
|
|
||||||
error = error + deltay;
|
|
||||||
if (deltax <= error)
|
|
||||||
{
|
|
||||||
y = y + ychange;
|
|
||||||
error = error - deltax;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
||||||
|
|
|
@ -15,12 +15,15 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
* $Id: lineto.c,v 1.20 2003/07/14 09:43:11 gvg Exp $
|
||||||
*/
|
*/
|
||||||
/* $Id: lineto.c,v 1.19 2003/07/11 15:59:37 royce Exp $ */
|
|
||||||
#include <ddk/winddi.h>
|
#include <ddk/winddi.h>
|
||||||
#include <ddk/ntddmou.h>
|
#include <ddk/ntddmou.h>
|
||||||
#include <include/inteng.h>
|
#include <include/inteng.h>
|
||||||
#include <include/dib.h>
|
#include <include/dib.h>
|
||||||
|
#include "clip.h"
|
||||||
#include "objects.h"
|
#include "objects.h"
|
||||||
#include "../dib/dib.h"
|
#include "../dib/dib.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
@ -29,6 +32,303 @@
|
||||||
#include <include/object.h>
|
#include <include/object.h>
|
||||||
#include <include/surface.h>
|
#include <include/surface.h>
|
||||||
|
|
||||||
|
static void FASTCALL
|
||||||
|
TranslateRects(RECT_ENUM *RectEnum, PPOINTL Translate)
|
||||||
|
{
|
||||||
|
PRECTL CurrentRect;
|
||||||
|
|
||||||
|
if (0 != Translate->x || 0 != Translate->y)
|
||||||
|
{
|
||||||
|
for (CurrentRect = RectEnum->arcl; CurrentRect < RectEnum->arcl + RectEnum->c; CurrentRect++)
|
||||||
|
{
|
||||||
|
CurrentRect->left += Translate->x;
|
||||||
|
CurrentRect->right += Translate->x;
|
||||||
|
CurrentRect->top += Translate->y;
|
||||||
|
CurrentRect->bottom += Translate->y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Draw a line from top-left to bottom-right
|
||||||
|
*/
|
||||||
|
static void FASTCALL
|
||||||
|
NWtoSE(PSURFOBJ OutputObj, PSURFGDI OutputGDI, PCLIPOBJ Clip,
|
||||||
|
PBRUSHOBJ Brush, LONG x, LONG y, LONG deltax, LONG deltay,
|
||||||
|
PPOINTL Translate)
|
||||||
|
{
|
||||||
|
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, ENUM_RECT_LIMIT);
|
||||||
|
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
|
||||||
|
TranslateRects(&RectEnum, Translate);
|
||||||
|
ClipRect = RectEnum.arcl;
|
||||||
|
delta = max(deltax, deltay);
|
||||||
|
i = 0;
|
||||||
|
error = 0;
|
||||||
|
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);
|
||||||
|
TranslateRects(&RectEnum, Translate);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
OutputGDI->DIB_PutPixel(OutputObj, 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
|
||||||
|
SWtoNE(PSURFOBJ OutputObj, PSURFGDI OutputGDI, PCLIPOBJ Clip,
|
||||||
|
PBRUSHOBJ Brush, LONG x, LONG y, LONG deltax, LONG deltay,
|
||||||
|
PPOINTL Translate)
|
||||||
|
{
|
||||||
|
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, ENUM_RECT_LIMIT);
|
||||||
|
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
|
||||||
|
TranslateRects(&RectEnum, Translate);
|
||||||
|
ClipRect = RectEnum.arcl;
|
||||||
|
delta = max(deltax, deltay);
|
||||||
|
i = 0;
|
||||||
|
error = 0;
|
||||||
|
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);
|
||||||
|
TranslateRects(&RectEnum, Translate);
|
||||||
|
ClipRect = RectEnum.arcl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ClipRect++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ClipRect < RectEnum.arcl + RectEnum.c)
|
||||||
|
{
|
||||||
|
if (ClipRect->left <= x && y < ClipRect->bottom)
|
||||||
|
{
|
||||||
|
OutputGDI->DIB_PutPixel(OutputObj, 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
|
||||||
|
NEtoSW(PSURFOBJ OutputObj, PSURFGDI OutputGDI, PCLIPOBJ Clip,
|
||||||
|
PBRUSHOBJ Brush, LONG x, LONG y, LONG deltax, LONG deltay,
|
||||||
|
PPOINTL Translate)
|
||||||
|
{
|
||||||
|
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, ENUM_RECT_LIMIT);
|
||||||
|
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
|
||||||
|
TranslateRects(&RectEnum, Translate);
|
||||||
|
ClipRect = RectEnum.arcl;
|
||||||
|
delta = max(deltax, deltay);
|
||||||
|
i = 0;
|
||||||
|
error = 0;
|
||||||
|
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);
|
||||||
|
TranslateRects(&RectEnum, Translate);
|
||||||
|
ClipRect = RectEnum.arcl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ClipRect++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ClipRect < RectEnum.arcl + RectEnum.c)
|
||||||
|
{
|
||||||
|
if (x < ClipRect->right && ClipRect->top <= y)
|
||||||
|
{
|
||||||
|
OutputGDI->DIB_PutPixel(OutputObj, 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
|
||||||
|
SEtoNW(PSURFOBJ OutputObj, PSURFGDI OutputGDI, PCLIPOBJ Clip,
|
||||||
|
PBRUSHOBJ Brush, LONG x, LONG y, LONG deltax, LONG deltay,
|
||||||
|
PPOINTL Translate)
|
||||||
|
{
|
||||||
|
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, ENUM_RECT_LIMIT);
|
||||||
|
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
|
||||||
|
TranslateRects(&RectEnum, Translate);
|
||||||
|
ClipRect = RectEnum.arcl;
|
||||||
|
delta = max(deltax, deltay);
|
||||||
|
i = 0;
|
||||||
|
error = 0;
|
||||||
|
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);
|
||||||
|
TranslateRects(&RectEnum, Translate);
|
||||||
|
ClipRect = RectEnum.arcl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ClipRect++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ClipRect < RectEnum.arcl + RectEnum.c)
|
||||||
|
{
|
||||||
|
if (x < ClipRect->right && y < ClipRect->bottom)
|
||||||
|
{
|
||||||
|
OutputGDI->DIB_PutPixel(OutputObj, 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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @unimplemented
|
||||||
*/
|
*/
|
||||||
|
@ -43,36 +343,38 @@ EngLineTo(SURFOBJ *DestObj,
|
||||||
RECTL *RectBounds,
|
RECTL *RectBounds,
|
||||||
MIX mix)
|
MIX mix)
|
||||||
{
|
{
|
||||||
LONG x, y, deltax, deltay, i, xchange, ychange, error, hx, vy;
|
LONG x, y, deltax, deltay, i, xchange, ychange, hx, vy;
|
||||||
ULONG Pixel = Brush->iSolidColor;
|
ULONG Pixel = Brush->iSolidColor;
|
||||||
SURFOBJ *OutputObj;
|
SURFOBJ *OutputObj;
|
||||||
SURFGDI *OutputGDI;
|
SURFGDI *OutputGDI;
|
||||||
RECTL DestRect;
|
RECTL DestRect;
|
||||||
POINTL Translate;
|
POINTL Translate;
|
||||||
INTENG_ENTER_LEAVE EnterLeave;
|
INTENG_ENTER_LEAVE EnterLeave;
|
||||||
|
RECT_ENUM RectEnum;
|
||||||
|
BOOL EnumMore;
|
||||||
|
|
||||||
DestRect.left = x1;
|
DestRect.left = x1;
|
||||||
if (x1 != x2)
|
if (x1 != x2)
|
||||||
{
|
{
|
||||||
DestRect.right = x2;
|
DestRect.right = x2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DestRect.right = x2 + 1;
|
DestRect.right = x2 + 1;
|
||||||
}
|
}
|
||||||
DestRect.top = y1;
|
DestRect.top = y1;
|
||||||
if (y1 != y2)
|
if (y1 != y2)
|
||||||
{
|
{
|
||||||
DestRect.bottom = y2;
|
DestRect.bottom = y2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DestRect.bottom = y2 + 1;
|
DestRect.bottom = y2 + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! IntEngEnter(&EnterLeave, DestObj, &DestRect, FALSE, &Translate, &OutputObj))
|
if (! IntEngEnter(&EnterLeave, DestObj, &DestRect, FALSE, &Translate, &OutputObj))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
x1 += Translate.x;
|
x1 += Translate.x;
|
||||||
|
@ -82,7 +384,6 @@ EngLineTo(SURFOBJ *DestObj,
|
||||||
|
|
||||||
OutputGDI = AccessInternalObjectFromUserObject(OutputObj);
|
OutputGDI = AccessInternalObjectFromUserObject(OutputObj);
|
||||||
|
|
||||||
// FIXME: Implement clipping
|
|
||||||
x = x1;
|
x = x1;
|
||||||
y = y1;
|
y = y1;
|
||||||
deltax = x2 - x1;
|
deltax = x2 - x1;
|
||||||
|
@ -90,71 +391,97 @@ EngLineTo(SURFOBJ *DestObj,
|
||||||
|
|
||||||
if (deltax < 0)
|
if (deltax < 0)
|
||||||
{
|
{
|
||||||
xchange = -1;
|
xchange = -1;
|
||||||
deltax = - deltax;
|
deltax = - deltax;
|
||||||
hx = x2;
|
hx = x2;
|
||||||
x--;
|
x--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
xchange = 1;
|
xchange = 1;
|
||||||
hx = x1;
|
hx = x1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deltay < 0)
|
if (deltay < 0)
|
||||||
{
|
{
|
||||||
ychange = -1;
|
ychange = -1;
|
||||||
deltay = - deltay;
|
deltay = - deltay;
|
||||||
vy = y2;
|
vy = y2;
|
||||||
y--;
|
y--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ychange = 1;
|
ychange = 1;
|
||||||
vy = y1;
|
vy = y1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y1 == y2)
|
if (y1 == y2)
|
||||||
{
|
{
|
||||||
OutputGDI->DIB_HLine(OutputObj, hx, hx + deltax, y1, Pixel);
|
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, ENUM_RECT_LIMIT);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
|
||||||
|
for (i = 0; i < RectEnum.c && RectEnum.arcl[i].top + Translate.y <= y1; i++)
|
||||||
|
{
|
||||||
|
if (y1 < RectEnum.arcl[i].bottom + Translate.y &&
|
||||||
|
RectEnum.arcl[i].left + Translate.x <= hx + deltax &&
|
||||||
|
hx < RectEnum.arcl[i].right + Translate.x)
|
||||||
|
{
|
||||||
|
OutputGDI->DIB_HLine(OutputObj,
|
||||||
|
max(hx, RectEnum.arcl[i].left + Translate.x),
|
||||||
|
min(hx + deltax, RectEnum.arcl[i].right + Translate.x),
|
||||||
|
y1, Pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (EnumMore);
|
||||||
}
|
}
|
||||||
else if (x1 == x2)
|
else if (x1 == x2)
|
||||||
{
|
{
|
||||||
OutputGDI->DIB_VLine(OutputObj, x1, vy, vy + deltay, Pixel);
|
CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, ENUM_RECT_LIMIT);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
EnumMore = CLIPOBJ_bEnum(Clip, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
|
||||||
|
for (i = 0; i < RectEnum.c; i++)
|
||||||
|
{
|
||||||
|
if (RectEnum.arcl[i].left + Translate.x <= x1 &&
|
||||||
|
x1 < RectEnum.arcl[i].right + Translate.x &&
|
||||||
|
RectEnum.arcl[i].top + Translate.y <= vy + deltay &&
|
||||||
|
vy < RectEnum.arcl[i].bottom + Translate.y)
|
||||||
|
{
|
||||||
|
OutputGDI->DIB_VLine(OutputObj, x1,
|
||||||
|
max(vy, RectEnum.arcl[i].top + Translate.y),
|
||||||
|
min(vy + deltay, RectEnum.arcl[i].bottom + Translate.y),
|
||||||
|
Pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (EnumMore);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error = 0;
|
if (0 < xchange)
|
||||||
|
{
|
||||||
if (deltax < deltay)
|
if (0 < ychange)
|
||||||
{
|
{
|
||||||
for (i = 0; i < deltay; i++)
|
NWtoSE(OutputObj, OutputGDI, Clip, Brush, x, y, deltax, deltay, &Translate);
|
||||||
{
|
}
|
||||||
OutputGDI->DIB_PutPixel(OutputObj, x, y, Pixel);
|
else
|
||||||
y = y + ychange;
|
{
|
||||||
error = error + deltax;
|
SWtoNE(OutputObj, OutputGDI, Clip, Brush, x, y, deltax, deltay, &Translate);
|
||||||
|
}
|
||||||
if (deltay <= error)
|
}
|
||||||
{
|
else
|
||||||
x = x + xchange;
|
{
|
||||||
error = error - deltay;
|
if (0 < ychange)
|
||||||
}
|
{
|
||||||
}
|
NEtoSW(OutputObj, OutputGDI, Clip, Brush, x, y, deltax, deltay, &Translate);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (i = 0; i < deltax; i++)
|
SEtoNW(OutputObj, OutputGDI, Clip, Brush, x, y, deltax, deltay, &Translate);
|
||||||
{
|
}
|
||||||
OutputGDI->DIB_PutPixel(OutputObj, x, y, Pixel);
|
}
|
||||||
x = x + xchange;
|
|
||||||
error = error + deltay;
|
|
||||||
if (deltax <= error)
|
|
||||||
{
|
|
||||||
y = y + ychange;
|
|
||||||
error = error - deltax;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return IntEngLeave(&EnterLeave);
|
return IntEngLeave(&EnterLeave);
|
||||||
|
@ -180,20 +507,23 @@ IntEngLineTo(SURFOBJ *DestSurf,
|
||||||
|
|
||||||
MouseSafetyOnDrawStart(DestSurf, SurfGDI, x1, y1, x2, y2);
|
MouseSafetyOnDrawStart(DestSurf, SurfGDI, x1, y1, x2, y2);
|
||||||
|
|
||||||
if (NULL != SurfGDI->LineTo) {
|
if (NULL != SurfGDI->LineTo)
|
||||||
|
{
|
||||||
/* Call the driver's DrvLineTo */
|
/* Call the driver's DrvLineTo */
|
||||||
ret = SurfGDI->LineTo(DestSurf, Clip, Brush, x1, y1, x2, y2, RectBounds, mix);
|
ret = SurfGDI->LineTo(DestSurf, Clip, Brush, x1, y1, x2, y2, RectBounds, mix);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (! ret && NULL != SurfGDI->StrokePath) {
|
if (! ret && NULL != SurfGDI->StrokePath)
|
||||||
/* FIXME: Emulate LineTo using drivers DrvStrokePath and set ret on success */
|
{
|
||||||
}
|
/* FIXME: Emulate LineTo using drivers DrvStrokePath and set ret on success */
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (! ret) {
|
if (! ret)
|
||||||
ret = EngLineTo(DestSurf, Clip, Brush, x1, y1, x2, y2, RectBounds, mix);
|
{
|
||||||
}
|
ret = EngLineTo(DestSurf, Clip, Brush, x1, y1, x2, y2, RectBounds, mix);
|
||||||
|
}
|
||||||
|
|
||||||
MouseSafetyOnDrawEnd(DestSurf, SurfGDI);
|
MouseSafetyOnDrawEnd(DestSurf, SurfGDI);
|
||||||
|
|
||||||
|
@ -213,25 +543,28 @@ IntEngPolyline(SURFOBJ *DestSurf,
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
|
|
||||||
//Draw the Polyline with a call to IntEngLineTo for each segment.
|
//Draw the Polyline with a call to IntEngLineTo for each segment.
|
||||||
for (i=1; i<dCount; i++)
|
for (i = 1; i < dCount; i++)
|
||||||
{
|
{
|
||||||
rect.left = MIN(pt[i-1].x, pt[i].x);
|
rect.left = MIN(pt[i-1].x, pt[i].x);
|
||||||
rect.top = MIN(pt[i-1].y, pt[i].y);
|
rect.top = MIN(pt[i-1].y, pt[i].y);
|
||||||
rect.right = MAX(pt[i-1].x, pt[i].x);
|
rect.right = MAX(pt[i-1].x, pt[i].x);
|
||||||
rect.bottom = MAX(pt[i-1].y, pt[i].y);
|
rect.bottom = MAX(pt[i-1].y, pt[i].y);
|
||||||
ret = IntEngLineTo(DestSurf,
|
ret = IntEngLineTo(DestSurf,
|
||||||
Clip,
|
Clip,
|
||||||
Brush,
|
Brush,
|
||||||
pt[i-1].x,
|
pt[i-1].x,
|
||||||
pt[i-1].y,
|
pt[i-1].y,
|
||||||
pt[i].x,
|
pt[i].x,
|
||||||
pt[i].y,
|
pt[i].y,
|
||||||
&rect,
|
&rect,
|
||||||
mix);
|
mix);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
break;
|
{
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#define __WIN32K_PAINT_H
|
#define __WIN32K_PAINT_H
|
||||||
|
|
||||||
BOOL STDCALL FillSolid (PSURFOBJ Surface, PRECTL Dimensions, ULONG iColor);
|
BOOL STDCALL FillSolid (PSURFOBJ Surface, PRECTL Dimensions, ULONG iColor);
|
||||||
BOOL STDCALL FillPolygon_ALTERNATE (PSURFOBJ SurfObj, PBRUSHOBJ BrushObj, MIX RopMode, CONST PPOINT Points, INT Count, RECTL BoundRect);
|
BOOL STDCALL FillPolygon_ALTERNATE (PDC dc, PSURFOBJ SurfObj, PBRUSHOBJ BrushObj, MIX RopMode, CONST PPOINT Points, INT Count, RECTL BoundRect);
|
||||||
BOOL STDCALL FillPolygon_WINDING (PSURFOBJ SurfObj, PBRUSHOBJ BrushObj, MIX RopMode, CONST PPOINT Points, INT Count, RECTL BoundRect);
|
BOOL STDCALL FillPolygon_WINDING (PSURFOBJ SurfObj, PBRUSHOBJ BrushObj, MIX RopMode, CONST PPOINT Points, INT Count, RECTL BoundRect);
|
||||||
|
|
||||||
#endif /* __WIN32K_PAINT_H */
|
#endif /* __WIN32K_PAINT_H */
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: fillshap.c,v 1.20 2003/06/25 16:55:33 gvg Exp $ */
|
/* $Id: fillshap.c,v 1.21 2003/07/14 09:43:11 gvg Exp $ */
|
||||||
|
|
||||||
#undef WIN32_LEAN_AND_MEAN
|
#undef WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -82,7 +82,8 @@ W32kPie(HDC hDC,
|
||||||
//When the fill mode is ALTERNATE, GDI fills the area between odd-numbered and
|
//When the fill mode is ALTERNATE, GDI fills the area between odd-numbered and
|
||||||
//even-numbered polygon sides on each scan line. That is, GDI fills the area between the
|
//even-numbered polygon sides on each scan line. That is, GDI fills the area between the
|
||||||
//first and second side, between the third and fourth side, and so on.
|
//first and second side, between the third and fourth side, and so on.
|
||||||
extern BOOL FillPolygon_ALTERNATE(SURFOBJ *SurfObj,
|
extern BOOL FillPolygon_ALTERNATE(PDC dc,
|
||||||
|
SURFOBJ *SurfObj,
|
||||||
PBRUSHOBJ BrushObj,
|
PBRUSHOBJ BrushObj,
|
||||||
MIX RopMode,
|
MIX RopMode,
|
||||||
CONST PPOINT Points,
|
CONST PPOINT Points,
|
||||||
|
@ -186,7 +187,7 @@ W32kPolygon(HDC hDC,
|
||||||
}
|
}
|
||||||
else /* default */
|
else /* default */
|
||||||
{
|
{
|
||||||
ret = FillPolygon_ALTERNATE(SurfObj, FillBrushObj, dc->w.ROPmode, Points, Count, DestRect);
|
ret = FillPolygon_ALTERNATE(dc, SurfObj, FillBrushObj, dc->w.ROPmode, Points, Count, DestRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw the Polygon Edges with the current pen
|
// Draw the Polygon Edges with the current pen
|
||||||
|
@ -243,7 +244,7 @@ W32kPolygon(HDC hDC,
|
||||||
}
|
}
|
||||||
DPRINT("Polygon Making line from (%d,%d) to (%d,%d)\n", From.x, From.y, To.x, To.y );
|
DPRINT("Polygon Making line from (%d,%d) to (%d,%d)\n", From.x, From.y, To.x, To.y );
|
||||||
ret = IntEngLineTo(SurfObj,
|
ret = IntEngLineTo(SurfObj,
|
||||||
NULL, /* ClipObj */
|
dc->CombinedClip,
|
||||||
OutBrushObj,
|
OutBrushObj,
|
||||||
From.x,
|
From.x,
|
||||||
From.y,
|
From.y,
|
||||||
|
@ -311,28 +312,28 @@ W32kRectangle(HDC hDC,
|
||||||
BottomRect += dc->w.DCOrgY;
|
BottomRect += dc->w.DCOrgY;
|
||||||
|
|
||||||
ret = IntEngLineTo(SurfObj,
|
ret = IntEngLineTo(SurfObj,
|
||||||
NULL, // ClipObj,
|
dc->CombinedClip,
|
||||||
BrushObj,
|
BrushObj,
|
||||||
LeftRect, TopRect, RightRect, TopRect,
|
LeftRect, TopRect, RightRect, TopRect,
|
||||||
RectBounds, // Bounding rectangle
|
RectBounds, // Bounding rectangle
|
||||||
dc->w.ROPmode); // MIX
|
dc->w.ROPmode); // MIX
|
||||||
|
|
||||||
ret = IntEngLineTo(SurfObj,
|
ret = IntEngLineTo(SurfObj,
|
||||||
NULL, // ClipObj,
|
dc->CombinedClip,
|
||||||
BrushObj,
|
BrushObj,
|
||||||
RightRect, TopRect, RightRect, BottomRect,
|
RightRect, TopRect, RightRect, BottomRect,
|
||||||
RectBounds, // Bounding rectangle
|
RectBounds, // Bounding rectangle
|
||||||
dc->w.ROPmode); // MIX
|
dc->w.ROPmode); // MIX
|
||||||
|
|
||||||
ret = IntEngLineTo(SurfObj,
|
ret = IntEngLineTo(SurfObj,
|
||||||
NULL, // ClipObj,
|
dc->CombinedClip,
|
||||||
BrushObj,
|
BrushObj,
|
||||||
LeftRect, BottomRect, RightRect, BottomRect,
|
LeftRect, BottomRect, RightRect, BottomRect,
|
||||||
RectBounds, // Bounding rectangle
|
RectBounds, // Bounding rectangle
|
||||||
dc->w.ROPmode); // MIX
|
dc->w.ROPmode); // MIX
|
||||||
|
|
||||||
ret = IntEngLineTo(SurfObj,
|
ret = IntEngLineTo(SurfObj,
|
||||||
NULL, // ClipObj,
|
dc->CombinedClip,
|
||||||
BrushObj,
|
BrushObj,
|
||||||
LeftRect, TopRect, LeftRect, BottomRect,
|
LeftRect, TopRect, LeftRect, BottomRect,
|
||||||
RectBounds, // Bounding rectangle
|
RectBounds, // Bounding rectangle
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: line.c,v 1.16 2003/05/18 17:16:18 ea Exp $ */
|
/* $Id: line.c,v 1.17 2003/07/14 09:43:11 gvg Exp $ */
|
||||||
|
|
||||||
// Some code from the WINE project source (www.winehq.com)
|
// Some code from the WINE project source (www.winehq.com)
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@
|
||||||
#include <win32k/path.h>
|
#include <win32k/path.h>
|
||||||
#include <win32k/pen.h>
|
#include <win32k/pen.h>
|
||||||
#include <win32k/region.h>
|
#include <win32k/region.h>
|
||||||
|
#include <include/error.h>
|
||||||
#include <include/inteng.h>
|
#include <include/inteng.h>
|
||||||
#include <include/object.h>
|
#include <include/object.h>
|
||||||
#include <include/path.h>
|
#include <include/path.h>
|
||||||
|
@ -128,57 +129,74 @@ W32kGetArcDirection(HDC hDC)
|
||||||
BOOL
|
BOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
W32kLineTo(HDC hDC,
|
W32kLineTo(HDC hDC,
|
||||||
int XEnd,
|
int XEnd,
|
||||||
int YEnd)
|
int YEnd)
|
||||||
{
|
{
|
||||||
DC *dc = DC_HandleToPtr(hDC);
|
DC *dc = DC_HandleToPtr(hDC);
|
||||||
SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject(dc->Surface);
|
SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject(dc->Surface);
|
||||||
BOOL ret;
|
BOOL Ret;
|
||||||
PPENOBJ pen;
|
PPENOBJ Pen;
|
||||||
PROSRGNDATA reg;
|
RECT Bounds;
|
||||||
#ifndef TODO
|
|
||||||
RECT defaultrect;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(!dc) return FALSE;
|
if (NULL == dc)
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if(PATH_IsPathOpen(dc->w.path)) {
|
if (PATH_IsPathOpen(dc->w.path))
|
||||||
ret = PATH_LineTo(hDC, XEnd, YEnd);
|
{
|
||||||
} else {
|
Ret = PATH_LineTo(hDC, XEnd, YEnd);
|
||||||
pen = (PPENOBJ) GDIOBJ_LockObj(dc->w.hPen, GO_PEN_MAGIC);
|
}
|
||||||
reg = (PROSRGNDATA)GDIOBJ_LockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC);
|
else
|
||||||
|
{
|
||||||
|
Pen = (PPENOBJ) GDIOBJ_LockObj(dc->w.hPen, GO_PEN_MAGIC);
|
||||||
|
ASSERT(NULL != Pen);
|
||||||
|
|
||||||
ASSERT( pen );
|
if (dc->w.CursPosX <= XEnd)
|
||||||
// not yet implemented ASSERT( reg );
|
{
|
||||||
#ifndef TODO
|
Bounds.left = dc->w.CursPosX;
|
||||||
if (NULL == reg) {
|
Bounds.right = XEnd;
|
||||||
defaultrect.left = 0;
|
}
|
||||||
defaultrect.top = 0;
|
else
|
||||||
defaultrect.right = 640;
|
{
|
||||||
defaultrect.bottom = 480;
|
Bounds.left = XEnd;
|
||||||
|
Bounds.right = dc->w.CursPosX;
|
||||||
|
}
|
||||||
|
Bounds.left += dc->w.DCOrgX;
|
||||||
|
Bounds.right += dc->w.DCOrgX;
|
||||||
|
if (dc->w.CursPosY <= YEnd)
|
||||||
|
{
|
||||||
|
Bounds.top = dc->w.CursPosY;
|
||||||
|
Bounds.bottom = YEnd;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Bounds.top = YEnd;
|
||||||
|
Bounds.bottom = dc->w.CursPosY;
|
||||||
|
}
|
||||||
|
Bounds.top += dc->w.DCOrgY;
|
||||||
|
Bounds.bottom += dc->w.DCOrgY;
|
||||||
|
|
||||||
reg = &defaultrect;
|
Ret = IntEngLineTo(SurfObj,
|
||||||
}
|
dc->CombinedClip,
|
||||||
#endif
|
PenToBrushObj(dc, Pen),
|
||||||
|
dc->w.DCOrgX + dc->w.CursPosX, dc->w.DCOrgY + dc->w.CursPosY,
|
||||||
|
dc->w.DCOrgX + XEnd, dc->w.DCOrgY + YEnd,
|
||||||
|
&Bounds,
|
||||||
|
dc->w.ROPmode);
|
||||||
|
|
||||||
/* Draw the line according to the DC origin */
|
GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC);
|
||||||
ret = IntEngLineTo(SurfObj,
|
}
|
||||||
NULL, // ClipObj
|
|
||||||
PenToBrushObj(dc, pen),
|
|
||||||
dc->w.DCOrgX + dc->w.CursPosX, dc->w.DCOrgY + dc->w.CursPosY,
|
|
||||||
dc->w.DCOrgX + XEnd, dc->w.DCOrgY + YEnd,
|
|
||||||
reg, // Bounding rectangle
|
|
||||||
dc->w.ROPmode); // MIX
|
|
||||||
|
|
||||||
GDIOBJ_UnlockObj( dc->w.hGCClipRgn, GO_REGION_MAGIC );
|
if (Ret)
|
||||||
GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC);
|
{
|
||||||
}
|
dc->w.CursPosX = XEnd;
|
||||||
if(ret) {
|
dc->w.CursPosY = YEnd;
|
||||||
dc->w.CursPosX = XEnd;
|
}
|
||||||
dc->w.CursPosY = YEnd;
|
DC_ReleasePtr(hDC);
|
||||||
}
|
|
||||||
DC_ReleasePtr( hDC );
|
return Ret;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
|
@ -336,7 +354,7 @@ W32kPolyline(HDC hDC,
|
||||||
|
|
||||||
//get IntEngPolyline to do the drawing.
|
//get IntEngPolyline to do the drawing.
|
||||||
ret = IntEngPolyline(SurfObj,
|
ret = IntEngPolyline(SurfObj,
|
||||||
NULL,
|
dc->CombinedClip,
|
||||||
PenToBrushObj(dc, pen),
|
PenToBrushObj(dc, pen),
|
||||||
pts,
|
pts,
|
||||||
Count,
|
Count,
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: polyfill.c,v 1.4 2003/06/25 16:55:33 gvg Exp $
|
/* $Id: polyfill.c,v 1.5 2003/07/14 09:43:11 gvg Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -33,6 +33,7 @@
|
||||||
#include <win32k/fillshap.h>
|
#include <win32k/fillshap.h>
|
||||||
#include <win32k/dc.h>
|
#include <win32k/dc.h>
|
||||||
#include <win32k/pen.h>
|
#include <win32k/pen.h>
|
||||||
|
#include <include/inteng.h>
|
||||||
#include <include/object.h>
|
#include <include/object.h>
|
||||||
#include <include/paint.h>
|
#include <include/paint.h>
|
||||||
|
|
||||||
|
@ -487,7 +488,7 @@ static void STDCALL POLYGONFILL_UpdateActiveEdges(int Scanline, PFILL_EDGE_LIST
|
||||||
** This method fills the portion of the polygon that intersects with the scanline
|
** This method fills the portion of the polygon that intersects with the scanline
|
||||||
** Scanline.
|
** Scanline.
|
||||||
*/
|
*/
|
||||||
static void STDCALL POLYGONFILL_FillScanLine(int ScanLine, PFILL_EDGE_LIST ActiveEdges, SURFOBJ *SurfObj, PBRUSHOBJ BrushObj, MIX RopMode)
|
static void STDCALL POLYGONFILL_FillScanLine(PDC dc, int ScanLine, PFILL_EDGE_LIST ActiveEdges, SURFOBJ *SurfObj, PBRUSHOBJ BrushObj, MIX RopMode)
|
||||||
{
|
{
|
||||||
BOOL OnOdd = TRUE;
|
BOOL OnOdd = TRUE;
|
||||||
RECTL BoundRect;
|
RECTL BoundRect;
|
||||||
|
@ -510,15 +511,15 @@ static void STDCALL POLYGONFILL_FillScanLine(int ScanLine, PFILL_EDGE_LIST Activ
|
||||||
|
|
||||||
XInterceptEven = pThis->XIntercept;
|
XInterceptEven = pThis->XIntercept;
|
||||||
DPRINT("Fill Line (%d, %d) to (%d, %d)\n",XInterceptOdd - 1, ScanLine, XInterceptEven - 1, ScanLine);
|
DPRINT("Fill Line (%d, %d) to (%d, %d)\n",XInterceptOdd - 1, ScanLine, XInterceptEven - 1, ScanLine);
|
||||||
ret = EngLineTo(SurfObj,
|
ret = IntEngLineTo(SurfObj,
|
||||||
NULL, /* ClipObj */
|
dc->CombinedClip,
|
||||||
BrushObj,
|
BrushObj,
|
||||||
XInterceptOdd - 1,
|
XInterceptOdd - 1,
|
||||||
ScanLine,
|
ScanLine,
|
||||||
XInterceptEven - 1,
|
XInterceptEven - 1,
|
||||||
ScanLine,
|
ScanLine,
|
||||||
&BoundRect, /* Bounding rectangle */
|
&BoundRect, /* Bounding rectangle */
|
||||||
RopMode); /* MIX */
|
RopMode); /* MIX */
|
||||||
OnOdd = TRUE;
|
OnOdd = TRUE;
|
||||||
}
|
}
|
||||||
pThis = pThis->pNext;
|
pThis = pThis->pNext;
|
||||||
|
@ -530,7 +531,7 @@ static void STDCALL POLYGONFILL_FillScanLine(int ScanLine, PFILL_EDGE_LIST Activ
|
||||||
//When the fill mode is ALTERNATE, GDI fills the area between odd-numbered and
|
//When the fill mode is ALTERNATE, GDI fills the area between odd-numbered and
|
||||||
//even-numbered polygon sides on each scan line. That is, GDI fills the area between the
|
//even-numbered polygon sides on each scan line. That is, GDI fills the area between the
|
||||||
//first and second side, between the third and fourth side, and so on.
|
//first and second side, between the third and fourth side, and so on.
|
||||||
BOOL STDCALL FillPolygon_ALTERNATE(SURFOBJ *SurfObj, PBRUSHOBJ BrushObj, MIX RopMode, CONST PPOINT Points, int Count, RECTL BoundRect)
|
BOOL STDCALL FillPolygon_ALTERNATE(PDC dc, SURFOBJ *SurfObj, PBRUSHOBJ BrushObj, MIX RopMode, CONST PPOINT Points, int Count, RECTL BoundRect)
|
||||||
{
|
{
|
||||||
PFILL_EDGE_LIST list = 0;
|
PFILL_EDGE_LIST list = 0;
|
||||||
PFILL_EDGE_LIST ActiveEdges = 0;
|
PFILL_EDGE_LIST ActiveEdges = 0;
|
||||||
|
@ -553,7 +554,7 @@ BOOL STDCALL FillPolygon_ALTERNATE(SURFOBJ *SurfObj, PBRUSHOBJ BrushObj, MIX Rop
|
||||||
{
|
{
|
||||||
POLYGONFILL_UpdateActiveEdges(ScanLine, &list, &ActiveEdges);
|
POLYGONFILL_UpdateActiveEdges(ScanLine, &list, &ActiveEdges);
|
||||||
/* DEBUG_PRINT_EDGELIST(ActiveEdges); */
|
/* DEBUG_PRINT_EDGELIST(ActiveEdges); */
|
||||||
POLYGONFILL_FillScanLine(ScanLine, ActiveEdges, SurfObj, BrushObj, RopMode);
|
POLYGONFILL_FillScanLine(dc, ScanLine, ActiveEdges, SurfObj, BrushObj, RopMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free Edge List. If any are left. */
|
/* Free Edge List. If any are left. */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue