Author: jimtabor
Date: Wed Jul 2 02:47:23 2008
New Revision: 34248
URL:
http://svn.reactos.org/svn/reactos?rev=34248&view=rev
Log:
Arc, RoundRect:
- Converted over to use the new draw/fill square algorithm for draw arcs and draw/fill
round rects.
- Tested with (Area.exe) Yuan program. Getting better.
Modified:
trunk/reactos/subsystems/win32/win32k/objects/arc.c
trunk/reactos/subsystems/win32/win32k/objects/drawing.c
trunk/reactos/subsystems/win32/win32k/objects/fillshap.c
Modified: trunk/reactos/subsystems/win32/win32k/objects/arc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/arc.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/arc.c [iso-8859-1] Wed Jul 2 02:47:23
2008
@@ -26,6 +26,7 @@
#define Rcos(d) ((d) == 0.0 ? 1.0 : ((d) == 90.0 ? 0.0 : cos(d*M_PI/180.0)))
BOOL FASTCALL IntFillArc( PDC dc, INT XLeft, INT YLeft, INT Width, INT Height, double
StartArc, double EndArc, ARCTYPE arctype);
+BOOL FASTCALL IntDrawArc( PDC dc, INT XLeft, INT YLeft, INT Width, INT Height, double
StartArc, double EndArc, ARCTYPE arctype, PGDIBRUSHOBJ PenBrushObj);
static
BOOL
@@ -147,6 +148,16 @@
arctype);
}
+ ret = IntDrawArc( dc,
+ RectBounds.left,
+ RectBounds.top,
+ abs(RectBounds.right-RectBounds.left), // Width
+ abs(RectBounds.bottom-RectBounds.top), // Height
+ AngleStart,
+ AngleEnd,
+ arctype,
+ PenBrushObj);
+
BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
if (NULL == BitmapObj)
{
@@ -161,63 +172,11 @@
if (arctype == GdiTypePie)
{
PUTLINE(CenterX, CenterY, SfCx + CenterX, SfCy + CenterY, PenBrushInst);
- }
- {
- double AngS = AngleStart, AngT = AngleEnd,
- Factor = fabs(RadiusX) < 25 ? 1.0 : (25/fabs(RadiusX));
- int x,y, ox = 0, oy = 0;
- BOOL Start = TRUE;
-
- if (dc->DcLevel.flPath & DCPATH_CLOCKWISE)
- {
- DPRINT1("Arc CW\n");
- for (; AngS < AngT; AngS += Factor)
- {
- x = (RadiusX * Rcos(AngS));
- y = (RadiusY * Rsin(AngS));
-
- DPRINT("Arc CW -> %d, X: %d Y: %d\n",(INT)AngS,x,y);
- if (Start)
- {
- PUTPIXEL(x + CenterX, y + CenterY, PenBrushInst);
- ox = x;
- oy = y;
- Start = FALSE;
- continue;
- }
- PUTLINE(ox + CenterX, oy + CenterY, x + CenterX, y + CenterY,
PenBrushInst);
- ox = x;
- oy = y;
- }
- }
- else
- {
- DPRINT1("Arc CCW\n");
- for (; AngT < AngS; AngS -= Factor)
- {
- x = (RadiusX * Rcos(AngS));
- y = (RadiusY * Rsin(AngS));
-
- DPRINT("Arc CCW -> %d, X: %d Y: %d\n",(INT)AngS,x,y);
- if (Start)
- {
- PUTPIXEL(x + CenterX, y + CenterY, PenBrushInst);
- ox = x;
- oy = y;
- Start = FALSE;
- continue;
- }
- PUTLINE(ox + CenterX, oy + CenterY, x + CenterX, y + CenterY,
PenBrushInst);
- ox = x;
- oy = y;
- }
- }
- }
- if (arctype == GdiTypePie)
PUTLINE(EfCx + CenterX, EfCy + CenterY, CenterX, CenterY, PenBrushInst);
+ }
if (arctype == GdiTypeChord)
- PUTLINE(EfCx + CenterX, EfCy + CenterY, SfCx + CenterX, SfCy + CenterY,
PenBrushInst);
-
+ PUTLINE(EfCx + CenterX, EfCy + CenterY, SfCx + CenterX, SfCy + CenterY,
PenBrushInst);
+
PenBrushObj->ptPenWidth.x = PenOrigWidth;
BITMAPOBJ_UnlockBitmap(BitmapObj);
PENOBJ_UnlockPen(PenBrushObj);
Modified: trunk/reactos/subsystems/win32/win32k/objects/drawing.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/drawing.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/drawing.c [iso-8859-1] Wed Jul 2
02:47:23 2008
@@ -63,6 +63,9 @@
int width, height; /* width and height of rect */
} Rect, *PRect;
+int FASTCALL IntFillRect(DC *dc, INT XLeft, INT YLeft, INT Width, INT Height,
PGDIBRUSHOBJ BrushObj, BOOL Pen);
+int FASTCALL app_fill_rect(DC *dc, Rect r, PGDIBRUSHOBJ BrushObj, BOOL Pen);
+
static
POINT
INTERNAL_CALL
@@ -101,152 +104,8 @@
* is no way for the program to know which portions of the
* window are currently obscured.
*/
-static
-int
-INTERNAL_CALL
-app_fill_rect(DC *dc, Rect r, PGDIBRUSHOBJ BrushObj)
-{
- DWORD ROP = PATCOPY;
- RECTL DestRect;
- BITMAPOBJ *BitmapObj;
- GDIBRUSHINST BrushInst;
- POINTL BrushOrigin;
- BOOL Ret = TRUE;
- PDC_ATTR Dc_Attr = NULL;
-
- ASSERT(BrushObj);
-
- BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
- if (BitmapObj == NULL)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return 0;
- }
-
- if (!(BrushObj->flAttrs & GDIBRUSH_IS_NULL))
- {
- Dc_Attr = dc->pDc_Attr;
- if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
-
- /* fix negative spaces */
- if (r.width < 0)
- {
- r.x += r.width;
- r.width = 0 - r.width;
- }
- if (r.height < 0)
- {
- r.y += r.height;
- r.height = 0 - r.height;
- }
-
- DestRect.left = r.x;
- DestRect.right = r.x + r.width;
-
- DestRect.top = r.y;
- DestRect.bottom = r.y + r.height;
-
- BrushOrigin.x = BrushObj->ptOrigin.x;
- BrushOrigin.y = BrushObj->ptOrigin.y;
-
- if (Dc_Attr->jROP2 == R2_XORPEN)
- ROP = PATINVERT;
- else
- ROP = PATCOPY;
-
- IntGdiInitBrushInstance(&BrushInst, BrushObj, dc->XlateBrush);
-
- Ret = IntEngBitBlt(
- &BitmapObj->SurfObj,
- NULL,
- NULL,
- dc->CombinedClip,
- NULL,
- &DestRect,
- NULL,
- NULL,
- &BrushInst.BrushObject, // use pDC->eboFill
- &BrushOrigin,
- ROP3_TO_ROP4(ROP));
- }
-
- BITMAPOBJ_UnlockBitmap(BitmapObj);
- return (int)Ret;
-}
-
-static
-int
-INTERNAL_CALL
-app_fill_rect_pen(DC *dc, Rect r, PGDIBRUSHOBJ BrushObj)
-{
- DWORD ROP = PATCOPY;
- RECTL DestRect;
- BITMAPOBJ *BitmapObj;
- GDIBRUSHINST BrushInst;
- POINTL BrushOrigin;
- BOOL Ret = TRUE;
- PDC_ATTR Dc_Attr = NULL;
-
- ASSERT(BrushObj);
-
- BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
- if (BitmapObj == NULL)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return 0;
- }
-
- if (!(BrushObj->flAttrs & GDIBRUSH_IS_NULL))
- {
- Dc_Attr = dc->pDc_Attr;
- if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
-
- /* fix negative spaces */
- if (r.width < 0)
- {
- r.x += r.width;
- r.width = 0 - r.width;
- }
- if (r.height < 0)
- {
- r.y += r.height;
- r.height = 0 - r.height;
- }
-
- DestRect.left = r.x;
- DestRect.right = r.x + r.width;
-
- DestRect.top = r.y;
- DestRect.bottom = r.y + r.height;
-
- BrushOrigin.x = BrushObj->ptOrigin.x;
- BrushOrigin.y = BrushObj->ptOrigin.y;
-
- if (Dc_Attr->jROP2 == R2_XORPEN)
- ROP = PATINVERT;
- else
- ROP = PATCOPY;
-
- IntGdiInitBrushInstance(&BrushInst, BrushObj, dc->XlatePen);
-
- Ret = IntEngBitBlt(
- &BitmapObj->SurfObj,
- NULL,
- NULL,
- dc->CombinedClip,
- NULL,
- &DestRect,
- NULL,
- NULL,
- &BrushInst.BrushObject, // use pDC->eboFill
- &BrushOrigin,
- ROP3_TO_ROP4(ROP));
- }
-
- BITMAPOBJ_UnlockBitmap(BitmapObj);
- return (int)Ret;
-}
-
+#define app_fill_rect( dc, r, BrushObj, Pen) \
+ IntFillRect(dc, r.x, r.y, r.width, r.height, BrushObj, Pen)
/*
* Drawing an ellipse with a certain line thickness.
@@ -306,7 +165,7 @@
// START_DEBUG();
if ((r.width <= 2) || (r.height <= 2))
- return app_fill_rect_pen(g, r, BrushObj);
+ return app_fill_rect(g, r, BrushObj, TRUE);
r1.x = r.x + a;
r1.y = r.y;
@@ -405,8 +264,8 @@
if ((r1.y < r.y+w) || (r1.x+W >= r1.x+r1.width-W))
{
- result &= app_fill_rect_pen(g, r1, BrushObj);
- result &= app_fill_rect_pen(g, r2, BrushObj);
+ result &= app_fill_rect(g, r1, BrushObj, TRUE);
+ result &= app_fill_rect(g, r2, BrushObj, TRUE);
prevx = r1.x;
prevy = r1.y;
@@ -414,14 +273,14 @@
else if (r1.y+r1.height < r2.y)
{
/* draw distinct rectangles */
- result &= app_fill_rect_pen(g, rect(r1.x,r1.y,
- W,1), BrushObj);
- result &= app_fill_rect_pen(g, rect(
- r1.x+r1.width-W,r1.y,W,1), BrushObj);
- result &= app_fill_rect_pen(g, rect(r2.x,
- r2.y,W,1), BrushObj);
- result &= app_fill_rect_pen(g, rect(
- r2.x+r2.width-W,r2.y,W,1), BrushObj);
+ result &= app_fill_rect(g, rect(r1.x,r1.y,
+ W,1), BrushObj, TRUE);
+ result &= app_fill_rect(g, rect(
+ r1.x+r1.width-W,r1.y,W,1), BrushObj, TRUE);
+ result &= app_fill_rect(g, rect(r2.x,
+ r2.y,W,1), BrushObj, TRUE);
+ result &= app_fill_rect(g, rect(
+ r2.x+r2.width-W,r2.y,W,1), BrushObj, TRUE);
prevx = r1.x;
prevy = r1.y;
@@ -450,14 +309,14 @@
W = w;
if (W+W >= r.width) {
- result &= app_fill_rect_pen(g, rect(r.x, r1.y,
- r.width, r1.height), BrushObj);
+ result &= app_fill_rect(g, rect(r.x, r1.y,
+ r.width, r1.height), BrushObj, TRUE);
return result;
}
- result &= app_fill_rect_pen(g, rect(r.x, r1.y, W, r1.height), BrushObj);
- result &= app_fill_rect_pen(g, rect(r.x+r.width-W, r1.y,
- W, r1.height), BrushObj);
+ result &= app_fill_rect(g, rect(r.x, r1.y, W, r1.height), BrushObj, TRUE);
+ result &= app_fill_rect(g, rect(r.x+r.width-W, r1.y,
+ W, r1.height), BrushObj, TRUE);
}
return result;
}
@@ -505,7 +364,8 @@
POINT p2, // End
int start_angle,
int end_angle,
- PGDIBRUSHOBJ BrushObj)
+ PGDIBRUSHOBJ BrushObj,
+ BOOL Pen)
{
int x1, x2;
int start_above, end_above;
@@ -580,36 +440,36 @@
{
/* fill outsides of wedge */
if (! app_fill_rect(g, rect(r.x, r.y,
- x1-r.x, r.height), BrushObj))
+ x1-r.x, r.height), BrushObj, Pen))
return 0;
return app_fill_rect(g, rect(x2, r.y,
- r.x+r.width-x2, r.height), BrushObj);
+ r.x+r.width-x2, r.height), BrushObj, Pen);
}
else
{
/* fill inside of wedge */
r.width = x1-x2;
r.x = x2;
- return app_fill_rect(g, r, BrushObj);
+ return app_fill_rect(g, r, BrushObj, Pen);
}
}
else if (start_above)
{
/* fill to the left of the start_line */
r.width = x1-r.x;
- return app_fill_rect(g, r, BrushObj);
+ return app_fill_rect(g, r, BrushObj, Pen);
}
else if (end_above)
{
/* fill right of end_line */
r.width = r.x+r.width-x2;
r.x = x2;
- return app_fill_rect(g, r, BrushObj);
+ return app_fill_rect(g, r, BrushObj, Pen);
}
else
{
if (start_angle > end_angle)
- return app_fill_rect(g,r, BrushObj);
+ return app_fill_rect(g,r, BrushObj, Pen);
else
return 1;
}
@@ -675,7 +535,7 @@
if (start_above && end_above)
{
if (start_angle > end_angle)
- return app_fill_rect(g,r, BrushObj);
+ return app_fill_rect(g,r, BrushObj, Pen);
else
return 1;
}
@@ -683,14 +543,14 @@
{
/* fill to the left of end_line */
r.width = x2-r.x;
- return app_fill_rect(g,r, BrushObj);
+ return app_fill_rect(g,r, BrushObj, Pen);
}
else if (end_above)
{
/* fill right of start_line */
r.width = r.x+r.width-x1;
r.x = x1;
- return app_fill_rect(g,r, BrushObj);
+ return app_fill_rect(g,r, BrushObj, Pen);
}
else
{
@@ -698,17 +558,17 @@
{
/* fill outsides of wedge */
if (! app_fill_rect(g, rect(r.x, r.y,
- x2-r.x, r.height), BrushObj))
+ x2-r.x, r.height), BrushObj, Pen))
return 0;
return app_fill_rect(g, rect(x1, r.y,
- r.x+r.width-x1, r.height), BrushObj);
+ r.x+r.width-x1, r.height), BrushObj, Pen);
}
else
{
/* fill inside of wedge */
r.width = x2-x1;
r.x = x1;
- return app_fill_rect(g, r, BrushObj);
+ return app_fill_rect(g, r, BrushObj, Pen);
}
}
}
@@ -767,7 +627,7 @@
// START_DEBUG();
if ((r.width <= 2) || (r.height <= 2))
- return app_fill_rect(g, r, BrushObj);
+ return app_fill_rect(g, r, BrushObj, FALSE);
r1.x = r.x + a;
r1.y = r.y;
@@ -813,8 +673,8 @@
if (r1.y+r1.height < r2.y) {
/* distinct rectangles */
- result &= app_fill_rect(g, r1, BrushObj);
- result &= app_fill_rect(g, r2, BrushObj);
+ result &= app_fill_rect(g, r1, BrushObj, FALSE);
+ result &= app_fill_rect(g, r2, BrushObj, FALSE);
}
/* move down */
@@ -839,7 +699,7 @@
r1.x = r.x;
r1.width = r.width;
r1.height = r2.y+r2.height-r1.y;
- result &= app_fill_rect(g, r1, BrushObj);
+ result &= app_fill_rect(g, r1, BrushObj, FALSE);
}
else if (x <= a) {
/* crossover, draw final line */
@@ -847,7 +707,7 @@
r1.width = r.width;
r1.height = r1.y+r1.height-r2.y;
r1.y = r2.y;
- result &= app_fill_rect(g, r1, BrushObj);
+ result &= app_fill_rect(g, r1, BrushObj, FALSE);
}
return result;
}
@@ -1014,10 +874,10 @@
/* distinct rectangles */
result &= app_fill_arc_rect(g, r1,
p0, p1, p2,
- start_angle, end_angle, BrushObj);
+ start_angle, end_angle, BrushObj, FALSE);
result &= app_fill_arc_rect(g, r2,
p0, p1, p2,
- start_angle, end_angle, BrushObj);
+ start_angle, end_angle, BrushObj, FALSE);
}
/* move down */
@@ -1039,7 +899,7 @@
while (r1.height > 0) {
result &= app_fill_arc_rect(g,
rect(r1.x, r1.y, r1.width, 1),
- p0, p1, p2, start_angle, end_angle, BrushObj);
+ p0, p1, p2, start_angle, end_angle, BrushObj, FALSE);
r1.y += 1;
r1.height -= 1;
}
@@ -1053,7 +913,7 @@
while (r1.height > 0) {
result &= app_fill_arc_rect(g,
rect(r1.x, r1.y, r1.width, 1),
- p0, p1, p2, start_angle, end_angle, BrushObj);
+ p0, p1, p2, start_angle, end_angle, BrushObj, FALSE);
r1.y += 1;
r1.height -= 1;
}
@@ -1061,7 +921,344 @@
return result;
}
+int app_draw_arc(DC *g, Rect r, int start_angle, int end_angle, PGDIBRUSHOBJ PenBrushObj,
BOOL Chord)
+{
+ /* Outer ellipse: e(x,y) = b*b*x*x + a*a*y*y - a*a*b*b */
+
+ int a = r.width / 2;
+ int b = r.height / 2;
+ int x = 0;
+ int y = b;
+ long a2 = a*a;
+ long b2 = b*b;
+ long xcrit = (3 * a2 / 4) + 1;
+ long ycrit = (3 * b2 / 4) + 1;
+ long t = b2 + a2 - 2*a2*b; /* t = e(x+1,y-1) */
+ long dxt = b2*(3+x+x);
+ long dyt = a2*(3-y-y);
+ int d2xt = b2+b2;
+ int d2yt = a2+a2;
+
+ int w = PenBrushObj->ptPenWidth.x;
+
+ /* Inner ellipse: E(X,Y) = B*B*X*X + A*A*Y*Y - A*A*B*B */
+
+ int A = a-w > 0 ? a-w : 0;
+ int B = b-w > 0 ? b-w : 0;
+ int X = 0;
+ int Y = B;
+ long A2 = A*A;
+ long B2 = B*B;
+ long XCRIT = (3 * A2 / 4) + 1;
+ long YCRIT = (3 * B2 / 4) + 1;
+ long T = B2 + A2 - 2*A2*B; /* T = E(X+1,Y-1) */
+ long DXT = B2*(3+X+X);
+ long DYT = A2*(3-Y-Y);
+ int D2XT = B2+B2;
+ int D2YT = A2+A2;
+
+ /* arc rectangle calculations */
+ int movedown, moveout;
+ int innerX = 0, prevx, prevy, W;
+ Rect r1, r2;
+ int result = 1;
+
+ /* line descriptions */
+ POINT p0, p1, p2;
+
+// START_DEBUG();
+
+ /* if angles differ by 360 degrees or more, close the shape */
+ if ((start_angle + 360 <= end_angle) ||
+ (start_angle - 360 >= end_angle))
+ {
+ return app_draw_ellipse(g, r, PenBrushObj);
+ }
+
+ /* make start_angle >= 0 and <= 360 */
+ while (start_angle < 0)
+ start_angle += 360;
+ start_angle %= 360;
+
+ /* make end_angle >= 0 and <= 360 */
+ while (end_angle < 0)
+ end_angle += 360;
+ end_angle %= 360;
+
+ /* draw nothing if the angles are equal */
+ if (start_angle == end_angle)
+ return 1;
+
+ /* find arc wedge line end points */
+ p1 = app_boundary_point(r, start_angle);
+ p2 = app_boundary_point(r, end_angle);
+ if (Chord)
+ p0 = pt((p1.x+p2.x)/2,(p1.y+p2.y)/2);
+ else
+ p0 = pt(r.x + r.width/2, r.y + r.height/2);
+
+ /* determine ellipse rectangles */
+ r1.x = r.x + a;
+ r1.y = r.y;
+ r1.width = r.width & 1; /* i.e. if width is odd */
+ r1.height = 1;
+
+ r2 = r1;
+ r2.y = r.y + r.height - 1;
+
+ prevx = r1.x;
+ prevy = r1.y;
+
+ while (y > 0)
+ {
+ while (Y == y)
+ {
+ innerX = X;
+
+ if (T + A2*Y < XCRIT) /* E(X+1,Y-1/2) <= 0 */
+ {
+ /* move outwards to encounter edge */
+ X += 1;
+ T += DXT;
+ DXT += D2XT;
+ }
+ else if (T - B2*X >= YCRIT) /* e(x+1/2,y-1) > 0 */
+ {
+ /* drop down one line */
+ Y -= 1;
+ T += DYT;
+ DYT += D2YT;
+ }
+ else {
+ /* drop diagonally down and out */
+ X += 1;
+ Y -= 1;
+ T += DXT + DYT;
+ DXT += D2XT;
+ DYT += D2YT;
+ }
+ }
+
+ movedown = moveout = 0;
+
+ W = x - innerX;
+ if (r1.x + W < prevx)
+ W = prevx - r1.x;
+ if (W < w)
+ W = w;
+
+ if (t + a2*y < xcrit) /* e(x+1,y-1/2) <= 0 */
+ {
+ /* move outwards to encounter edge */
+ x += 1;
+ t += dxt;
+ dxt += d2xt;
+
+ moveout = 1;
+ }
+ else if (t - b2*x >= ycrit) /* e(x+1/2,y-1) > 0 */
+ {
+ /* drop down one line */
+ y -= 1;
+ t += dyt;
+ dyt += d2yt;
+
+ movedown = 1;
+ }
+ else {
+ /* drop diagonally down and out */
+ x += 1;
+ y -= 1;
+ t += dxt + dyt;
+ dxt += d2xt;
+ dyt += d2yt;
+
+ movedown = 1;
+ moveout = 1;
+ }
+
+ if (movedown) {
+ if (r1.width == 0) {
+ r1.x -= 1; r1.width += 2;
+ r2.x -= 1; r2.width += 2;
+ moveout = 0;
+ }
+
+ if (r1.x < r.x)
+ r1.x = r2.x = r.x;
+ if (r1.width > r.width)
+ r1.width = r2.width = r.width;
+ if (r1.y == r2.y-1) {
+ r1.x = r2.x = r.x;
+ r1.width = r2.width = r.width;
+ }
+
+ if ((r1.y < r.y+w) || (r1.x+W >= r1.x+r1.width-W))
+ {
+ result &= app_fill_arc_rect(g, r1,
+ p0, p1, p2,
+ start_angle, end_angle, PenBrushObj, TRUE);
+ result &= app_fill_arc_rect(g, r2,
+ p0, p1, p2,
+ start_angle, end_angle, PenBrushObj, TRUE);
+
+ prevx = r1.x;
+ prevy = r1.y;
+ }
+ else if (r1.y+r1.height < r2.y)
+ {
+ /* draw distinct rectangles */
+ result &= app_fill_arc_rect(g, rect(
+ r1.x,r1.y,W,1),
+ p0, p1, p2,
+ start_angle, end_angle, PenBrushObj, TRUE);
+ result &= app_fill_arc_rect(g, rect(
+ r1.x+r1.width-W,r1.y,W,1),
+ p0, p1, p2,
+ start_angle, end_angle, PenBrushObj, TRUE);
+ result &= app_fill_arc_rect(g, rect(
+ r2.x,r2.y,W,1),
+ p0, p1, p2,
+ start_angle, end_angle, PenBrushObj, TRUE);
+ result &= app_fill_arc_rect(g, rect(
+ r2.x+r2.width-W,r2.y,W,1),
+ p0, p1, p2,
+ start_angle, end_angle, PenBrushObj, TRUE);
+
+ prevx = r1.x;
+ prevy = r1.y;
+ }
+
+ /* move down */
+ r1.y += 1;
+ r2.y -= 1;
+ }
+
+ if (moveout) {
+ /* move outwards */
+ r1.x -= 1; r1.width += 2;
+ r2.x -= 1; r2.width += 2;
+ }
+ }
+ if ((x <= a) && (prevy < r2.y)) {
+ /* draw final lines */
+ r1.height = r1.y+r1.height-r2.y;
+ r1.y = r2.y;
+
+ W = w;
+ if (r.x + W != prevx)
+ W = prevx - r.x;
+ if (W < w)
+ W = w;
+
+ if (W+W >= r.width) {
+ while (r1.height > 0) {
+ result &= app_fill_arc_rect(g, rect(r.x,
+ r1.y, r.width, 1), p0, p1, p2,
+ start_angle, end_angle, PenBrushObj, TRUE);
+ r1.y += 1;
+ r1.height -= 1;
+ }
+ return result;
+ }
+
+ while (r1.height > 0) {
+ result &= app_fill_arc_rect(g, rect(r.x, r1.y,
+ W, 1), p0, p1, p2,
+ start_angle, end_angle, PenBrushObj, TRUE);
+ result &= app_fill_arc_rect(g, rect(r.x+r.width-W,
+ r1.y, W, 1), p0, p1, p2,
+ start_angle, end_angle, PenBrushObj, TRUE);
+ r1.y += 1;
+ r1.height -= 1;
+ }
+ }
+
+ return result;
+}
+
/* ReactOS Interface *********************************************************/
+
+int
+FASTCALL
+IntFillRect( DC *dc,
+ INT XLeft,
+ INT YLeft,
+ INT Width,
+ INT Height,
+ PGDIBRUSHOBJ BrushObj,
+ BOOL Pen)
+{
+ DWORD ROP = PATCOPY;
+ RECTL DestRect;
+ BITMAPOBJ *BitmapObj;
+ GDIBRUSHINST BrushInst;
+ POINTL BrushOrigin;
+ BOOL Ret = TRUE;
+ PDC_ATTR Dc_Attr = NULL;
+
+ ASSERT(BrushObj);
+
+ BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
+ if (BitmapObj == NULL)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return 0;
+ }
+
+ if (!(BrushObj->flAttrs & GDIBRUSH_IS_NULL))
+ {
+ Dc_Attr = dc->pDc_Attr;
+ if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
+
+ /* fix negative spaces */
+ if (Width < 0)
+ {
+ XLeft += Width;
+ Width = 0 - Width;
+ }
+ if (Height < 0)
+ {
+ YLeft += Height;
+ Height = 0 - Height;
+ }
+
+ DestRect.left = XLeft;
+ DestRect.right = XLeft + Width;
+
+ DestRect.top = YLeft;
+ DestRect.bottom = YLeft + Height;
+
+ BrushOrigin.x = BrushObj->ptOrigin.x;
+ BrushOrigin.y = BrushObj->ptOrigin.y;
+
+ if (Dc_Attr->jROP2 == R2_XORPEN)
+ ROP = PATINVERT;
+ else
+ ROP = PATCOPY;
+
+ if (Pen)
+ IntGdiInitBrushInstance(&BrushInst, BrushObj, dc->XlatePen);
+ else
+ IntGdiInitBrushInstance(&BrushInst, BrushObj, dc->XlateBrush);
+
+ Ret = IntEngBitBlt(
+ &BitmapObj->SurfObj,
+ NULL,
+ NULL,
+ dc->CombinedClip,
+ NULL,
+ &DestRect,
+ NULL,
+ NULL,
+ &BrushInst.BrushObject, // use pDC->eboFill
+ &BrushOrigin,
+ ROP3_TO_ROP4(ROP));
+ }
+
+ BITMAPOBJ_UnlockBitmap(BitmapObj);
+ return (int)Ret;
+}
BOOL
FASTCALL
@@ -1102,6 +1299,28 @@
BOOL
FASTCALL
+IntDrawArc( PDC dc,
+ INT XLeft,
+ INT YLeft,
+ INT Width,
+ INT Height,
+ double StartArc,
+ double EndArc,
+ ARCTYPE arctype,
+ PGDIBRUSHOBJ PenBrushObj)
+{
+ int Start = ceill(StartArc);
+ int End = ceill(EndArc);
+ BOOL Chord = (arctype == GdiTypeChord);
+ // Sort out alignment here.
+ return app_draw_arc(dc, rect( XLeft, YLeft, Width, Height),
+ (dc->DcLevel.flPath & DCPATH_CLOCKWISE) ? -End : -Start,
+ (dc->DcLevel.flPath & DCPATH_CLOCKWISE) ? -Start : -End,
+ PenBrushObj, Chord);
+}
+
+BOOL
+FASTCALL
IntDrawEllipse( PDC dc,
INT XLeft,
INT YLeft,
@@ -1139,3 +1358,154 @@
BRUSHOBJ_UnlockBrush(FillBrushObj);
return ret;
}
+
+BOOL
+FASTCALL
+IntFillRoundRect( PDC dc,
+ INT Left,
+ INT Top,
+ INT Right,
+ INT Bottom,
+ INT Wellipse,
+ INT Hellipse)
+{
+ PDC_ATTR Dc_Attr;
+ PGDIBRUSHOBJ FillBrushObj;
+ Rect r;
+ int rx, ry; /* radius in x and y directions */
+
+ Dc_Attr = dc->pDc_Attr;
+ if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
+
+ FillBrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush);
+ if (NULL == FillBrushObj)
+ {
+ DPRINT1("FillEllipse Fail\n");
+ SetLastWin32Error(ERROR_INTERNAL_ERROR);
+ return FALSE;
+ }
+ // x y Width Height
+ r = rect( Left, Top, abs(Right-Left), abs(Bottom-Top));
+ rx = Wellipse/2;
+ ry = Hellipse/2;
+
+ if (Wellipse > r.width)
+ {
+ if (Hellipse > r.height) // > W > H
+ ret = app_fill_ellipse(dc, r, FillBrushObj);
+ else // > W < H
+ {
+
+ app_fill_arc(dc, rect( r.x, r.y, r.width - 1, Hellipse),
+ 0, 180, FillBrushObj,FALSE);
+ app_fill_arc(dc, rect(r.x, Bottom - Hellipse - 1, r.width - 1, Hellipse),
+ 180, 360, FillBrushObj, FALSE);
+ }
+ }
+ else if(Hellipse > r.height) // < W > H
+ {
+ app_fill_arc(dc, rect(r.x, r.y, Wellipse, r.height - 1),
+ 90, 270, FillBrushObj, FALSE);
+ app_fill_arc(dc, rect(Right - Wellipse - 1, r.y, Wellipse, r.height - 1),
+ 270, 90, FillBrushObj,FALSE);
+ }
+ else // < W < H
+ {
+ app_fill_arc(dc, rect(r.x, r.y, Wellipse, Hellipse),
+ 90, 180, FillBrushObj, FALSE);
+
+ app_fill_arc(dc, rect(r.x, Bottom - Hellipse - 1, Wellipse, Hellipse),
+ 180, 270, FillBrushObj, FALSE);
+
+ app_fill_arc(dc, rect(Right - Wellipse - 1, Bottom - Hellipse - 1, Wellipse,
Hellipse),
+ 270, 360, FillBrushObj,FALSE);
+
+ app_fill_arc(dc, rect(Right - Wellipse - 1, r.y, Wellipse, Hellipse ),
+ 0, 90, FillBrushObj,FALSE);
+ }
+ if (Wellipse < r.width)
+ {
+ app_fill_rect(dc, rect(r.x+rx, r.y, r.width-rx-rx, ry+1), FillBrushObj, FALSE);
+ app_fill_rect(dc, rect(r.x+rx, r.y+r.height-ry+1, r.width-rx-rx, ry-1),
FillBrushObj, FALSE);
+ }
+ if (Hellipse < r.height)
+ {
+ app_fill_rect(dc, rect(r.x, r.y+ry+1, r.width, r.height-ry-ry), FillBrushObj,
FALSE);
+ }
+
+ BRUSHOBJ_UnlockBrush(FillBrushObj);
+ return TRUE;
+}
+
+
+BOOL
+FASTCALL
+IntDrawRoundRect( PDC dc,
+ INT Left,
+ INT Top,
+ INT Right,
+ INT Bottom,
+ INT Wellipse,
+ INT Hellipse,
+ PGDIBRUSHOBJ PenBrushObj)
+{
+ Rect r;
+ int rx, ry; /* radius in x and y directions */
+ int w = PenBrushObj->ptPenWidth.x;
+
+ r = rect( Left, Top, abs(Right-Left), abs(Bottom-Top));
+ rx = Wellipse/2;
+ ry = Hellipse/2;
+
+ if (Wellipse > r.width)
+ {
+ if (Hellipse > r.height) // > W > H
+ app_draw_ellipse(dc, r, PenBrushObj);
+ else // > W < H
+ {
+
+ app_draw_arc(dc, rect( r.x, r.y, r.width - 1, Hellipse - 1),
+ 0, 180, PenBrushObj, FALSE);
+ app_draw_arc(dc, rect(r.x, Bottom - Hellipse, r.width - 1, Hellipse - 1),
+ 180, 360, PenBrushObj, FALSE);
+ }
+ }
+ else if(Hellipse > r.height) // < W > H
+ {
+ app_draw_arc(dc, rect(r.x, r.y, Wellipse - 1, r.height - 1),
+ 90, 270, PenBrushObj, FALSE);
+ app_draw_arc(dc, rect(Right - Wellipse, r.y, Wellipse - 1, r.height - 1),
+ 270, 90, PenBrushObj, FALSE);
+ }
+ else // < W < H
+ {
+ app_draw_arc(dc, rect(r.x, r.y, Wellipse-1, Hellipse - 1),
+ 90, 180, PenBrushObj, FALSE);
+
+ app_draw_arc(dc, rect(r.x, Bottom - Hellipse, Wellipse - 1, Hellipse - 1),
+ 180, 270, PenBrushObj, FALSE);
+
+ app_draw_arc(dc, rect(Right - Wellipse, Bottom - Hellipse, Wellipse - 1, Hellipse -
1),
+ 270, 360, PenBrushObj, FALSE);
+
+ app_draw_arc(dc, rect(Right - Wellipse, r.y, Wellipse - 1, Hellipse - 1 ),
+ 0, 90, PenBrushObj, FALSE);
+ }
+ if ( Hellipse < r.height)
+ {
+ app_fill_rect(dc, rect(r.x, r.y+ry+1, w, r.height-ry-ry), PenBrushObj, TRUE);
+
+
+ app_fill_rect(dc, rect(r.x+r.width-w, r.y+ry+1, w, r.height-ry-ry),
+ PenBrushObj, TRUE);
+ }
+ if ( Wellipse < r.width)
+ {
+ app_fill_rect(dc, rect(r.x+rx, r.y+r.height-w, r.width-rx-rx, w),
+ PenBrushObj, TRUE);
+
+ app_fill_rect(dc, rect(r.x+rx, r.y, r.width-rx-rx, w), PenBrushObj, TRUE);
+ }
+ return TRUE;
+}
+
Modified: trunk/reactos/subsystems/win32/win32k/objects/fillshap.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/fillshap.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/fillshap.c [iso-8859-1] Wed Jul 2
02:47:23 2008
@@ -46,6 +46,8 @@
BOOL FASTCALL IntFillEllipse( PDC dc, INT XLeft, INT YLeft, INT Width, INT Height);
BOOL FASTCALL IntDrawEllipse( PDC dc, INT XLeft, INT YLeft, INT Width, INT Height,
PGDIBRUSHOBJ PenBrushObj);
+BOOL FASTCALL IntFillRoundRect( PDC dc, INT Left, INT Top, INT Right, INT Bottom, INT
Wellipse, INT Hellipse);
+BOOL FASTCALL IntDrawRoundRect( PDC dc, INT Left, INT Top, INT Right, INT Bottom, INT
Wellipse, INT Hellipse, PGDIBRUSHOBJ PenBrushObj);
BOOL FASTCALL
IntGdiPolygon(PDC dc,
@@ -550,7 +552,7 @@
DestRect.left = LeftRect;
DestRect.right = RightRect;
- DestRect.top = TopRect;
+ DestRect.top = TopRect;
DestRect.bottom = BottomRect;
FillBrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush);
@@ -669,271 +671,97 @@
FASTCALL
IntRoundRect(
PDC dc,
- int left,
- int top,
- int right,
- int bottom,
+ int Left,
+ int Top,
+ int Right,
+ int Bottom,
int xCurveDiameter,
int yCurveDiameter)
{
PDC_ATTR Dc_Attr;
- BITMAPOBJ *BitmapObj;
- PGDIBRUSHOBJ PenBrushObj, FillBrushObj;
- GDIBRUSHINST FillBrushInst, PenBrushInst;
- RECTL RectBounds;
- int potential_steps;
- int i, col, row, width, height, x1, x1start, x2, x2start, y1, y2;
- int xradius, yradius;
- //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
+ PGDIBRUSHOBJ PenBrushObj;
+ RECTL RectBounds;
+ LONG PenWidth, PenOrigWidth;
+ BOOL ret = TRUE; // default to success
ASSERT ( dc ); // caller's responsibility to set this up
if ( PATH_IsPathOpen(dc->DcLevel) )
- return PATH_RoundRect ( dc, left, top, right, bottom,
+ return PATH_RoundRect ( dc, Left, Top, Right, Bottom,
xCurveDiameter, yCurveDiameter );
+
+ if ((Left == Right) || (Top == Bottom)) return TRUE;
+
+ xCurveDiameter = max(abs( xCurveDiameter ), 1);
+ yCurveDiameter = max(abs( yCurveDiameter ), 1);
+
+ if (Right < Left)
+ {
+ INT tmp = Right; Right = Left; Left = tmp;
+ }
+ if (Bottom < Top)
+ {
+ INT tmp = Bottom; Bottom = Top; Top = tmp;
+ }
+
Dc_Attr = dc->pDc_Attr;
if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
- xradius = xCurveDiameter >> 1;
- yradius = yCurveDiameter >> 1;
-
- left += dc->ptlDCOrig.x;
- right += dc->ptlDCOrig.x;
- top += dc->ptlDCOrig.y;
- bottom += dc->ptlDCOrig.y;
-
- RectBounds.left = left;
- RectBounds.right = right;
- RectBounds.top = top;
- RectBounds.bottom = bottom;
-
- BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
- if (!BitmapObj)
+ PenBrushObj = PENOBJ_LockPen(Dc_Attr->hpen);
+ if (!PenBrushObj)
{
/* Nothing to do, as we don't have a bitmap */
SetLastWin32Error(ERROR_INTERNAL_ERROR);
return FALSE;
}
- FillBrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush);
- if (FillBrushObj)
- {
- if (FillBrushObj->flAttrs & GDIBRUSH_IS_NULL)
- {
- /* make null brush check simpler... */
- BRUSHOBJ_UnlockBrush(FillBrushObj);
- FillBrushObj = NULL;
- }
- else
- {
- IntGdiInitBrushInstance(&FillBrushInst, FillBrushObj,
dc->XlateBrush);
- }
- }
-
- PenBrushObj = PENOBJ_LockPen(Dc_Attr->hpen);
- if (PenBrushObj)
- {
- if (PenBrushObj->flAttrs & GDIBRUSH_IS_NULL)
- {
- /* make null pen check simpler... */
- PENOBJ_UnlockPen(PenBrushObj);
- PenBrushObj = NULL;
- }
- else
- {
- IntGdiInitBrushInstance(&PenBrushInst, PenBrushObj, dc->XlatePen);
- }
- }
-
- 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 )
- PUTLINE ( x1, y1, x2, y1, FillBrushInst );
- if ( first )
- {
- if ( PenBrushObj )
- {
- if ( x1start > x1 )
- {
- PUTLINE ( x1, y1, x1start, y1, PenBrushInst );
- PUTLINE ( x2start+1, y2, x2+1, y2, PenBrushInst );
- }
- else
- {
- PUTPIXEL ( x1, y1, PenBrushInst );
- PUTPIXEL ( x2, y2, PenBrushInst );
- }
- }
- first = FALSE;
- }
- else
- {
- if ( FillBrushObj )
- PUTLINE ( x1, y2, x2, y2, FillBrushInst );
- if ( PenBrushObj )
- {
- if ( x1start >= x1 )
- {
- PUTLINE ( x1, y1, x1start+1, y1, PenBrushInst );
- PUTLINE ( x2start, y2, x2+1, y2, PenBrushInst );
- }
- else
- {
- PUTPIXEL ( x1, y1, PenBrushInst );
- PUTPIXEL ( x2, y2, PenBrushInst );
- }
- }
- }
- if ( PenBrushObj )
- {
- if ( x1start > x1 )
- {
- PUTLINE ( x1, y2, x1start+1, y2, PenBrushInst );
- PUTLINE ( x2start, y1, x2+1, y1, PenBrushInst );
- }
- else
- {
- PUTPIXEL ( x1, y2, PenBrushInst );
- PUTPIXEL ( x2, y1, PenBrushInst );
- }
- }
- x1start = x1-1;
- x2start = x2+1;
- row--, y1++, y2--, ddec -= four_a_square;
- d -= ddec;
- }
-
- 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 )
- {
- PUTLINE ( x1, y1, x2, y1, FillBrushInst );
- PUTLINE ( x1, y2, x2, y2, FillBrushInst );
- }
- if ( PenBrushObj )
- {
- PUTPIXEL ( x2, y1, PenBrushInst );
- PUTPIXEL ( x1, y2, PenBrushInst );
- PUTPIXEL ( x2, y2, PenBrushInst );
- PUTPIXEL ( x1, y1, PenBrushInst );
- }
-
- 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 )
- {
- PUTLINE ( left, y1, right, y1, FillBrushInst );
- PUTLINE ( left, y2, right, y2, FillBrushInst );
- }
- if ( PenBrushObj )
- {
- if ( x1 > (left+1) )
- {
- PUTLINE ( left, y1, x1, y1, PenBrushInst );
- PUTLINE ( x2+1, y1, right, y1, PenBrushInst );
- PUTLINE ( left+1, y2, x1, y2, PenBrushInst );
- PUTLINE ( x2+1, y2, right+1, y2, PenBrushInst );
- }
- else
- {
- PUTPIXEL ( left, y1, PenBrushInst );
- PUTPIXEL ( right, y2, PenBrushInst );
- }
- }
-
- x1 = left+xradius;
- x2 = right-xradius;
- y1 = top+yradius;
- y2 = bottom-yradius;
-
- if ( FillBrushObj )
- {
- for ( i = y1+1; i < y2; i++ )
- PUTLINE ( left, i, right, i, FillBrushInst );
- }
-
- if ( PenBrushObj )
- {
- PUTLINE ( x1, top, x2, top, PenBrushInst );
- PUTLINE ( right, y1, right, y2, PenBrushInst );
- PUTLINE ( x2, bottom, x1, bottom, PenBrushInst );
- PUTLINE ( left, y2, left, y1, PenBrushInst );
- }
-
- BITMAPOBJ_UnlockBitmap(BitmapObj);
- if (PenBrushObj != NULL)
- PENOBJ_UnlockPen(PenBrushObj);
- if (FillBrushObj != NULL)
- BRUSHOBJ_UnlockBrush(FillBrushObj);
-
+ PenOrigWidth = PenWidth = PenBrushObj->ptPenWidth.x;
+ if (PenBrushObj->ulPenStyle == PS_NULL) PenWidth = 0;
+
+ if (PenBrushObj->ulPenStyle == PS_INSIDEFRAME)
+ {
+ if (2*PenWidth > (Right - Left)) PenWidth = (Right -Left + 1)/2;
+ if (2*PenWidth > (Bottom - Top)) PenWidth = (Bottom -Top + 1)/2;
+ Left += PenWidth / 2;
+ Right -= (PenWidth - 1) / 2;
+ Top += PenWidth / 2;
+ Bottom -= (PenWidth - 1) / 2;
+ }
+
+ if (!PenWidth) PenWidth = 1;
+ PenBrushObj->ptPenWidth.x = PenWidth;
+
+ RectBounds.left = Left;
+ RectBounds.top = Top;
+ RectBounds.right = Right;
+ RectBounds.bottom = Bottom;
+
+ IntLPtoDP(dc, (LPPOINT)&RectBounds, 2);
+
+ RectBounds.left += dc->ptlDCOrig.x;
+ RectBounds.top += dc->ptlDCOrig.y;
+ RectBounds.right += dc->ptlDCOrig.x;
+ RectBounds.bottom += dc->ptlDCOrig.y;
+
+ ret = IntFillRoundRect( dc,
+ RectBounds.left,
+ RectBounds.top,
+ RectBounds.right,
+ RectBounds.bottom,
+ xCurveDiameter,
+ yCurveDiameter);
+ if (ret)
+ ret = IntDrawRoundRect( dc,
+ RectBounds.left,
+ RectBounds.top,
+ RectBounds.right,
+ RectBounds.bottom,
+ xCurveDiameter,
+ yCurveDiameter,
+ PenBrushObj);
+
+ PenBrushObj->ptPenWidth.x = PenOrigWidth;
+ PENOBJ_UnlockPen(PenBrushObj);
return ret;
}