/// <summary>See <c>WpfExtensions</c> for details.</summary> public static void DrawRectangle(DrawingContext dc, Rect rect, Paint paint, CornerRadius corners, CornerStyle cornerStyle, BorderSide borderSide, bool snapToPixel) { // get brush and stroke resources if (paint == null) return; var fill = paint.Fill; var strokes = paint.GetStrokePens().ToArray(); var hasFill = (fill != null); var hasStroke = (strokes.Length > 0 && borderSide != BorderSide.None); if (!hasFill && !hasStroke) return; // compute the drawing rectangle with offset for pixel snapping // (assumptions: the box itself is pixel snapped, all strokes have same thickness, and the thickness is a whole number) var halfThickness = Math.Round(hasStroke ? strokes[0].Thickness : 0.0) / 2; if (snapToPixel && hasStroke) { rect = new Rect(rect.X + halfThickness, rect.Y + halfThickness, (rect.Width - 2 * halfThickness).Max(0), (rect.Height - 2 * halfThickness).Max(0)); } // select drawing function based on the corners complexity DrawingFunction fillFunc = null; if (corners.IsZero()) { fillFunc = _drawSimpleRectangle; } else if (corners.IsUniform()) { fillFunc = _drawRoundedRectangle; } else { fillFunc = _drawComplexRectangle; } // draw the border if (hasStroke) { if (paint.IsA<QuadPaint>()) { rect = _drawSide(dc, rect, null, strokes[0], corners, cornerStyle, BorderSide.Left); rect = _drawSide(dc, rect, null, strokes[1], corners, cornerStyle, BorderSide.Top); rect = _drawSide(dc, rect, null, strokes[2], corners, cornerStyle, BorderSide.Right); rect = _drawSide(dc, rect, null, strokes[3], corners, cornerStyle, BorderSide.Bottom); corners = _inflateCorners(corners, strokes[3]); } else { var strokeFunc = (borderSide == BorderSide.All ? fillFunc : _drawSide); foreach (var stroke in strokes) { rect = strokeFunc(dc, rect, null, stroke, corners, cornerStyle, borderSide); corners = _inflateCorners(corners, stroke); } } } // draw the background if (hasFill) { if (snapToPixel) { rect = _deflateRect(rect, -halfThickness); } if (paint.FillMode == BrushMappingMode.Absolute) { fill = _mapAbsoluteFill(fill, rect); } fillFunc(dc, rect, fill, null, corners, cornerStyle, borderSide); } }