/// <summary> /// Dispose method. Inheritors should override this method to do any additional cleanup. /// </summary> protected override void Dispose(bool disposing) { base.Dispose(disposing); if (disposing) { if (_pen != null) { _pen.Dispose(); _pen = null; } if (_brush != null) { _brush.Dispose(); _brush = null; } if (_fontFactory != null) { _fontFactory.Dispose(); _fontFactory = null; } } }
/// <summary> /// Default constructor. /// </summary> public GdiRenderer() { _pen = new Pen(Color.White); _brush = new SolidBrush(Color.Black); _fontFactory = new FontFactory(); }
/// <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); } }
/// <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); } }