RoundRect() implementation by Royce3

svn path=/trunk/; revision=6026
This commit is contained in:
Gé van Geldorp 2003-09-09 15:49:59 +00:00
parent 93e8262300
commit 213461d136
5 changed files with 298 additions and 36 deletions

View file

@ -1,4 +1,4 @@
/* $Id: stubs.c,v 1.34 2003/09/06 19:44:00 jimtabor Exp $
/* $Id: stubs.c,v 1.35 2003/09/09 15:49:59 gvg Exp $
*
* reactos/lib/gdi32/misc/stubs.c
*
@ -650,26 +650,6 @@ RectVisible(
}
/*
* @unimplemented
*/
BOOL
STDCALL
RoundRect(
HDC a0,
int a1,
int a2,
int a3,
int a4,
int a5,
int a6
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @unimplemented
*/

View file

@ -34,6 +34,24 @@ Rectangle(HDC hDC,
return NtGdiRectangle(hDC, LeftRect, TopRect, RightRect, BottomRect);
}
/*
* @implemented
*/
BOOL
STDCALL
RoundRect(
HDC hdc,
int left,
int top,
int right,
int bottom,
int width,
int height
)
{
return NtGdiRoundRect ( hdc, left, top, right, bottom, width, height );
}
/*
* @implemented
*/

View file

@ -14,6 +14,7 @@ BOOL FASTCALL PATH_PolylineTo (PDC dc, const POINT *pts, DWORD cbPoints);
BOOL FASTCALL PATH_PolyPolygon ( PDC dc, const POINT* pts, const INT* counts, UINT polygons);
BOOL FASTCALL PATH_PolyPolyline( PDC dc, const POINT* pts, const DWORD* counts, DWORD polylines);
BOOL FASTCALL PATH_Rectangle (PDC dc, INT x1, INT y1, INT x2, INT y2);
BOOL FASTCALL PATH_RoundRect (PDC dc, INT x1, INT y1, INT x2, INT y2, INT xradius, INT yradius);
BOOL FASTCALL PATH_PathToRegion (const GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn);
#ifdef _WIN32K_PATH_INTERNAL
BOOL FASTCALL PATH_AddEntry (GdiPath *pPath, const POINT *pPoint, BYTE flags);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: fillshap.c,v 1.30 2003/08/28 19:41:37 gvg Exp $ */
/* $Id: fillshap.c,v 1.31 2003/09/09 15:49:59 gvg Exp $ */
#undef WIN32_LEAN_AND_MEAN
#include <windows.h>
@ -33,7 +33,7 @@
#include <include/paint.h>
#include <internal/safe.h>
//#define NDEBUG
#define NDEBUG
#include <win32k/debug1.h>
BOOL
@ -405,9 +405,259 @@ NtGdiRectangle(HDC hDC,
return ret;
}
/*
* a couple macros used by IntRoundRect()
*/
#define RRPUTPIXEL(x,y,brushObj) \
ret = ret && IntEngLineTo(SurfObj, \
dc->CombinedClip, \
brushObj, \
x, y, (x)+1, y, \
RectBounds, \
dc->w.ROPmode);
#define RRLINE(x1,y1,x2,y2,brushObj) \
ret = ret && IntEngLineTo(SurfObj, \
dc->CombinedClip, \
brushObj, \
x1, y1, x2, y2, \
RectBounds, \
dc->w.ROPmode);
BOOL
FASTCALL
IntRoundRect(
PDC dc,
int left,
int top,
int right,
int bottom,
int xradius,
int yradius)
{
SURFOBJ *SurfObj;
BRUSHOBJ PenBrush, *PenBrushObj, *FillBrushObj;
PRECTL RectBounds;
int i, col, row, width, height, x1, x1start, x2, x2start, y1, y2;
//float aspect_square;
long a_square, b_square,
two_a_square, two_b_square,
four_a_square, four_b_square,
d, dinc, ddec;
BOOL first,
ret = TRUE; // default to success
ASSERT ( dc ); // caller's responsibility to set this up
if ( PATH_IsPathOpen(dc->w.path) )
return PATH_RoundRect ( dc, left, top, right, bottom, xradius, yradius );
left += dc->w.DCOrgX;
right += dc->w.DCOrgX;
top += dc->w.DCOrgY;
bottom += dc->w.DCOrgY;
RectBounds = (PRECTL) RGNDATA_LockRgn(dc->w.hGCClipRgn);
SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface);
FillBrushObj = BRUSHOBJ_LockBrush(dc->w.hBrush);
ASSERT(FillBrushObj);
if ( FillBrushObj->logbrush.lbStyle == BS_NULL )
FillBrushObj = NULL; // make null brush check simpler...
HPenToBrushObj ( &PenBrush, dc->w.hPen );
if ( PenBrush.logbrush.lbStyle != BS_NULL )
PenBrushObj = &PenBrush;
else
PenBrushObj = NULL;
right--;
bottom--;
width = right - left;
height = bottom - top;
if ( (xradius<<1) > width )
xradius = width >> 1;
if ( (yradius<<1) > height )
yradius = height >> 1;
b_square = yradius * yradius;
a_square = xradius * xradius;
row = yradius;
col = 0;
two_a_square = a_square << 1;
four_a_square = a_square << 2;
four_b_square = b_square << 2;
two_b_square = b_square << 1;
d = two_a_square * ((row - 1) * (row))
+ a_square
+ two_b_square * (1 - a_square);
x1 = left+xradius;
x2 = right-xradius;
y1 = top;
y2 = bottom;
x1start = x1;
x2start = x2;
dinc = two_b_square*3; /* two_b_square * (3 + (col << 1)); */
ddec = four_a_square * row;
first = TRUE;
for ( ;; )
{
if ( d >= 0 )
{
if ( FillBrushObj )
RRLINE ( x1, y1, x2, y1, FillBrushObj );
if ( first )
{
if ( PenBrushObj )
{
if ( x1start > x1 )
{
RRLINE ( x1, y1, x1start, y1, PenBrushObj );
RRLINE ( x2start+1, y2, x2+1, y2, PenBrushObj );
}
else
{
RRPUTPIXEL ( x1, y1, PenBrushObj );
RRPUTPIXEL ( x2, y2, PenBrushObj );
}
}
first = FALSE;
}
else
{
if ( FillBrushObj )
RRLINE ( x1, y2, x2, y2, FillBrushObj );
if ( PenBrushObj )
{
if ( x1start >= x1 )
{
RRLINE ( x1, y1, x1start+1, y1, PenBrushObj );
RRLINE ( x2start, y2, x2+1, y2, PenBrushObj );
}
else
{
RRPUTPIXEL ( x1, y1, PenBrushObj );
RRPUTPIXEL ( x2, y2, PenBrushObj );
}
}
}
if ( PenBrushObj )
{
if ( x1start > x1 )
{
RRLINE ( x1, y2, x1start+1, y2, PenBrushObj );
RRLINE ( x2start, y1, x2+1, y1, PenBrushObj );
}
else
{
RRPUTPIXEL ( x1, y2, PenBrushObj );
RRPUTPIXEL ( x2, y1, PenBrushObj );
}
}
x1start = x1-1;
x2start = x2+1;
row--, y1++, y2--, ddec -= four_a_square;
d -= ddec;
}
int potential_steps = ( a_square * row ) / b_square - col + 1;
while ( d < 0 && potential_steps-- )
{
d += dinc; /* two_b_square * (3 + (col << 1)); */
col++, x1--, x2++, dinc += four_b_square;
}
if ( a_square * row <= b_square * col )
break;
};
d = two_b_square * (col + 1) * col
+ two_a_square * (row * (row - 2) + 1)
+ (1 - two_a_square) * b_square;
dinc = ddec; /* four_b_square * col; */
ddec = two_a_square * ((row << 1) - 3);
while ( row )
{
if ( FillBrushObj )
{
RRLINE ( x1, y1, x2, y1, FillBrushObj );
RRLINE ( x1, y2, x2, y2, FillBrushObj );
}
if ( PenBrushObj )
{
RRPUTPIXEL ( x2, y1, PenBrushObj );
RRPUTPIXEL ( x1, y2, PenBrushObj );
RRPUTPIXEL ( x2, y2, PenBrushObj );
RRPUTPIXEL ( x1, y1, PenBrushObj );
}
if ( d <= 0 )
{
col++, x1--, x2++, dinc += four_b_square;
d += dinc; //four_b_square * col;
}
row--, y1++, y2--, ddec -= four_a_square;
d -= ddec; //two_a_square * ((row << 1) - 3);
}
if ( FillBrushObj )
{
RRLINE ( left, y1, right, y1, FillBrushObj );
RRLINE ( left, y2, right, y2, FillBrushObj );
}
if ( PenBrushObj )
{
if ( x1 > (left+1) )
{
RRLINE ( left, y1, x1, y1, PenBrushObj );
RRLINE ( x2+1, y1, right, y1, PenBrushObj );
RRLINE ( left+1, y2, x1, y2, PenBrushObj );
RRLINE ( x2+1, y2, right+1, y2, PenBrushObj );
}
else
{
RRPUTPIXEL ( left, y1, PenBrushObj );
RRPUTPIXEL ( right, y2, PenBrushObj );
}
}
x1 = left+xradius;
x2 = right-xradius;
y1 = top+yradius;
y2 = bottom-yradius;
if ( FillBrushObj )
{
for ( i = y1+1; i < y2; i++ )
RRLINE ( left, i, right, i, FillBrushObj );
}
if ( PenBrushObj )
{
RRLINE ( x1, top, x2, top, PenBrushObj );
RRLINE ( right, y1, right, y2, PenBrushObj );
RRLINE ( x2, bottom, x1, bottom, PenBrushObj );
RRLINE ( left, y2, left, y1, PenBrushObj );
}
BRUSHOBJ_UnlockBrush(dc->w.hBrush);
return ret;
}
BOOL
STDCALL
NtGdiRoundRect(HDC hDC,
NtGdiRoundRect(
HDC hDC,
int LeftRect,
int TopRect,
int RightRect,
@ -415,14 +665,19 @@ NtGdiRoundRect(HDC hDC,
int Width,
int Height)
{
// FIXME - drawing a rectangle until someone can implement
// RoundRect properly...
DC *dc = DC_LockDc(hDC);
BOOL ret = FALSE; // default to failure
BOOL ret = FALSE; /* default to failure */
if ( dc )
__asm__("int $3\n");
DPRINT("NtGdiRoundRect(0x%x,%i,%i,%i,%i,%i,%i)\n",hDC,LeftRect,TopRect,RightRect,BottomRect,Width,Height);
if ( !dc )
{
ret = IntRectangle ( dc, LeftRect, TopRect, RightRect, BottomRect );
DPRINT1("NtGdiRoundRect() - hDC is invalid\n");
SetLastWin32Error(ERROR_INVALID_PARAMETER);
}
else
{
ret = IntRoundRect ( dc, LeftRect, TopRect, RightRect, BottomRect, Width, Height );
DC_UnlockDc ( hDC );
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: path.c,v 1.15 2003/08/20 07:45:02 gvg Exp $ */
/* $Id: path.c,v 1.16 2003/09/09 15:49:59 gvg Exp $ */
#undef WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <ddk/ntddk.h>
@ -373,6 +373,14 @@ PATH_Rectangle ( PDC dc, INT x1, INT y1, INT x2, INT y2 )
return TRUE;
}
BOOL
FASTCALL
PATH_RoundRect (PDC dc, INT x1, INT y1, INT x2, INT y2, INT xradius, INT yradius)
{
UNIMPLEMENTED;
return FALSE;
}
/* PATH_Ellipse
*
* Should be called when a call to Ellipse is performed on a DC that has