/// <summary> /// Draws a point primitive to the specified destination buffer. /// </summary> /// <param name="buffer">The destination buffer.</param> /// <param name="brush">A GDI brush to use for drawing.</param> /// <param name="point">The point primitive to be drawn.</param> /// <param name="dpi">The intended output DPI.</param> public static void DrawPointPrimitive(IGdiBuffer buffer, SolidBrush brush, PointPrimitive point, float dpi = _nominalScreenDpi) { buffer.Graphics.Transform = point.SpatialTransform.CumulativeTransform; point.CoordinateSystem = CoordinateSystem.Source; try { var dropShadowOffset = GetDropShadowOffset(point, dpi); var width = CalculateScaledPenWidth(point, 1, dpi); // Draw drop shadow brush.Color = Color.Black; buffer.Graphics.FillRectangle( brush, point.Point.X + dropShadowOffset.Width, point.Point.Y + dropShadowOffset.Height, width, width); // Draw point brush.Color = point.Color; buffer.Graphics.FillRectangle( brush, point.Point.X, point.Point.Y, width, width); } finally { point.ResetCoordinateSystem(); buffer.Graphics.ResetTransform(); } }
/// <summary> /// Draws a line primitive to the specified destination buffer. /// </summary> /// <param name="buffer">The destination buffer.</param> /// <param name="pen">A GDI pen to use for drawing.</param> /// <param name="line">The line primitive to be drawn.</param> /// <param name="dpi">The intended output DPI.</param> public static void DrawLinePrimitive(IGdiBuffer buffer, Pen pen, ILineSegmentGraphic line, float dpi = _nominalScreenDpi) { buffer.Graphics.Transform = line.SpatialTransform.CumulativeTransform; line.CoordinateSystem = CoordinateSystem.Source; buffer.Graphics.SmoothingMode = SmoothingMode.AntiAlias; try { // Draw drop shadow pen.Color = Color.Black; pen.Width = CalculateScaledPenWidth(line, 1, dpi); SetDashStyle(pen, line); var dropShadowOffset = GetDropShadowOffset(line, dpi); buffer.Graphics.DrawLine( pen, line.Point1 + dropShadowOffset, line.Point2 + dropShadowOffset); // Draw line pen.Color = line.Color; buffer.Graphics.DrawLine( pen, line.Point1, line.Point2); } finally { buffer.Graphics.SmoothingMode = SmoothingMode.None; line.ResetCoordinateSystem(); buffer.Graphics.ResetTransform(); } }
public static void DrawAnnotationBox(IGdiBuffer buffer, SolidBrush brush, IFontFactory fontFactory, string annotationText, AnnotationBox annotationBox, float dpi = _nominalScreenDpi) { var fakeFactory = new LegacyGdiObjectFactory(fontFactory, brush); DrawAnnotationBox(buffer, fakeFactory, annotationText, annotationBox, dpi); }
/// <summary> /// Draws an arc primitive to the specified destination buffer. /// </summary> /// <param name="buffer">The destination buffer.</param> /// <param name="pen">A GDI pen to use for drawing.</param> /// <param name="arc">The arc primitive to be drawn.</param> /// <param name="dpi">The intended output DPI.</param> public static void DrawArcPrimitive(IGdiBuffer buffer, Pen pen, IArcGraphic arc, float dpi = _nominalScreenDpi) { buffer.Graphics.Transform = arc.SpatialTransform.CumulativeTransform; arc.CoordinateSystem = CoordinateSystem.Source; buffer.Graphics.SmoothingMode = SmoothingMode.AntiAlias; try { var rectangle = new RectangleF(arc.TopLeft.X, arc.TopLeft.Y, arc.Width, arc.Height); rectangle = RectangleUtilities.ConvertToPositiveRectangle(rectangle); var dropShadowOffset = GetDropShadowOffset(arc, dpi); // Draw drop shadow pen.Color = Color.Black; pen.Width = CalculateScaledPenWidth(arc, 1, dpi); SetDashStyle(pen, arc); buffer.Graphics.DrawArc( pen, rectangle.Left + dropShadowOffset.Width, rectangle.Top + dropShadowOffset.Height, rectangle.Width, rectangle.Height, arc.StartAngle, arc.SweepAngle); // Draw rectangle pen.Color = arc.Color; buffer.Graphics.DrawArc( pen, rectangle.Left, rectangle.Top, rectangle.Width, rectangle.Height, arc.StartAngle, arc.SweepAngle); } finally { buffer.Graphics.SmoothingMode = SmoothingMode.None; arc.ResetCoordinateSystem(); buffer.Graphics.ResetTransform(); } }
/// <summary> /// Draws a spline primitive to the specified destination buffer. /// </summary> /// <param name="buffer">The destination buffer.</param> /// <param name="pen">A GDI pen to use for drawing.</param> /// <param name="spline">The spline primitive to be drawn.</param> /// <param name="dpi">The intended output DPI.</param> public static void DrawSplinePrimitive(IGdiBuffer buffer, Pen pen, SplinePrimitive spline, float dpi = _nominalScreenDpi) { buffer.Graphics.Transform = spline.SpatialTransform.CumulativeTransform; spline.CoordinateSystem = CoordinateSystem.Source; buffer.Graphics.SmoothingMode = SmoothingMode.AntiAlias; try { // Draw drop shadow pen.Color = Color.Black; pen.Width = CalculateScaledPenWidth(spline, 1, dpi); SetDashStyle(pen, spline); var dropShadowOffset = GetDropShadowOffset(spline, dpi); var pathPoints = GetCurvePoints(spline.Points, dropShadowOffset); if (spline.Points.IsClosed) { buffer.Graphics.DrawClosedCurve(pen, pathPoints); } else { buffer.Graphics.DrawCurve(pen, pathPoints); } // Draw line pen.Color = spline.Color; pathPoints = GetCurvePoints(spline.Points, SizeF.Empty); if (spline.Points.IsClosed) { buffer.Graphics.DrawClosedCurve(pen, pathPoints); } else { buffer.Graphics.DrawCurve(pen, pathPoints); } } finally { buffer.Graphics.SmoothingMode = SmoothingMode.None; spline.ResetCoordinateSystem(); buffer.Graphics.ResetTransform(); } }
/// <summary> /// Draws a text primitive to the specified destination buffer. /// </summary> /// <param name="buffer">The destination buffer.</param> /// <param name="gdiObjectFactory">A factory for GDI+ objects.</param> /// <param name="text">The text primitive to be drawn.</param> /// <param name="dpi">The intended output DPI.</param> public static void DrawTextPrimitive(IGdiBuffer buffer, IGdiObjectFactory gdiObjectFactory, InvariantTextPrimitive text, float dpi = _nominalScreenDpi) { text.CoordinateSystem = CoordinateSystem.Destination; try { // We adjust the font size depending on the scale so that it's the same size // irrespective of the zoom var fontSize = CalculateScaledFontPoints(text.SizeInPoints, dpi); var createFontArgs = new CreateFontArgs(text.Font, fontSize, FontStyle.Regular, GraphicsUnit.Point) { DefaultFontName = FontFactory.GenericSansSerif }; var font = gdiObjectFactory.CreateFont(createFontArgs); // Calculate how big the text will be so we can set the bounding box text.Dimensions = buffer.Graphics.MeasureString(text.Text, font); // Draw drop shadow var brush = gdiObjectFactory.CreateBrush(new CreateBrushArgs(Color.Black)); var dropShadowOffset = new SizeF(1, 1); var boundingBoxTopLeft = new PointF(text.BoundingBox.Left, text.BoundingBox.Top); buffer.Graphics.DrawString( text.Text, font, brush, boundingBoxTopLeft + dropShadowOffset); // Draw text brush = gdiObjectFactory.CreateBrush(new CreateBrushArgs(text.Color)); buffer.Graphics.DrawString( text.Text, font, brush, boundingBoxTopLeft); } finally { text.ResetCoordinateSystem(); } }
/// <summary> /// Draws an ellipse primitive to the specified destination buffer. /// </summary> /// <param name="buffer">The destination buffer.</param> /// <param name="pen">A GDI pen to use for drawing.</param> /// <param name="ellipse">The ellipse primitive to be drawn.</param> /// <param name="dpi">The intended output DPI.</param> public static void DrawEllipsePrimitive(IGdiBuffer buffer, Pen pen, IBoundableGraphic ellipse, float dpi = _nominalScreenDpi) { buffer.Graphics.Transform = ellipse.SpatialTransform.CumulativeTransform; ellipse.CoordinateSystem = CoordinateSystem.Source; buffer.Graphics.SmoothingMode = SmoothingMode.AntiAlias; try { var rectangle = new RectangleF(ellipse.TopLeft.X, ellipse.TopLeft.Y, ellipse.Width, ellipse.Height); rectangle = RectangleUtilities.ConvertToPositiveRectangle(rectangle); var dropShadowOffset = GetDropShadowOffset(ellipse, dpi); // Draw drop shadow pen.Color = Color.Black; pen.Width = CalculateScaledPenWidth(ellipse, 1, dpi); SetDashStyle(pen, ellipse); buffer.Graphics.DrawEllipse( pen, rectangle.Left + dropShadowOffset.Width, rectangle.Top + dropShadowOffset.Height, rectangle.Width, rectangle.Height); // Draw rectangle pen.Color = ellipse.Color; buffer.Graphics.DrawEllipse( pen, rectangle.Left, rectangle.Top, rectangle.Width, rectangle.Height); } finally { buffer.Graphics.SmoothingMode = SmoothingMode.None; ellipse.ResetCoordinateSystem(); buffer.Graphics.ResetTransform(); } }
/// <summary> /// Draws a text primitive to the specified destination buffer. /// </summary> /// <param name="buffer">The destination buffer.</param> /// <param name="brush">A GDI brush to use for drawing.</param> /// <param name="fontFactory">A GDI font factory to use for drawing.</param> /// <param name="text">The text primitive to be drawn.</param> /// <param name="dpi">The intended output DPI.</param> public static void DrawTextPrimitive(IGdiBuffer buffer, SolidBrush brush, FontFactory fontFactory, InvariantTextPrimitive text, float dpi = _nominalScreenDpi) { text.CoordinateSystem = CoordinateSystem.Destination; try { // We adjust the font size depending on the scale so that it's the same size // irrespective of the zoom var fontSize = CalculateScaledFontPoints(text.SizeInPoints, dpi); var font = fontFactory.GetFont(text.Font, fontSize, FontStyle.Regular, GraphicsUnit.Point, FontFactory.GenericSansSerif); // Calculate how big the text will be so we can set the bounding box text.Dimensions = buffer.Graphics.MeasureString(text.Text, font); // Draw drop shadow brush.Color = Color.Black; var dropShadowOffset = new SizeF(1, 1); var boundingBoxTopLeft = new PointF(text.BoundingBox.Left, text.BoundingBox.Top); buffer.Graphics.DrawString( text.Text, font, brush, boundingBoxTopLeft + dropShadowOffset); // Draw text brush.Color = text.Color; buffer.Graphics.DrawString( text.Text, font, brush, boundingBoxTopLeft); } finally { text.ResetCoordinateSystem(); } }
/// <summary> /// Draws an annotation box to the specified destination buffer. /// </summary> /// <param name="buffer">The destination buffer.</param> /// <param name="brush">A GDI brush to use for drawing.</param> /// <param name="fontFactory">A GDI font factory to use for drawing.</param> /// <param name="annotationText">The annotation text to be drawn.</param> /// <param name="annotationBox">The annotation box to be drawn.</param> /// <param name="dpi">The intended output DPI.</param> public static void DrawAnnotationBox(IGdiBuffer buffer, SolidBrush brush, FontFactory fontFactory, string annotationText, AnnotationBox annotationBox, float dpi = _nominalScreenDpi) { // if there's nothing to draw, there's nothing to do. go figure. if (string.IsNullOrEmpty(annotationText)) return; var clientRectangle = RectangleUtilities.CalculateSubRectangle(buffer.Bounds, annotationBox.NormalizedRectangle); //Deflate the client rectangle by 4 pixels to allow some space //between neighbouring rectangles whose borders coincide. Rectangle.Inflate(clientRectangle, -4, -4); var fontSize = (clientRectangle.Height/annotationBox.NumberOfLines) - 1; //don't draw it if it's too small to read, anyway. if (fontSize < MinimumFontSizeInPixels) return; using (var format = new StringFormat()) { if (annotationBox.Truncation == AnnotationBox.TruncationBehaviour.Truncate) format.Trimming = StringTrimming.Character; else format.Trimming = StringTrimming.EllipsisCharacter; if (annotationBox.FitWidth) format.Trimming = StringTrimming.None; if (annotationBox.Justification == AnnotationBox.JustificationBehaviour.Right) format.Alignment = StringAlignment.Far; else if (annotationBox.Justification == AnnotationBox.JustificationBehaviour.Center) format.Alignment = StringAlignment.Center; else format.Alignment = StringAlignment.Near; if (annotationBox.VerticalAlignment == AnnotationBox.VerticalAlignmentBehaviour.Top) format.LineAlignment = StringAlignment.Near; else if (annotationBox.VerticalAlignment == AnnotationBox.VerticalAlignmentBehaviour.Center) format.LineAlignment = StringAlignment.Center; else format.LineAlignment = StringAlignment.Far; //allow p's and q's, etc to extend slightly beyond the bounding rectangle. Only completely visible lines are shown. format.FormatFlags = StringFormatFlags.NoClip; if (annotationBox.NumberOfLines == 1) format.FormatFlags |= StringFormatFlags.NoWrap; var style = FontStyle.Regular; if (annotationBox.Bold) style |= FontStyle.Bold; if (annotationBox.Italics) style |= FontStyle.Italic; //don't draw it if it's too small to read, anyway. if (fontSize < MinimumFontSizeInPixels) return; var font = fontFactory.GetFont(annotationBox.Font, fontSize, style, GraphicsUnit.Pixel, AnnotationBox.DefaultFont); var layoutArea = new SizeF(clientRectangle.Width, clientRectangle.Height); var size = buffer.Graphics.MeasureString(annotationText, font, layoutArea, format); if (annotationBox.FitWidth && size.Width > clientRectangle.Width) { fontSize = (int) (Math.Round(fontSize*clientRectangle.Width/(double) size.Width - 0.5)); //don't draw it if it's too small to read, anyway. if (fontSize < MinimumFontSizeInPixels) return; font = fontFactory.GetFont(annotationBox.Font, fontSize, style, GraphicsUnit.Pixel, AnnotationBox.DefaultFont); } // Draw drop shadow brush.Color = Color.Black; clientRectangle.Offset(1, 1); buffer.Graphics.DrawString( annotationText, font, brush, clientRectangle, format); brush.Color = Color.FromName(annotationBox.Color); clientRectangle.Offset(-1, -1); buffer.Graphics.DrawString( annotationText, font, brush, clientRectangle, format); } }
public static void DrawTextPrimitive(IGdiBuffer buffer, SolidBrush brush, IFontFactory fontFactory, InvariantTextPrimitive text, float dpi = _nominalScreenDpi) { var fakeFactory = new LegacyGdiObjectFactory(fontFactory, brush); DrawTextPrimitive(buffer, fakeFactory, text, dpi); }
/// <summary> /// Draws an annotation box to the specified destination buffer. /// </summary> /// <param name="buffer">The destination buffer.</param> /// <param name="gdiObjectFactory">A factory for GDI objects.</param> /// <param name="annotationText">The annotation text to be drawn.</param> /// <param name="annotationBox">The annotation box to be drawn.</param> /// <param name="dpi">The intended output DPI.</param> public static void DrawAnnotationBox(IGdiBuffer buffer, IGdiObjectFactory gdiObjectFactory, string annotationText, AnnotationBox annotationBox, float dpi = _nominalScreenDpi) { // if there's nothing to draw, there's nothing to do. go figure. if (string.IsNullOrWhiteSpace(annotationText)) { return; } var clientRectangle = RectangleUtilities.CalculateSubRectangle(buffer.Bounds, annotationBox.NormalizedRectangle); //Deflate the client rectangle by 4 pixels to allow some space //between neighbouring rectangles whose borders coincide. Rectangle.Inflate(clientRectangle, -4, -4); var fontSize = (clientRectangle.Height / annotationBox.NumberOfLines) - 1; //don't draw it if it's too small to read, anyway. if (fontSize < MinimumFontSizeInPixels) { return; } var style = FontStyle.Regular; if (annotationBox.Bold) { style |= FontStyle.Bold; } if (annotationBox.Italics) { style |= FontStyle.Italic; } //don't draw it if it's too small to read, anyway. if (fontSize < MinimumFontSizeInPixels) { return; } var fontArgs = new CreateFontArgs(annotationBox.Font, fontSize, style, GraphicsUnit.Pixel) { DefaultFontName = AnnotationBox.DefaultFont }; var font = gdiObjectFactory.CreateFont(fontArgs); var format = gdiObjectFactory.CreateStringFormat(new CreateStringFormatArgs(annotationBox)); var layoutArea = new SizeF(clientRectangle.Width, clientRectangle.Height); var size = buffer.Graphics.MeasureString(annotationText, font, layoutArea, format); if (annotationBox.FitWidth && size.Width > clientRectangle.Width) { fontSize = (int)(Math.Round(fontSize * clientRectangle.Width / (double)size.Width - 0.5)); //don't draw it if it's too small to read, anyway. if (fontSize < MinimumFontSizeInPixels) { return; } font = gdiObjectFactory.CreateFont(fontArgs); } // Draw drop shadow var brush = gdiObjectFactory.CreateBrush(new CreateBrushArgs(Color.Black)); clientRectangle.Offset(1, 1); buffer.Graphics.DrawString( annotationText, font, brush, clientRectangle, format); brush = gdiObjectFactory.CreateBrush(new CreateBrushArgs(annotationBox.Color)); clientRectangle.Offset(-1, -1); buffer.Graphics.DrawString( annotationText, font, brush, clientRectangle, format); }
/// <summary> /// Draws an annotation box to the specified destination buffer. /// </summary> /// <param name="buffer">The destination buffer.</param> /// <param name="brush">A GDI brush to use for drawing.</param> /// <param name="fontFactory">A GDI font factory to use for drawing.</param> /// <param name="annotationText">The annotation text to be drawn.</param> /// <param name="annotationBox">The annotation box to be drawn.</param> /// <param name="dpi">The intended output DPI.</param> public static void DrawAnnotationBox(IGdiBuffer buffer, SolidBrush brush, FontFactory fontFactory, string annotationText, AnnotationBox annotationBox, float dpi = _nominalScreenDpi) { // if there's nothing to draw, there's nothing to do. go figure. if (string.IsNullOrEmpty(annotationText)) { return; } var clientRectangle = RectangleUtilities.CalculateSubRectangle(buffer.Bounds, annotationBox.NormalizedRectangle); //Deflate the client rectangle by 4 pixels to allow some space //between neighbouring rectangles whose borders coincide. Rectangle.Inflate(clientRectangle, -4, -4); var fontSize = (clientRectangle.Height / annotationBox.NumberOfLines) - 1; //don't draw it if it's too small to read, anyway. if (fontSize < MinimumFontSizeInPixels) { return; } using (var format = new StringFormat()) { if (annotationBox.Truncation == AnnotationBox.TruncationBehaviour.Truncate) { format.Trimming = StringTrimming.Character; } else { format.Trimming = StringTrimming.EllipsisCharacter; } if (annotationBox.FitWidth) { format.Trimming = StringTrimming.None; } if (annotationBox.Justification == AnnotationBox.JustificationBehaviour.Right) { format.Alignment = StringAlignment.Far; } else if (annotationBox.Justification == AnnotationBox.JustificationBehaviour.Center) { format.Alignment = StringAlignment.Center; } else { format.Alignment = StringAlignment.Near; } if (annotationBox.VerticalAlignment == AnnotationBox.VerticalAlignmentBehaviour.Top) { format.LineAlignment = StringAlignment.Near; } else if (annotationBox.VerticalAlignment == AnnotationBox.VerticalAlignmentBehaviour.Center) { format.LineAlignment = StringAlignment.Center; } else { format.LineAlignment = StringAlignment.Far; } //allow p's and q's, etc to extend slightly beyond the bounding rectangle. Only completely visible lines are shown. format.FormatFlags = StringFormatFlags.NoClip; if (annotationBox.NumberOfLines == 1) { format.FormatFlags |= StringFormatFlags.NoWrap; } var style = FontStyle.Regular; if (annotationBox.Bold) { style |= FontStyle.Bold; } if (annotationBox.Italics) { style |= FontStyle.Italic; } //don't draw it if it's too small to read, anyway. if (fontSize < MinimumFontSizeInPixels) { return; } var font = fontFactory.GetFont(annotationBox.Font, fontSize, style, GraphicsUnit.Pixel, AnnotationBox.DefaultFont); var layoutArea = new SizeF(clientRectangle.Width, clientRectangle.Height); var size = buffer.Graphics.MeasureString(annotationText, font, layoutArea, format); if (annotationBox.FitWidth && size.Width > clientRectangle.Width) { fontSize = (int)(Math.Round(fontSize * clientRectangle.Width / (double)size.Width - 0.5)); //don't draw it if it's too small to read, anyway. if (fontSize < MinimumFontSizeInPixels) { return; } font = fontFactory.GetFont(annotationBox.Font, fontSize, style, GraphicsUnit.Pixel, AnnotationBox.DefaultFont); } // Draw drop shadow brush.Color = Color.Black; clientRectangle.Offset(1, 1); buffer.Graphics.DrawString( annotationText, font, brush, clientRectangle, format); brush.Color = Color.FromName(annotationBox.Color); clientRectangle.Offset(-1, -1); buffer.Graphics.DrawString( annotationText, font, brush, clientRectangle, format); } }
public static void DrawPointPrimitive(IGdiBuffer buffer, SolidBrush brush, PointPrimitive point, float dpi = _nominalScreenDpi) { var fakeFactory = new LegacyGdiObjectFactory(null, brush); DrawPointPrimitive(buffer, fakeFactory, point, dpi); }
/// <summary> /// Draws an annotation box to the specified destination buffer. /// </summary> /// <param name="buffer">The destination buffer.</param> /// <param name="gdiObjectFactory">A factory for GDI objects.</param> /// <param name="annotationText">The annotation text to be drawn.</param> /// <param name="annotationBox">The annotation box to be drawn.</param> /// <param name="dpi">The intended output DPI.</param> public static void DrawAnnotationBox(IGdiBuffer buffer, IGdiObjectFactory gdiObjectFactory, string annotationText, AnnotationBox annotationBox, float dpi = _nominalScreenDpi) { // if there's nothing to draw, there's nothing to do. go figure. if (string.IsNullOrWhiteSpace(annotationText)) return; var clientRectangle = RectangleUtilities.CalculateSubRectangle(buffer.Bounds, annotationBox.NormalizedRectangle); //Deflate the client rectangle by 4 pixels to allow some space //between neighbouring rectangles whose borders coincide. Rectangle.Inflate(clientRectangle, -4, -4); var fontSize = (clientRectangle.Height/annotationBox.NumberOfLines) - 1; //don't draw it if it's too small to read, anyway. if (fontSize < MinimumFontSizeInPixels) return; var style = FontStyle.Regular; if (annotationBox.Bold) style |= FontStyle.Bold; if (annotationBox.Italics) style |= FontStyle.Italic; //don't draw it if it's too small to read, anyway. if (fontSize < MinimumFontSizeInPixels) return; var fontArgs = new CreateFontArgs(annotationBox.Font, fontSize, style, GraphicsUnit.Pixel) { DefaultFontName = AnnotationBox.DefaultFont }; var font = gdiObjectFactory.CreateFont(fontArgs); var format = gdiObjectFactory.CreateStringFormat(new CreateStringFormatArgs(annotationBox)); var layoutArea = new SizeF(clientRectangle.Width, clientRectangle.Height); var size = buffer.Graphics.MeasureString(annotationText, font, layoutArea, format); if (annotationBox.FitWidth && size.Width > clientRectangle.Width) { fontSize = (int) (Math.Round(fontSize*clientRectangle.Width/(double) size.Width - 0.5)); //don't draw it if it's too small to read, anyway. if (fontSize < MinimumFontSizeInPixels) return; font = gdiObjectFactory.CreateFont(fontArgs); } // Draw drop shadow var brush = gdiObjectFactory.CreateBrush(new CreateBrushArgs(Color.Black)); clientRectangle.Offset(1, 1); buffer.Graphics.DrawString( annotationText, font, brush, clientRectangle, format); brush = gdiObjectFactory.CreateBrush(new CreateBrushArgs(annotationBox.Color)); clientRectangle.Offset(-1, -1); buffer.Graphics.DrawString( annotationText, font, brush, clientRectangle, format); }
/// <summary> /// Draws a spline primitive to the specified destination buffer. /// </summary> /// <param name="buffer">The destination buffer.</param> /// <param name="pen">A GDI pen to use for drawing.</param> /// <param name="spline">The spline primitive to be drawn.</param> /// <param name="dpi">The intended output DPI.</param> public static void DrawSplinePrimitive(IGdiBuffer buffer, Pen pen, SplinePrimitive spline, float dpi = _nominalScreenDpi) { buffer.Graphics.Transform = spline.SpatialTransform.CumulativeTransform; spline.CoordinateSystem = CoordinateSystem.Source; buffer.Graphics.SmoothingMode = SmoothingMode.AntiAlias; try { // Draw drop shadow pen.Color = Color.Black; pen.Width = CalculateScaledPenWidth(spline, 1, dpi); SetDashStyle(pen, spline); var dropShadowOffset = GetDropShadowOffset(spline, dpi); var pathPoints = GetCurvePoints(spline.Points, dropShadowOffset); if (spline.Points.IsClosed) buffer.Graphics.DrawClosedCurve(pen, pathPoints); else buffer.Graphics.DrawCurve(pen, pathPoints); // Draw line pen.Color = spline.Color; pathPoints = GetCurvePoints(spline.Points, SizeF.Empty); if (spline.Points.IsClosed) buffer.Graphics.DrawClosedCurve(pen, pathPoints); else buffer.Graphics.DrawCurve(pen, pathPoints); } finally { buffer.Graphics.SmoothingMode = SmoothingMode.None; spline.ResetCoordinateSystem(); buffer.Graphics.ResetTransform(); } }