mirror of
https://github.com/reactos/reactos.git
synced 2025-06-05 01:10:26 +00:00
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. svn path=/trunk/; revision=34248
This commit is contained in:
parent
2964504432
commit
d170af286f
3 changed files with 636 additions and 479 deletions
|
@ -26,6 +26,7 @@
|
||||||
#define Rcos(d) ((d) == 0.0 ? 1.0 : ((d) == 90.0 ? 0.0 : cos(d*M_PI/180.0)))
|
#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 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
|
static
|
||||||
BOOL
|
BOOL
|
||||||
|
@ -147,6 +148,16 @@ IntArc( DC *dc,
|
||||||
arctype);
|
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);
|
BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
|
||||||
if (NULL == BitmapObj)
|
if (NULL == BitmapObj)
|
||||||
{
|
{
|
||||||
|
@ -161,62 +172,10 @@ IntArc( DC *dc,
|
||||||
if (arctype == GdiTypePie)
|
if (arctype == GdiTypePie)
|
||||||
{
|
{
|
||||||
PUTLINE(CenterX, CenterY, SfCx + CenterX, SfCy + CenterY, PenBrushInst);
|
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);
|
PUTLINE(EfCx + CenterX, EfCy + CenterY, CenterX, CenterY, PenBrushInst);
|
||||||
|
}
|
||||||
if (arctype == GdiTypeChord)
|
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;
|
PenBrushObj->ptPenWidth.x = PenOrigWidth;
|
||||||
BITMAPOBJ_UnlockBitmap(BitmapObj);
|
BITMAPOBJ_UnlockBitmap(BitmapObj);
|
||||||
|
|
|
@ -63,6 +63,9 @@ typedef struct _Rect
|
||||||
int width, height; /* width and height of rect */
|
int width, height; /* width and height of rect */
|
||||||
} Rect, *PRect;
|
} 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
|
static
|
||||||
POINT
|
POINT
|
||||||
INTERNAL_CALL
|
INTERNAL_CALL
|
||||||
|
@ -101,152 +104,8 @@ rect(int x, int y, int width, int height)
|
||||||
* is no way for the program to know which portions of the
|
* is no way for the program to know which portions of the
|
||||||
* window are currently obscured.
|
* window are currently obscured.
|
||||||
*/
|
*/
|
||||||
static
|
#define app_fill_rect( dc, r, BrushObj, Pen) \
|
||||||
int
|
IntFillRect(dc, r.x, r.y, r.width, r.height, BrushObj, Pen)
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Drawing an ellipse with a certain line thickness.
|
* Drawing an ellipse with a certain line thickness.
|
||||||
|
@ -306,7 +165,7 @@ app_draw_ellipse(DC *g, Rect r, PGDIBRUSHOBJ BrushObj)
|
||||||
// START_DEBUG();
|
// START_DEBUG();
|
||||||
|
|
||||||
if ((r.width <= 2) || (r.height <= 2))
|
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.x = r.x + a;
|
||||||
r1.y = r.y;
|
r1.y = r.y;
|
||||||
|
@ -405,8 +264,8 @@ app_draw_ellipse(DC *g, Rect r, PGDIBRUSHOBJ BrushObj)
|
||||||
|
|
||||||
if ((r1.y < r.y+w) || (r1.x+W >= r1.x+r1.width-W))
|
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(g, r1, BrushObj, TRUE);
|
||||||
result &= app_fill_rect_pen(g, r2, BrushObj);
|
result &= app_fill_rect(g, r2, BrushObj, TRUE);
|
||||||
|
|
||||||
prevx = r1.x;
|
prevx = r1.x;
|
||||||
prevy = r1.y;
|
prevy = r1.y;
|
||||||
|
@ -414,14 +273,14 @@ app_draw_ellipse(DC *g, Rect r, PGDIBRUSHOBJ BrushObj)
|
||||||
else if (r1.y+r1.height < r2.y)
|
else if (r1.y+r1.height < r2.y)
|
||||||
{
|
{
|
||||||
/* draw distinct rectangles */
|
/* draw distinct rectangles */
|
||||||
result &= app_fill_rect_pen(g, rect(r1.x,r1.y,
|
result &= app_fill_rect(g, rect(r1.x,r1.y,
|
||||||
W,1), BrushObj);
|
W,1), BrushObj, TRUE);
|
||||||
result &= app_fill_rect_pen(g, rect(
|
result &= app_fill_rect(g, rect(
|
||||||
r1.x+r1.width-W,r1.y,W,1), BrushObj);
|
r1.x+r1.width-W,r1.y,W,1), BrushObj, TRUE);
|
||||||
result &= app_fill_rect_pen(g, rect(r2.x,
|
result &= app_fill_rect(g, rect(r2.x,
|
||||||
r2.y,W,1), BrushObj);
|
r2.y,W,1), BrushObj, TRUE);
|
||||||
result &= app_fill_rect_pen(g, rect(
|
result &= app_fill_rect(g, rect(
|
||||||
r2.x+r2.width-W,r2.y,W,1), BrushObj);
|
r2.x+r2.width-W,r2.y,W,1), BrushObj, TRUE);
|
||||||
|
|
||||||
prevx = r1.x;
|
prevx = r1.x;
|
||||||
prevy = r1.y;
|
prevy = r1.y;
|
||||||
|
@ -450,14 +309,14 @@ app_draw_ellipse(DC *g, Rect r, PGDIBRUSHOBJ BrushObj)
|
||||||
W = w;
|
W = w;
|
||||||
|
|
||||||
if (W+W >= r.width) {
|
if (W+W >= r.width) {
|
||||||
result &= app_fill_rect_pen(g, rect(r.x, r1.y,
|
result &= app_fill_rect(g, rect(r.x, r1.y,
|
||||||
r.width, r1.height), BrushObj);
|
r.width, r1.height), BrushObj, TRUE);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result &= app_fill_rect_pen(g, rect(r.x, 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_pen(g, rect(r.x+r.width-W, r1.y,
|
result &= app_fill_rect(g, rect(r.x+r.width-W, r1.y,
|
||||||
W, r1.height), BrushObj);
|
W, r1.height), BrushObj, TRUE);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -505,7 +364,8 @@ app_fill_arc_rect(DC *g,
|
||||||
POINT p2, // End
|
POINT p2, // End
|
||||||
int start_angle,
|
int start_angle,
|
||||||
int end_angle,
|
int end_angle,
|
||||||
PGDIBRUSHOBJ BrushObj)
|
PGDIBRUSHOBJ BrushObj,
|
||||||
|
BOOL Pen)
|
||||||
{
|
{
|
||||||
int x1, x2;
|
int x1, x2;
|
||||||
int start_above, end_above;
|
int start_above, end_above;
|
||||||
|
@ -580,36 +440,36 @@ app_fill_arc_rect(DC *g,
|
||||||
{
|
{
|
||||||
/* fill outsides of wedge */
|
/* fill outsides of wedge */
|
||||||
if (! app_fill_rect(g, rect(r.x, r.y,
|
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 0;
|
||||||
return app_fill_rect(g, rect(x2, r.y,
|
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
|
else
|
||||||
{
|
{
|
||||||
/* fill inside of wedge */
|
/* fill inside of wedge */
|
||||||
r.width = x1-x2;
|
r.width = x1-x2;
|
||||||
r.x = x2;
|
r.x = x2;
|
||||||
return app_fill_rect(g, r, BrushObj);
|
return app_fill_rect(g, r, BrushObj, Pen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (start_above)
|
else if (start_above)
|
||||||
{
|
{
|
||||||
/* fill to the left of the start_line */
|
/* fill to the left of the start_line */
|
||||||
r.width = x1-r.x;
|
r.width = x1-r.x;
|
||||||
return app_fill_rect(g, r, BrushObj);
|
return app_fill_rect(g, r, BrushObj, Pen);
|
||||||
}
|
}
|
||||||
else if (end_above)
|
else if (end_above)
|
||||||
{
|
{
|
||||||
/* fill right of end_line */
|
/* fill right of end_line */
|
||||||
r.width = r.x+r.width-x2;
|
r.width = r.x+r.width-x2;
|
||||||
r.x = x2;
|
r.x = x2;
|
||||||
return app_fill_rect(g, r, BrushObj);
|
return app_fill_rect(g, r, BrushObj, Pen);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (start_angle > end_angle)
|
if (start_angle > end_angle)
|
||||||
return app_fill_rect(g,r, BrushObj);
|
return app_fill_rect(g,r, BrushObj, Pen);
|
||||||
else
|
else
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -675,7 +535,7 @@ app_fill_arc_rect(DC *g,
|
||||||
if (start_above && end_above)
|
if (start_above && end_above)
|
||||||
{
|
{
|
||||||
if (start_angle > end_angle)
|
if (start_angle > end_angle)
|
||||||
return app_fill_rect(g,r, BrushObj);
|
return app_fill_rect(g,r, BrushObj, Pen);
|
||||||
else
|
else
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -683,14 +543,14 @@ app_fill_arc_rect(DC *g,
|
||||||
{
|
{
|
||||||
/* fill to the left of end_line */
|
/* fill to the left of end_line */
|
||||||
r.width = x2-r.x;
|
r.width = x2-r.x;
|
||||||
return app_fill_rect(g,r, BrushObj);
|
return app_fill_rect(g,r, BrushObj, Pen);
|
||||||
}
|
}
|
||||||
else if (end_above)
|
else if (end_above)
|
||||||
{
|
{
|
||||||
/* fill right of start_line */
|
/* fill right of start_line */
|
||||||
r.width = r.x+r.width-x1;
|
r.width = r.x+r.width-x1;
|
||||||
r.x = x1;
|
r.x = x1;
|
||||||
return app_fill_rect(g,r, BrushObj);
|
return app_fill_rect(g,r, BrushObj, Pen);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -698,17 +558,17 @@ app_fill_arc_rect(DC *g,
|
||||||
{
|
{
|
||||||
/* fill outsides of wedge */
|
/* fill outsides of wedge */
|
||||||
if (! app_fill_rect(g, rect(r.x, r.y,
|
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 0;
|
||||||
return app_fill_rect(g, rect(x1, r.y,
|
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
|
else
|
||||||
{
|
{
|
||||||
/* fill inside of wedge */
|
/* fill inside of wedge */
|
||||||
r.width = x2-x1;
|
r.width = x2-x1;
|
||||||
r.x = x1;
|
r.x = x1;
|
||||||
return app_fill_rect(g, r, BrushObj);
|
return app_fill_rect(g, r, BrushObj, Pen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -767,7 +627,7 @@ app_fill_ellipse(DC *g, Rect r, PGDIBRUSHOBJ BrushObj)
|
||||||
// START_DEBUG();
|
// START_DEBUG();
|
||||||
|
|
||||||
if ((r.width <= 2) || (r.height <= 2))
|
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.x = r.x + a;
|
||||||
r1.y = r.y;
|
r1.y = r.y;
|
||||||
|
@ -813,8 +673,8 @@ app_fill_ellipse(DC *g, Rect r, PGDIBRUSHOBJ BrushObj)
|
||||||
|
|
||||||
if (r1.y+r1.height < r2.y) {
|
if (r1.y+r1.height < r2.y) {
|
||||||
/* distinct rectangles */
|
/* distinct rectangles */
|
||||||
result &= app_fill_rect(g, r1, BrushObj);
|
result &= app_fill_rect(g, r1, BrushObj, FALSE);
|
||||||
result &= app_fill_rect(g, r2, BrushObj);
|
result &= app_fill_rect(g, r2, BrushObj, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* move down */
|
/* move down */
|
||||||
|
@ -839,7 +699,7 @@ app_fill_ellipse(DC *g, Rect r, PGDIBRUSHOBJ BrushObj)
|
||||||
r1.x = r.x;
|
r1.x = r.x;
|
||||||
r1.width = r.width;
|
r1.width = r.width;
|
||||||
r1.height = r2.y+r2.height-r1.y;
|
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) {
|
else if (x <= a) {
|
||||||
/* crossover, draw final line */
|
/* crossover, draw final line */
|
||||||
|
@ -847,7 +707,7 @@ app_fill_ellipse(DC *g, Rect r, PGDIBRUSHOBJ BrushObj)
|
||||||
r1.width = r.width;
|
r1.width = r.width;
|
||||||
r1.height = r1.y+r1.height-r2.y;
|
r1.height = r1.y+r1.height-r2.y;
|
||||||
r1.y = r2.y;
|
r1.y = r2.y;
|
||||||
result &= app_fill_rect(g, r1, BrushObj);
|
result &= app_fill_rect(g, r1, BrushObj, FALSE);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1014,10 +874,10 @@ app_fill_arc(DC *g, Rect r, int start_angle, int end_angle, PGDIBRUSHOBJ BrushOb
|
||||||
/* distinct rectangles */
|
/* distinct rectangles */
|
||||||
result &= app_fill_arc_rect(g, r1,
|
result &= app_fill_arc_rect(g, r1,
|
||||||
p0, p1, p2,
|
p0, p1, p2,
|
||||||
start_angle, end_angle, BrushObj);
|
start_angle, end_angle, BrushObj, FALSE);
|
||||||
result &= app_fill_arc_rect(g, r2,
|
result &= app_fill_arc_rect(g, r2,
|
||||||
p0, p1, p2,
|
p0, p1, p2,
|
||||||
start_angle, end_angle, BrushObj);
|
start_angle, end_angle, BrushObj, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* move down */
|
/* move down */
|
||||||
|
@ -1039,7 +899,7 @@ app_fill_arc(DC *g, Rect r, int start_angle, int end_angle, PGDIBRUSHOBJ BrushOb
|
||||||
while (r1.height > 0) {
|
while (r1.height > 0) {
|
||||||
result &= app_fill_arc_rect(g,
|
result &= app_fill_arc_rect(g,
|
||||||
rect(r1.x, r1.y, r1.width, 1),
|
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.y += 1;
|
||||||
r1.height -= 1;
|
r1.height -= 1;
|
||||||
}
|
}
|
||||||
|
@ -1053,7 +913,7 @@ app_fill_arc(DC *g, Rect r, int start_angle, int end_angle, PGDIBRUSHOBJ BrushOb
|
||||||
while (r1.height > 0) {
|
while (r1.height > 0) {
|
||||||
result &= app_fill_arc_rect(g,
|
result &= app_fill_arc_rect(g,
|
||||||
rect(r1.x, r1.y, r1.width, 1),
|
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.y += 1;
|
||||||
r1.height -= 1;
|
r1.height -= 1;
|
||||||
}
|
}
|
||||||
|
@ -1061,8 +921,345 @@ app_fill_arc(DC *g, Rect r, int start_angle, int end_angle, PGDIBRUSHOBJ BrushOb
|
||||||
return result;
|
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 *********************************************************/
|
/* 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
|
BOOL
|
||||||
FASTCALL
|
FASTCALL
|
||||||
IntFillArc( PDC dc,
|
IntFillArc( PDC dc,
|
||||||
|
@ -1100,6 +1297,28 @@ IntFillArc( PDC dc,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
BOOL
|
||||||
FASTCALL
|
FASTCALL
|
||||||
IntDrawEllipse( PDC dc,
|
IntDrawEllipse( PDC dc,
|
||||||
|
@ -1139,3 +1358,154 @@ IntFillEllipse( PDC dc,
|
||||||
BRUSHOBJ_UnlockBrush(FillBrushObj);
|
BRUSHOBJ_UnlockBrush(FillBrushObj);
|
||||||
return ret;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,8 @@
|
||||||
|
|
||||||
BOOL FASTCALL IntFillEllipse( PDC dc, INT XLeft, INT YLeft, INT Width, INT Height);
|
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 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
|
BOOL FASTCALL
|
||||||
IntGdiPolygon(PDC dc,
|
IntGdiPolygon(PDC dc,
|
||||||
|
@ -669,271 +671,97 @@ BOOL
|
||||||
FASTCALL
|
FASTCALL
|
||||||
IntRoundRect(
|
IntRoundRect(
|
||||||
PDC dc,
|
PDC dc,
|
||||||
int left,
|
int Left,
|
||||||
int top,
|
int Top,
|
||||||
int right,
|
int Right,
|
||||||
int bottom,
|
int Bottom,
|
||||||
int xCurveDiameter,
|
int xCurveDiameter,
|
||||||
int yCurveDiameter)
|
int yCurveDiameter)
|
||||||
{
|
{
|
||||||
PDC_ATTR Dc_Attr;
|
PDC_ATTR Dc_Attr;
|
||||||
BITMAPOBJ *BitmapObj;
|
PGDIBRUSHOBJ PenBrushObj;
|
||||||
PGDIBRUSHOBJ PenBrushObj, FillBrushObj;
|
RECTL RectBounds;
|
||||||
GDIBRUSHINST FillBrushInst, PenBrushInst;
|
LONG PenWidth, PenOrigWidth;
|
||||||
RECTL RectBounds;
|
BOOL ret = TRUE; // default to success
|
||||||
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
|
|
||||||
|
|
||||||
ASSERT ( dc ); // caller's responsibility to set this up
|
ASSERT ( dc ); // caller's responsibility to set this up
|
||||||
|
|
||||||
if ( PATH_IsPathOpen(dc->DcLevel) )
|
if ( PATH_IsPathOpen(dc->DcLevel) )
|
||||||
return PATH_RoundRect ( dc, left, top, right, bottom,
|
return PATH_RoundRect ( dc, Left, Top, Right, Bottom,
|
||||||
xCurveDiameter, yCurveDiameter );
|
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;
|
Dc_Attr = dc->pDc_Attr;
|
||||||
if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
|
if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
|
||||||
|
|
||||||
xradius = xCurveDiameter >> 1;
|
PenBrushObj = PENOBJ_LockPen(Dc_Attr->hpen);
|
||||||
yradius = yCurveDiameter >> 1;
|
if (!PenBrushObj)
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
/* Nothing to do, as we don't have a bitmap */
|
/* Nothing to do, as we don't have a bitmap */
|
||||||
SetLastWin32Error(ERROR_INTERNAL_ERROR);
|
SetLastWin32Error(ERROR_INTERNAL_ERROR);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
FillBrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush);
|
PenOrigWidth = PenWidth = PenBrushObj->ptPenWidth.x;
|
||||||
if (FillBrushObj)
|
if (PenBrushObj->ulPenStyle == PS_NULL) PenWidth = 0;
|
||||||
|
|
||||||
|
if (PenBrushObj->ulPenStyle == PS_INSIDEFRAME)
|
||||||
{
|
{
|
||||||
if (FillBrushObj->flAttrs & GDIBRUSH_IS_NULL)
|
if (2*PenWidth > (Right - Left)) PenWidth = (Right -Left + 1)/2;
|
||||||
{
|
if (2*PenWidth > (Bottom - Top)) PenWidth = (Bottom -Top + 1)/2;
|
||||||
/* make null brush check simpler... */
|
Left += PenWidth / 2;
|
||||||
BRUSHOBJ_UnlockBrush(FillBrushObj);
|
Right -= (PenWidth - 1) / 2;
|
||||||
FillBrushObj = NULL;
|
Top += PenWidth / 2;
|
||||||
}
|
Bottom -= (PenWidth - 1) / 2;
|
||||||
else
|
|
||||||
{
|
|
||||||
IntGdiInitBrushInstance(&FillBrushInst, FillBrushObj, dc->XlateBrush);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PenBrushObj = PENOBJ_LockPen(Dc_Attr->hpen);
|
if (!PenWidth) PenWidth = 1;
|
||||||
if (PenBrushObj)
|
PenBrushObj->ptPenWidth.x = PenWidth;
|
||||||
{
|
|
||||||
if (PenBrushObj->flAttrs & GDIBRUSH_IS_NULL)
|
|
||||||
{
|
|
||||||
/* make null pen check simpler... */
|
|
||||||
PENOBJ_UnlockPen(PenBrushObj);
|
|
||||||
PenBrushObj = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IntGdiInitBrushInstance(&PenBrushInst, PenBrushObj, dc->XlatePen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
right--;
|
RectBounds.left = Left;
|
||||||
bottom--;
|
RectBounds.top = Top;
|
||||||
|
RectBounds.right = Right;
|
||||||
|
RectBounds.bottom = Bottom;
|
||||||
|
|
||||||
width = right - left;
|
IntLPtoDP(dc, (LPPOINT)&RectBounds, 2);
|
||||||
height = bottom - top;
|
|
||||||
|
|
||||||
if ( (xradius<<1) > width )
|
RectBounds.left += dc->ptlDCOrig.x;
|
||||||
xradius = width >> 1;
|
RectBounds.top += dc->ptlDCOrig.y;
|
||||||
if ( (yradius<<1) > height )
|
RectBounds.right += dc->ptlDCOrig.x;
|
||||||
yradius = height >> 1;
|
RectBounds.bottom += dc->ptlDCOrig.y;
|
||||||
|
|
||||||
b_square = yradius * yradius;
|
ret = IntFillRoundRect( dc,
|
||||||
a_square = xradius * xradius;
|
RectBounds.left,
|
||||||
row = yradius;
|
RectBounds.top,
|
||||||
col = 0;
|
RectBounds.right,
|
||||||
two_a_square = a_square << 1;
|
RectBounds.bottom,
|
||||||
four_a_square = a_square << 2;
|
xCurveDiameter,
|
||||||
four_b_square = b_square << 2;
|
yCurveDiameter);
|
||||||
two_b_square = b_square << 1;
|
if (ret)
|
||||||
d = two_a_square * ((row - 1) * (row))
|
ret = IntDrawRoundRect( dc,
|
||||||
+ a_square
|
RectBounds.left,
|
||||||
+ two_b_square * (1 - a_square);
|
RectBounds.top,
|
||||||
|
RectBounds.right,
|
||||||
x1 = left+xradius;
|
RectBounds.bottom,
|
||||||
x2 = right-xradius;
|
xCurveDiameter,
|
||||||
y1 = top;
|
yCurveDiameter,
|
||||||
y2 = bottom;
|
PenBrushObj);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
|
PenBrushObj->ptPenWidth.x = PenOrigWidth;
|
||||||
|
PENOBJ_UnlockPen(PenBrushObj);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue