mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
RoundRect() implementation by Royce3
svn path=/trunk/; revision=6026
This commit is contained in:
parent
93e8262300
commit
213461d136
5 changed files with 298 additions and 36 deletions
|
@ -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
|
* 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
|
* @unimplemented
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -34,6 +34,24 @@ Rectangle(HDC hDC,
|
||||||
return NtGdiRectangle(hDC, LeftRect, TopRect, RightRect, BottomRect);
|
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
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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_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_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_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);
|
BOOL FASTCALL PATH_PathToRegion (const GdiPath *pPath, INT nPolyFillMode, HRGN *pHrgn);
|
||||||
#ifdef _WIN32K_PATH_INTERNAL
|
#ifdef _WIN32K_PATH_INTERNAL
|
||||||
BOOL FASTCALL PATH_AddEntry (GdiPath *pPath, const POINT *pPoint, BYTE flags);
|
BOOL FASTCALL PATH_AddEntry (GdiPath *pPath, const POINT *pPoint, BYTE flags);
|
||||||
|
|
|
@ -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.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
|
#undef WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
#include <include/paint.h>
|
#include <include/paint.h>
|
||||||
#include <internal/safe.h>
|
#include <internal/safe.h>
|
||||||
|
|
||||||
//#define NDEBUG
|
#define NDEBUG
|
||||||
#include <win32k/debug1.h>
|
#include <win32k/debug1.h>
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
|
@ -405,9 +405,259 @@ NtGdiRectangle(HDC hDC,
|
||||||
return ret;
|
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
|
BOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
NtGdiRoundRect(HDC hDC,
|
NtGdiRoundRect(
|
||||||
|
HDC hDC,
|
||||||
int LeftRect,
|
int LeftRect,
|
||||||
int TopRect,
|
int TopRect,
|
||||||
int RightRect,
|
int RightRect,
|
||||||
|
@ -415,14 +665,19 @@ NtGdiRoundRect(HDC hDC,
|
||||||
int Width,
|
int Width,
|
||||||
int Height)
|
int Height)
|
||||||
{
|
{
|
||||||
// FIXME - drawing a rectangle until someone can implement
|
|
||||||
// RoundRect properly...
|
|
||||||
DC *dc = DC_LockDc(hDC);
|
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 );
|
DC_UnlockDc ( hDC );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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: 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
|
#undef WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
|
@ -373,6 +373,14 @@ PATH_Rectangle ( PDC dc, INT x1, INT y1, INT x2, INT y2 )
|
||||||
return TRUE;
|
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
|
/* PATH_Ellipse
|
||||||
*
|
*
|
||||||
* Should be called when a call to Ellipse is performed on a DC that has
|
* Should be called when a call to Ellipse is performed on a DC that has
|
||||||
|
|
Loading…
Reference in a new issue