DrawPath doesn't return a correct shape when the corners are rounded

61 views Asked by At

I'm trying to draw a rectangle with rounded corners. But when I print the layout there's a problem with the lines like the image below:

Wrong Image of Rect

while the image that I need to print is this:

Correct Image of Rect

This is the part of the code which can be useful for reach the solution:

private void DrawBorder(LayoutObject object, Graphics graphics)
{
    var objectX = object.X;
    var objectY = object.Y;
    if (_rotate180)
    {
        (objectX, objectY) = object.CalculateRotation180(_layoutHeight, _layoutWidth);
    }

    // Calculate object dimensions based on graphics DPI
    var xDpi = objectX * graphics.DpiX;
    var yDpi = objectY * graphics.DpiY;

    var widthDpi = object.Width * graphics.DpiX;
    var heightDpi = object.Height * graphics.DpiY;

    var borderWidthX = object.BorderThickness * graphics.DpiX;
    var borderWidthY = object.BorderThickness * graphics.DpiY;

    var cornerRadiusX = object.CornerRadius * graphics.DpiX;
    var cornerRadiusY = object.CornerRadius * graphics.DpiY;

    var rectangle = new RectangleF(xDpi, yDpi, widthDpi, heightDpi);

    // Draw the border (with possible rounding)
    if (borderWidthX > 0 || borderWidthY > 0)
    {
        if (!string.IsNullOrWhiteSpace(object.BorderColor))
        {
            var brush = object.BorderColor.FromRgbaToSolidBrush();

            if (_rotate180)
            {
                graphics.RotateCenter(180.0F, rectangle);
            }

            if (object.Orientation > 0)
            {
                graphics.RotateCenter(object.Orientation, rectangle);
            }

            // Define the rectangle for drawing the border based on the original rectangle.
            var borderRectangle = new RectangleF(xDpi + (borderWidthX / 2), yDpi + (borderWidthY / 2), widthDpi - borderWidthX, heightDpi - borderWidthY);

            if (cornerRadiusX > 0 || cornerRadiusY > 0)
            {
                // Draw the rounded border.
                cornerRadiusX -= borderWidthX / 2;
                cornerRadiusY -= borderWidthY / 2;

                graphics.DrawRoundedCornerRectangle(borderRectangle, new Pen(brush, borderWidthX), cornerRadiusX, cornerRadiusY);
            }
            else
            {
                graphics.DrawRectangle(new Pen(brush, borderWidthX), borderRectangle.X, borderRectangle.Y, borderRectangle.Width, borderRectangle.Height);
            }

            graphics.ResetTransform();
        }
    }
}

and the static methods for the rectangle with rounded corners are:

public static void DrawRoundedCornerRectangle(this Graphics graphics, RectangleF rectangle, Pen pen, float xradius, float yradius)
        {
            using (GraphicsPath path = MakeRoundedRect(rectangle, xradius, yradius))
            {
                graphics.DrawPath(pen, path);
            }
        }

private static GraphicsPath MakeRoundedRect(RectangleF rect, float xradius, float yradius)
        {
            // Make a GraphicsPath to draw the rectangle.
            var path = new GraphicsPath();

            // Upper left corner.
            RectangleF corner = new RectangleF(rect.X, rect.Y, 2 * xradius, 2 * yradius);
            path.AddArc(corner, 180, 90);

            // Upper right corner.
            corner = new RectangleF(rect.Right - 2 * xradius, rect.Y, 2 * xradius, 2 * yradius);
            path.AddArc(corner, 270, 90);

            // Lower right corner.
            corner = new RectangleF(rect.Right - 2 * xradius, rect.Bottom - 2 * yradius, 2 * xradius, 2 * yradius);
            path.AddArc(corner, 0, 90);

            // Lower left corner.
            corner = new RectangleF(rect.X, rect.Bottom - 2 * yradius, 2 * xradius, 2 * yradius);
            path.AddArc(corner, 90, 90);

            // Join with the start point.
            path.CloseFigure();

            return path;
        }
1

There are 1 answers

0
Peter Dongan On

It looks like your corner radiuses are very large and that this is caused by using dpi as a scaling factor instead of dpi/baseValue.

Usually you can divide DPI by 96 for a scaling factor, because 96 is a fairly standard dpi.