1 //-------------------------------------------------------------
2 // <copyright company=
\92Microsoft Corporation
\92>
3 // Copyright © Microsoft Corporation. All Rights Reserved.
5 //-------------------------------------------------------------
6 // @owner=alexgor, deliant
7 //=================================================================
8 // File: ChartRenderingEngine.cs
10 // Namespace: System.Web.UI.WebControls[Windows.Forms].Charting
12 // Classes: ChartRenderingEngine, ValueA, PointA, RectangleA,
15 // Purpose: ChartRenderingEngine class provides a common interface
16 // to the graphics rendering and animation engines.
17 // Internally it uses SvgChartGraphics, FlashGraphics or
18 // GdiGraphics classes depending on the ActiveRenderingType
21 // ValueA, PointA, RectangleA and ColorA classes are
22 // used to store data about animated values like colors
23 // position or rectangles. They store starting value/time,
24 // end value/time, repeat flags and other settings. These
25 // clases are used with animation engines.
27 // Reviwed: AG - Jul 15, 2003
28 // AG - Microsoft 16, 2007
30 //===================================================================
33 #region Used namespaces
37 using System.Drawing.Drawing2D;
38 using System.Drawing.Text;
39 using System.Drawing.Imaging;
40 using System.ComponentModel;
41 using System.Collections;
44 using System.Diagnostics.CodeAnalysis;
48 using System.Windows.Forms.DataVisualization.Charting.Utilities;
49 using System.Windows.Forms.DataVisualization.Charting.Borders3D;
51 using System.Web.UI.DataVisualization.Charting.Utilities;
52 using System.Web.UI.DataVisualization.Charting.Borders3D;
59 namespace System.Windows.Forms.DataVisualization.Charting
61 namespace System.Web.UI.DataVisualization.Charting
68 /// Specify Rendering AxisName
70 internal enum RenderingType
75 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gdi")]
81 [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Svg")]
85 #endregion // Enumerations
88 /// The ChartGraphics class provides a common interface to the
89 /// graphics rendering.
92 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
93 [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
95 public partial class ChartGraphics
99 // Current rendering type
100 private RenderingType _activeRenderingType = RenderingType.Gdi;
102 // GDI+ rendering engine
103 private GdiGraphics _gdiGraphics = new GdiGraphics();
105 // Document title used for SVG rendering
106 //private string documentTitle = string.Empty;
108 // True if text should be clipped
109 internal bool IsTextClipped = false;
113 #region Drawing Methods
116 /// Draws a line connecting two PointF structures.
118 /// <param name="pen">Pen object that determines the color, width, and style of the line.</param>
119 /// <param name="pt1">PointF structure that represents the first point to connect.</param>
120 /// <param name="pt2">PointF structure that represents the second point to connect.</param>
121 internal void DrawLine(
127 RenderingObject.DrawLine( pen, pt1, pt2 );
131 /// Draws a line connecting the two points specified by coordinate pairs.
133 /// <param name="pen">Pen object that determines the color, width, and style of the line.</param>
134 /// <param name="x1">x-coordinate of the first point.</param>
135 /// <param name="y1">y-coordinate of the first point.</param>
136 /// <param name="x2">x-coordinate of the second point.</param>
137 /// <param name="y2">y-coordinate of the second point.</param>
138 internal void DrawLine(
146 RenderingObject.DrawLine( pen, x1, y1, x2, y2 );
150 /// Draws the specified portion of the specified Image object at the specified location and with the specified size.
152 /// <param name="image">Image object to draw.</param>
153 /// <param name="destRect">Rectangle structure that specifies the location and size of the drawn image. The image is scaled to fit the rectangle.</param>
154 /// <param name="srcX">x-coordinate of the upper-left corner of the portion of the source image to draw.</param>
155 /// <param name="srcY">y-coordinate of the upper-left corner of the portion of the source image to draw.</param>
156 /// <param name="srcWidth">Width of the portion of the source image to draw.</param>
157 /// <param name="srcHeight">Height of the portion of the source image to draw.</param>
158 /// <param name="srcUnit">Member of the GraphicsUnit enumeration that specifies the units of measure used to determine the source rectangle.</param>
159 /// <param name="imageAttr">ImageAttributes object that specifies recoloring and gamma information for the image object.</param>
160 internal void DrawImage(
161 System.Drawing.Image image,
167 GraphicsUnit srcUnit,
168 ImageAttributes imageAttr
171 RenderingObject.DrawImage(
184 /// Draws an ellipse defined by a bounding rectangle specified by
185 /// a pair of coordinates, a height, and a width.
187 /// <param name="pen">Pen object that determines the color, width, and style of the ellipse.</param>
188 /// <param name="x">x-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse.</param>
189 /// <param name="y">y-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse.</param>
190 /// <param name="width">Width of the bounding rectangle that defines the ellipse.</param>
191 /// <param name="height">Height of the bounding rectangle that defines the ellipse.</param>
192 internal void DrawEllipse(
200 RenderingObject.DrawEllipse( pen, x, y, width, height );
204 /// Draws a cardinal spline through a specified array of PointF structures
205 /// using a specified tension. The drawing begins offset from
206 /// the beginning of the array.
208 /// <param name="pen">Pen object that determines the color, width, and height of the curve.</param>
209 /// <param name="points">Array of PointF structures that define the spline.</param>
210 /// <param name="offset">Offset from the first element in the array of the points parameter to the starting point in the curve.</param>
211 /// <param name="numberOfSegments">Number of segments after the starting point to include in the curve.</param>
212 /// <param name="tension">Value greater than or equal to 0.0F that specifies the tension of the curve.</param>
213 internal void DrawCurve(
217 int numberOfSegments,
221 ChartGraphics chartGraphics = this as ChartGraphics;
222 if (chartGraphics == null || !chartGraphics.IsMetafile)
224 RenderingObject.DrawCurve(pen, points, offset, numberOfSegments, tension);
228 // Special handling required for the metafiles. We cannot pass large array of
229 // points because they will be persisted inside EMF file and cause exponential
230 // increase in emf file size. Draw curve method uses additional 2, 3 or 4 points
231 // depending on which segement is drawn.
232 PointF[] pointsExact = null;
233 if (offset == 0 && numberOfSegments == points.Length - 1)
235 // In case the array contains the minimum required number of points
236 // to draw segments - just call the curve drawing method
237 RenderingObject.DrawCurve(pen, points, offset, numberOfSegments, tension);
241 if (offset == 0 && numberOfSegments < points.Length - 1)
243 // Segment is at the beginning of the array with more points following
244 pointsExact = new PointF[numberOfSegments + 2];
245 for (int index = 0; index < numberOfSegments + 2; index++)
247 pointsExact[index] = points[index];
250 else if (offset > 0 && (offset + numberOfSegments) == points.Length - 1)
252 // Segment is at the end of the array with more points prior to it
253 pointsExact = new PointF[numberOfSegments + 2];
254 for (int index = 0; index < numberOfSegments + 2; index++)
256 pointsExact[index] = points[offset + index - 1];
260 else if (offset > 0 && (offset + numberOfSegments) < points.Length - 1)
262 // Segment in the middle of the array with points prior and following it
263 pointsExact = new PointF[numberOfSegments + 3];
264 for (int index = 0; index < numberOfSegments + 3; index++)
266 pointsExact[index] = points[offset + index - 1];
271 // Render the curve using minimum number of required points in the array
272 RenderingObject.DrawCurve(pen, pointsExact, offset, numberOfSegments, tension);
278 /// Draws a rectangle specified by a coordinate pair, a width, and a height.
280 /// <param name="pen">Pen object that determines the color, width, and style of the rectangle.</param>
281 /// <param name="x">x-coordinate of the upper-left corner of the rectangle to draw.</param>
282 /// <param name="y">y-coordinate of the upper-left corner of the rectangle to draw.</param>
283 /// <param name="width">Width of the rectangle to draw.</param>
284 /// <param name="height">Height of the rectangle to draw.</param>
285 internal void DrawRectangle(
293 RenderingObject.DrawRectangle( pen, x, y, width, height );
297 /// Draws a polygon defined by an array of PointF structures.
299 /// <param name="pen">Pen object that determines the color, width, and style of the polygon.</param>
300 /// <param name="points">Array of PointF structures that represent the vertices of the polygon.</param>
301 internal void DrawPolygon(
306 RenderingObject.DrawPolygon( pen, points );
310 /// Draws the specified text string in the specified rectangle with the specified Brush and Font objects using the formatting properties of the specified StringFormat object.
312 /// <param name="s">String to draw.</param>
313 /// <param name="font">Font object that defines the text format of the string.</param>
314 /// <param name="brush">Brush object that determines the color and texture of the drawn text.</param>
315 /// <param name="layoutRectangle">RectangleF structure that specifies the location of the drawn text.</param>
316 /// <param name="format">StringFormat object that specifies formatting properties, such as line spacing and alignment, that are applied to the drawn text.</param>
317 internal void DrawString(
321 RectangleF layoutRectangle,
325 using (StringFormat fmt = (StringFormat)format.Clone())
328 fmt.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
329 if (!IsTextClipped && (fmt.FormatFlags & StringFormatFlags.NoClip) != StringFormatFlags.NoClip)
330 fmt.FormatFlags |= StringFormatFlags.NoClip;
331 RenderingObject.DrawString(s, font, brush, layoutRectangle, fmt);
336 /// Draws the specified text string at the specified location with the specified Brush and Font objects using the formatting properties of the specified StringFormat object.
338 /// <param name="s">String to draw.</param>
339 /// <param name="font">Font object that defines the text format of the string.</param>
340 /// <param name="brush">Brush object that determines the color and texture of the drawn text.</param>
341 /// <param name="point">PointF structure that specifies the upper-left corner of the drawn text.</param>
342 /// <param name="format">StringFormat object that specifies formatting properties, such as line spacing and alignment, that are applied to the drawn text.</param>
343 internal void DrawString(
353 using (StringFormat fmt = (StringFormat)format.Clone())
355 fmt.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
356 if (fmt.Alignment == StringAlignment.Far)
358 fmt.Alignment = StringAlignment.Near;
360 else if (fmt.Alignment == StringAlignment.Near)
362 fmt.Alignment = StringAlignment.Far;
364 RenderingObject.DrawString(s, font, brush, point, fmt);
368 RenderingObject.DrawString(s, font, brush, point, format);
372 /// Draws the specified portion of the specified Image object at the specified location and with the specified size.
374 /// <param name="image">Image object to draw.</param>
375 /// <param name="destRect">Rectangle structure that specifies the location and size of the drawn image. The image is scaled to fit the rectangle.</param>
376 /// <param name="srcX">x-coordinate of the upper-left corner of the portion of the source image to draw.</param>
377 /// <param name="srcY">y-coordinate of the upper-left corner of the portion of the source image to draw.</param>
378 /// <param name="srcWidth">Width of the portion of the source image to draw.</param>
379 /// <param name="srcHeight">Height of the portion of the source image to draw.</param>
380 /// <param name="srcUnit">Member of the GraphicsUnit enumeration that specifies the units of measure used to determine the source rectangle.</param>
381 /// <param name="imageAttrs">ImageAttributes object that specifies recoloring and gamma information for the image object.</param>
382 internal void DrawImage(
383 System.Drawing.Image image,
389 GraphicsUnit srcUnit,
390 ImageAttributes imageAttrs
393 RenderingObject.DrawImage( image, destRect, srcX, srcY, srcWidth, srcHeight, srcUnit, imageAttrs );
397 /// Draws a rectangle specified by a coordinate pair, a width, and a height.
399 /// <param name="pen">A Pen object that determines the color, width, and style of the rectangle.</param>
400 /// <param name="x">The x-coordinate of the upper-left corner of the rectangle to draw.</param>
401 /// <param name="y">The y-coordinate of the upper-left corner of the rectangle to draw.</param>
402 /// <param name="width">The width of the rectangle to draw.</param>
403 /// <param name="height">The height of the rectangle to draw.</param>
404 internal void DrawRectangle(
412 RenderingObject.DrawRectangle( pen, x, y, width, height );
416 /// Draws a GraphicsPath object.
418 /// <param name="pen">Pen object that determines the color, width, and style of the path.</param>
419 /// <param name="path">GraphicsPath object to draw.</param>
420 internal void DrawPath(
425 // Check if path is empty
427 path.PointCount == 0)
432 RenderingObject.DrawPath( pen, path );
436 /// Draws a pie shape defined by an ellipse specified by a coordinate pair, a width, and a height and two radial lines.
438 /// <param name="pen">Pen object that determines the color, width, and style of the pie shape.</param>
439 /// <param name="x">x-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse from which the pie shape comes.</param>
440 /// <param name="y">y-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse from which the pie shape comes.</param>
441 /// <param name="width">Width of the bounding rectangle that defines the ellipse from which the pie shape comes.</param>
442 /// <param name="height">Height of the bounding rectangle that defines the ellipse from which the pie shape comes.</param>
443 /// <param name="startAngle">Angle measured in degrees clockwise from the x-axis to the first side of the pie shape.</param>
444 /// <param name="sweepAngle">Angle measured in degrees clockwise from the startAngle parameter to the second side of the pie shape.</param>
445 internal void DrawPie(
455 RenderingObject.DrawPie( pen, x, y, width, height, startAngle, sweepAngle );
459 /// Draws an ellipse defined by a bounding RectangleF.
461 /// <param name="pen">Pen object that determines the color, width, and style of the ellipse.</param>
462 /// <param name="rect">RectangleF structure that defines the boundaries of the ellipse.</param>
463 internal void DrawEllipse(
468 RenderingObject.DrawEllipse( pen, rect );
472 /// Draws a series of line segments that connect an array of PointF structures.
474 /// <param name="pen">Pen object that determines the color, width, and style of the line segments.</param>
475 /// <param name="points">Array of PointF structures that represent the points to connect.</param>
476 internal void DrawLines(
481 RenderingObject.DrawLines( pen, points );
484 #endregion // Drawing Methods
486 #region Filling Methods
489 /// Fills the interior of an ellipse defined by a bounding rectangle
490 /// specified by a RectangleF structure.
492 /// <param name="brush">Brush object that determines the characteristics of the fill.</param>
493 /// <param name="rect">RectangleF structure that represents the bounding rectangle that defines the ellipse.</param>
494 internal void FillEllipse(
499 RenderingObject.FillEllipse( brush, rect );
503 /// Fills the interior of a GraphicsPath object.
505 /// <param name="brush">Brush object that determines the characteristics of the fill.</param>
506 /// <param name="path">GraphicsPath object that represents the path to fill.</param>
507 internal void FillPath(
512 // Check if path is empty
514 path.PointCount == 0)
519 RenderingObject.FillPath( brush, path );
523 /// Fills the interior of a Region object.
525 /// <param name="brush">Brush object that determines the characteristics of the fill.</param>
526 /// <param name="region">Region object that represents the area to fill.</param>
527 internal void FillRegion(
532 RenderingObject.FillRegion( brush, region );
536 /// Fills the interior of a rectangle specified by a RectangleF structure.
538 /// <param name="brush">Brush object that determines the characteristics of the fill.</param>
539 /// <param name="rect">RectangleF structure that represents the rectangle to fill.</param>
540 internal void FillRectangle(
545 RenderingObject.FillRectangle( brush, rect );
549 /// Fills the interior of a rectangle specified by a pair of coordinates, a width, and a height.
551 /// <param name="brush">Brush object that determines the characteristics of the fill.</param>
552 /// <param name="x">x-coordinate of the upper-left corner of the rectangle to fill.</param>
553 /// <param name="y">y-coordinate of the upper-left corner of the rectangle to fill.</param>
554 /// <param name="width">Width of the rectangle to fill.</param>
555 /// <param name="height">Height of the rectangle to fill.</param>
556 internal void FillRectangle(
564 RenderingObject.FillRectangle( brush, x, y, width, height );
568 /// Fills the interior of a polygon defined by an array of points specified by PointF structures .
570 /// <param name="brush">Brush object that determines the characteristics of the fill.</param>
571 /// <param name="points">Array of PointF structures that represent the vertices of the polygon to fill.</param>
572 internal void FillPolygon(
577 RenderingObject.FillPolygon( brush, points );
581 /// Fills the interior of a pie section defined by an ellipse
582 /// specified by a pair of coordinates, a width, and a height
583 /// and two radial lines.
585 /// <param name="brush">Brush object that determines the characteristics of the fill.</param>
586 /// <param name="x">x-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse from which the pie section comes.</param>
587 /// <param name="y">y-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse from which the pie section comes.</param>
588 /// <param name="width">Width of the bounding rectangle that defines the ellipse from which the pie section comes.</param>
589 /// <param name="height">Height of the bounding rectangle that defines the ellipse from which the pie section comes.</param>
590 /// <param name="startAngle">Angle in degrees measured clockwise from the x-axis to the first side of the pie section.</param>
591 /// <param name="sweepAngle">Angle in degrees measured clockwise from the startAngle parameter to the second side of the pie section.</param>
592 internal void FillPie(
602 RenderingObject.FillPie( brush, x, y, width, height, startAngle, sweepAngle );
605 #endregion // Filling Methods
607 #region Other Methods
610 /// This method starts SVG Selection mode
612 /// <param name="url">The location of the referenced object, expressed as a URI reference.</param>
613 /// <param name="title">Title which could be used for tooltips.</param>
614 internal void StartHotRegion( string url, string title )
616 RenderingObject.BeginSelection( url, title );
620 /// This method starts SVG Selection mode
622 /// <param name="point">Data Point which properties are used for SVG selection</param>
623 internal void StartHotRegion(DataPoint point)
625 StartHotRegion( point, false );
629 /// This method starts SVG Selection mode
631 /// <param name="point">Data Point which properties are used for SVG selection</param>
632 /// <param name="labelRegion">Indicates if point label region is processed.</param>
633 internal void StartHotRegion(DataPoint point, bool labelRegion)
635 string hRef = string.Empty;
636 string tooltip = (labelRegion) ? point.LabelToolTip : point.ToolTip;
637 #if !Microsoft_CONTROL
638 hRef = (labelRegion) ? point.LabelUrl : point.Url;
640 if(hRef.Length > 0 || tooltip.Length > 0)
642 RenderingObject.BeginSelection(
643 point.ReplaceKeywords( hRef ),
644 point.ReplaceKeywords( tooltip ) );
649 /// This method stops SVG Selection mode
651 internal void EndHotRegion()
653 RenderingObject.EndSelection();
657 /// Measures the specified string when drawn with the specified
658 /// Font object and formatted with the specified StringFormat object.
660 /// <param name="text">String to measure.</param>
661 /// <param name="font">Font object defines the text format of the string.</param>
662 /// <param name="layoutArea">SizeF structure that specifies the maximum layout area for the text.</param>
663 /// <param name="stringFormat">StringFormat object that represents formatting information, such as line spacing, for the string.</param>
664 /// <returns>This method returns a SizeF structure that represents the size, in pixels, of the string specified in the text parameter as drawn with the font parameter and the stringFormat parameter.</returns>
665 internal SizeF MeasureString(
669 StringFormat stringFormat
672 return RenderingObject.MeasureString( text, font, layoutArea, stringFormat );
676 /// Measures the specified string when drawn with the specified
677 /// Font object and formatted with the specified StringFormat object.
679 /// <param name="text">String to measure.</param>
680 /// <param name="font">Font object defines the text format of the string.</param>
681 /// <returns>This method returns a SizeF structure that represents the size, in pixels, of the string specified in the text parameter as drawn with the font parameter and the stringFormat parameter.</returns>
682 internal SizeF MeasureString(
687 return RenderingObject.MeasureString( text, font );
691 /// Saves the current state of this Graphics object and identifies the saved state with a GraphicsState object.
693 /// <returns>This method returns a GraphicsState object that represents the saved state of this Graphics object.</returns>
694 internal GraphicsState Save()
696 return RenderingObject.Save();
700 /// Restores the state of this Graphics object to the state represented by a GraphicsState object.
702 /// <param name="gstate">GraphicsState object that represents the state to which to restore this Graphics object.</param>
703 internal void Restore(
707 RenderingObject.Restore( gstate );
711 /// Resets the clip region of this Graphics object to an infinite region.
713 internal void ResetClip()
715 RenderingObject.ResetClip();
719 /// Sets the clipping region of this Graphics object to the rectangle specified by a RectangleF structure.
721 /// <param name="rect">RectangleF structure that represents the new clip region.</param>
722 internal void SetClipAbs(RectangleF rect)
724 RenderingObject.SetClip( rect );
728 /// Prepends the specified translation to the transformation matrix of this Graphics object.
730 /// <param name="dx">x component of the translation.</param>
731 /// <param name="dy">y component of the translation.</param>
732 internal void TranslateTransform(
737 RenderingObject.TranslateTransform( dx, dy );
740 #endregion // Other Methods
745 /// Gets current rendering object.
747 internal IChartRenderingEngine RenderingObject
756 /// Gets the active rendering type.
758 internal RenderingType ActiveRenderingType
762 return _activeRenderingType;
767 /// Gets or sets the rendering mode for text associated with this Graphics object.
769 internal TextRenderingHint TextRenderingHint
773 return RenderingObject.TextRenderingHint;
777 RenderingObject.TextRenderingHint = value;
782 /// Gets or sets the world transformation for this Graphics object.
784 internal Matrix Transform
788 return RenderingObject.Transform;
792 RenderingObject.Transform = value;
797 /// Gets or sets the rendering quality for this Graphics object.
799 internal SmoothingMode SmoothingMode
803 return RenderingObject.SmoothingMode;
807 RenderingObject.SmoothingMode = value;
812 /// Gets or sets a Region object that limits the drawing region of this Graphics object.
818 return RenderingObject.Clip;
822 RenderingObject.Clip = value;
827 /// Gets a value indicating whether the clipping region of this Graphics object is empty.
829 internal bool IsClipEmpty {
832 return RenderingObject.IsClipEmpty;
837 /// Gets or sets the reference to the Graphics object.
839 public Graphics Graphics
843 return RenderingObject.Graphics;
847 RenderingObject.Graphics = value;
851 #endregion // Properties