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,24 +405,279 @@ 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,
int LeftRect,
int TopRect,
int RightRect,
int BottomRect,
int Width,
int Height)
NtGdiRoundRect(
HDC hDC,
int LeftRect,
int TopRect,
int RightRect,
int BottomRect,
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