/// <summary> /// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="SvgRenderer"/> object. /// </summary> /// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param> protected override void Render(SvgRenderer renderer) { // Do nothing }
/// <summary> /// Renders the children of this <see cref="SvgElement"/>. /// </summary> /// <param name="renderer">The <see cref="SvgRenderer"/> to render the child <see cref="SvgElement"/>s to.</param> protected virtual void RenderChildren(SvgRenderer renderer) { foreach (SvgElement element in this.Children) { element.Render(renderer); } }
/// <summary> /// Gets a <see cref="Brush"/> representing the current paint server. /// </summary> /// <param name="styleOwner">The owner <see cref="SvgVisualElement"/>.</param> /// <param name="opacity">The opacity of the brush.</param> public abstract Brush GetBrush(SvgVisualElement styleOwner, SvgRenderer renderer, float opacity);
/// <summary> /// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="SvgRenderer"/> object. /// </summary> /// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param> protected virtual void Render(SvgRenderer renderer) { this.PushTransforms(renderer); this.RenderChildren(renderer); this.PopTransforms(renderer); }
public static System.Drawing.PointF GetDevicePointOffset(SvgUnit x, SvgUnit y, SvgRenderer renderer, SvgElement owner) { return new System.Drawing.PointF(x.ToDeviceValue(renderer, UnitRenderingType.HorizontalOffset, owner), y.ToDeviceValue(renderer, UnitRenderingType.VerticalOffset, owner)); }
/// <summary> /// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="SvgRenderer"/> object. /// </summary> /// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param> protected override void Render(SvgRenderer renderer) { // Never render paint servers or their children }
/// <summary> /// Initializes the <see cref="SvgText"/> class. /// </summary> static SvgText() { Bitmap bitmap = new Bitmap(1, 1); _stringMeasure = SvgRenderer.FromImage(bitmap); _stringMeasure.TextRenderingHint = TextRenderingHint.AntiAlias; }
/// <summary> /// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object. /// </summary> protected override void Render(SvgRenderer renderer) { if (Width.Value > 0.0f && Height.Value > 0.0f) { base.Render(renderer); } }
/// <summary> /// Creates a new <see cref="SvgRenderer"/> from the specified <see cref="Image"/>. /// </summary> /// <param name="image"><see cref="Image"/> from which to create the new <see cref="SvgRenderer"/>.</param> public static SvgRenderer FromImage(Image image) { SvgRenderer renderer = new SvgRenderer(); renderer._innerGraphics = Graphics.FromImage(image); return renderer; }
/// <summary> /// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="SvgRenderer"/> object. /// </summary> /// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param> protected override void Render(SvgRenderer renderer) { // Do nothing. Children should NOT be rendered. }
public PointF ToDeviceValue(SvgRenderer renderer, SvgElement owner) { return SvgUnit.GetDevicePoint(this.X, this.Y, renderer, owner); }
/// <summary> /// Applies the required transforms to <see cref="SvgRenderer"/>. /// </summary> /// <param name="renderer">The <see cref="SvgRenderer"/> to be transformed.</param> protected internal override void PushTransforms(SvgRenderer renderer) { base.PushTransforms(renderer); renderer.TranslateTransform(this.X.ToDeviceValue(this), this.Y.ToDeviceValue(this, true)); }
/// <summary> /// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object. /// </summary> /// <param name="graphics">The <see cref="SvgRenderer"/> object to render to.</param> protected override void Render(SvgRenderer renderer) { if (this.Path != null && this.Visible) { this.PushTransforms(renderer); this.SetClip(renderer); // If this element needs smoothing enabled turn anti-aliasing on if (this.RequiresSmoothRendering) { renderer.SmoothingMode = SmoothingMode.AntiAlias; } this.RenderFill(renderer); this.RenderStroke(renderer); // Reset the smoothing mode if (this.RequiresSmoothRendering && renderer.SmoothingMode == SmoothingMode.AntiAlias) { renderer.SmoothingMode = SmoothingMode.Default; } this.ResetClip(renderer); this.PopTransforms(renderer); } }
public override GraphicsPath Path(SvgRenderer renderer) { if (_Path == null || this.IsPathDirty) { _Path = new GraphicsPath(); try { for (int i = 0; i < Points.Count; i += 2) { PointF endPoint = new PointF(Points[i].ToDeviceValue(renderer, UnitRenderingType.Horizontal, this), Points[i + 1].ToDeviceValue(renderer, UnitRenderingType.Vertical, this)); // TODO: Remove unrequired first line if (_Path.PointCount == 0) { _Path.AddLine(endPoint, endPoint); } else { _Path.AddLine(_Path.GetLastPoint(), endPoint); } } } catch (Exception exc) { Trace.TraceError("Error rendering points: " + exc.Message); } this.IsPathDirty = false; } return _Path; }
/// <summary> /// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object. /// </summary> /// <param name="graphics">The <see cref="Graphics"/> object to render to.</param> protected override void Render(SvgRenderer renderer) { this.PushTransforms(renderer); this.SetClip(renderer); base.RenderChildren(renderer); this.ResetClip(renderer); this.PopTransforms(renderer); }
/// <summary> /// Renders the fill of the <see cref="SvgVisualElement"/> to the specified <see cref="SvgRenderer"/> /// </summary> /// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param> protected internal virtual void RenderFill(SvgRenderer renderer) { if (this.Fill != null) { using (Brush brush = this.Fill.GetBrush(this, this.FillOpacity)) { if (brush != null) { this.Path.FillMode = this.FillRule == SvgFillRule.NonZero ? FillMode.Winding : FillMode.Alternate; renderer.FillPath(brush, this.Path); } } } }
/// <summary> /// Applies the required transforms to <see cref="SvgRenderer"/>. /// </summary> /// <param name="renderer">The <see cref="SvgRenderer"/> to be transformed.</param> protected internal override void PushTransforms(SvgRenderer renderer) { base.PushTransforms(renderer); if (!this.ViewBox.Equals(SvgViewBox.Empty)) { if (this.ViewBox.MinX > 0 || this.ViewBox.MinY > 0) { renderer.TranslateTransform(this.ViewBox.MinX, this.ViewBox.MinY, MatrixOrder.Append); } renderer.ScaleTransform(this.Width.ToDeviceValue() / this.ViewBox.Width, this.Height.ToDeviceValue() / this.ViewBox.Height, MatrixOrder.Append); } }
protected override void Render(SvgRenderer renderer) { this.PushTransforms(renderer); SvgVisualElement element = (SvgVisualElement)this.OwnerDocument.IdManager.GetElementById(this.ReferencedElement); // For the time of rendering we want the referenced element to inherit // this elements transforms SvgElement parent = element._parent; element._parent = this; element.RenderElement(renderer); element._parent = parent; this.PopTransforms(renderer); }
public override Brush GetBrush(SvgVisualElement styleOwner, SvgRenderer renderer, float opacity) { //is none? if (this == SvgPaintServer.None) { return(new SolidBrush(Color.Transparent)); } int alpha = (int)((opacity * (this.Colour.A / 255.0f)) * 255); Color colour = Color.FromArgb(alpha, this.Colour); return(new SolidBrush(colour)); }
/// <summary> /// Gets the <see cref="GraphicsPath"/> for this element. /// </summary> public override GraphicsPath Path(SvgRenderer renderer) { if (this._path == null || this.IsPathDirty) { _path = new GraphicsPath(); foreach (SvgPathSegment segment in this.PathData) { segment.AddToPath(_path); } this.IsPathDirty = false; } return(_path); }
/// <summary> /// Renders the <see cref="SvgDocument"/> into a given Bitmap <see cref="Bitmap"/>. /// </summary> public virtual void Draw(Bitmap bitmap) { //Trace.TraceInformation("Begin Render"); using (var renderer = SvgRenderer.FromImage(bitmap)) { // EO, 2014-12-05: Requested to ensure proper zooming out (reduce size). Otherwise it clip the image. this.Overflow = SvgOverflow.Auto; var boundable = new GenericBoundable(0, 0, bitmap.Width, bitmap.Height); this.Draw(renderer, boundable); } //Trace.TraceInformation("End Render"); }
// public override SvgElementCollection Children // { // get // { // SvgElement element = this.OwnerDocument.IdManager.GetElementById(this.ReferencedElement); // SvgElementCollection elements = new SvgElementCollection(this, true); // elements.Add(element); // return elements; // } // } protected override void Render(SvgRenderer renderer) { this.PushTransforms(renderer); SvgVisualElement element = (SvgVisualElement)this.OwnerDocument.IdManager.GetElementById(this.ReferencedElement); // For the time of rendering we want the referenced element to inherit // this elements transforms SvgElement parent = element._parent; element._parent = this; element.RenderElement(renderer); element._parent = parent; this.PopTransforms(renderer); }
/// <summary> /// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object. /// </summary> /// <param name="graphics">The <see cref="Graphics"/> object to render to.</param> protected override void Render(SvgRenderer renderer) { if (!Visible || !Displayable) { return; } if (this.PushTransforms(renderer)) { this.SetClip(renderer); base.RenderChildren(renderer); this.ResetClip(renderer); this.PopTransforms(renderer); } }
public override System.Drawing.Drawing2D.GraphicsPath Path(SvgRenderer renderer) { if (this._path == null || this.IsPathDirty) { PointF start = new PointF(this.StartX.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this), this.StartY.ToDeviceValue(renderer, UnitRenderingType.Vertical, this)); PointF end = new PointF(this.EndX.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this), this.EndY.ToDeviceValue(renderer, UnitRenderingType.Vertical, this)); this._path = new GraphicsPath(); this._path.AddLine(start, end); this.IsPathDirty = false; } return(this._path); }
/// <summary> /// Gets the <see cref="GraphicsPath"/> for this element. /// </summary> /// <value></value> public override GraphicsPath Path(SvgRenderer renderer) { if (this._path == null || this.IsPathDirty) { var center = SvgUnit.GetDevicePoint(this._centerX, this._centerY, renderer, this); var radius = SvgUnit.GetDevicePoint(this._radiusX, this._radiusY, renderer, this); this._path = new GraphicsPath(); _path.StartFigure(); _path.AddEllipse(center.X - radius.X, center.Y - radius.Y, 2 * radius.X, 2 * radius.Y); _path.CloseFigure(); this.IsPathDirty = false; } return(_path); }
/// <summary> /// Renders the <see cref="SvgDocument"/> into a given Bitmap <see cref="Bitmap"/>. /// </summary> public virtual void Draw(Bitmap bitmap) { //Trace.TraceInformation("Begin Render"); using (var renderer = SvgRenderer.FromImage(bitmap)) { renderer.TextRenderingHint = TextRenderingHint.AntiAlias; renderer.TextContrast = 1; renderer.PixelOffsetMode = PixelOffsetMode.Half; this.Render(renderer); renderer.Save(); } //Trace.TraceInformation("End Render"); }
/// <summary> /// Create a pen that can be used to render this marker /// </summary> /// <param name="pStroke"></param> /// <returns></returns> private Pen CreatePen(SvgPath pPath, SvgRenderer renderer) { Brush pBrush = pPath.Stroke.GetBrush(this, renderer, Opacity); switch (MarkerUnits) { case SvgMarkerUnits.strokeWidth: return(new Pen(pBrush, StrokeWidth.ToDeviceValue(renderer, UnitRenderingType.Other, this) * pPath.StrokeWidth.ToDeviceValue(renderer, UnitRenderingType.Other, this))); case SvgMarkerUnits.userSpaceOnUse: return(new Pen(pBrush, StrokeWidth.ToDeviceValue(renderer, UnitRenderingType.Other, this))); } return(new Pen(pBrush, StrokeWidth.ToDeviceValue(renderer, UnitRenderingType.Other, this))); }
/// <summary> /// Common code for rendering a marker once the orientation angle has been calculated /// </summary> /// <param name="fAngle"></param> /// <param name="pRenderer"></param> /// <param name="pOwner"></param> /// <param name="pMarkerPoint"></param> private void RenderPart2(float fAngle, SvgRenderer pRenderer, SvgPath pOwner, PointF pMarkerPoint) { Pen pRenderPen = CreatePen(pOwner, pRenderer); GraphicsPath markerPath = GetClone(pOwner); Matrix transMatrix = new Matrix(); transMatrix.Translate(pMarkerPoint.X, pMarkerPoint.Y); if (Orient.IsAuto) { transMatrix.Rotate(fAngle); } else { transMatrix.Rotate(Orient.Angle); } switch (MarkerUnits) { case SvgMarkerUnits.strokeWidth: transMatrix.Translate(AdjustForViewBoxWidth(-RefX.ToDeviceValue(pRenderer, UnitRenderingType.Horizontal, this) * pOwner.StrokeWidth.ToDeviceValue(pRenderer, UnitRenderingType.Other, this)), AdjustForViewBoxHeight(-RefY.ToDeviceValue(pRenderer, UnitRenderingType.Vertical, this) * pOwner.StrokeWidth.ToDeviceValue(pRenderer, UnitRenderingType.Other, this))); break; case SvgMarkerUnits.userSpaceOnUse: transMatrix.Translate(-RefX.ToDeviceValue(pRenderer, UnitRenderingType.Horizontal, this), -RefY.ToDeviceValue(pRenderer, UnitRenderingType.Vertical, this)); break; } markerPath.Transform(transMatrix); pRenderer.DrawPath(pRenderPen, markerPath); SvgPaintServer pFill = Fill; SvgFillRule pFillRule = FillRule; // TODO: What do we use the fill rule for? float fOpacity = FillOpacity; if (pFill != null) { Brush pBrush = pFill.GetBrush(this, pRenderer, fOpacity); pRenderer.FillPath(pBrush, markerPath); pBrush.Dispose(); } pRenderPen.Dispose(); markerPath.Dispose(); transMatrix.Dispose(); }
private void Render(ISvgRenderer renderer, bool renderFilter) { if (this.Visible && this.Displayable && this.PushTransforms(renderer) && (!this.Renderable || this.Path(renderer) != null)) { if (!(renderFilter && this.RenderFilter(renderer))) { this.SetClip(renderer); if (this.Renderable) { var opacity = Math.Min(Math.Max(this.Opacity, 0), 1); if (opacity == 1f) { this.RenderFillAndStroke(renderer); } else { IsPathDirty = true; var bounds = this.Bounds; IsPathDirty = true; using (var canvas = new Bitmap((int)Math.Ceiling(bounds.Width), (int)Math.Ceiling(bounds.Height))) { using (var canvasRenderer = SvgRenderer.FromImage(canvas)) { canvasRenderer.SetBoundable(renderer.GetBoundable()); canvasRenderer.TranslateTransform(-bounds.X, -bounds.Y); this.RenderFillAndStroke(canvasRenderer); } var srcRect = new RectangleF(0f, 0f, bounds.Width, bounds.Height); renderer.DrawImage(canvas, bounds, srcRect, GraphicsUnit.Pixel, opacity); } } } else { base.RenderChildren(renderer); } this.ResetClip(renderer); this.PopTransforms(renderer); } } }
/// <summary> /// Renders the stroke of the <see cref="SvgVisualElement"/> to the specified <see cref="SvgRenderer"/> /// </summary> /// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param> protected internal virtual void RenderStroke(SvgRenderer renderer) { if (this.Stroke != null) { float strokeWidth = this.StrokeWidth.ToDeviceValue(this); using (var pen = new Pen(this.Stroke.GetBrush(this, this.StrokeOpacity), strokeWidth)) { if (this.StrokeDashArray != null && this.StrokeDashArray.Count > 0) { /* divide by stroke width - GDI behaviour that I don't quite understand yet.*/ pen.DashPattern = this.StrokeDashArray.ConvertAll(u => u.Value / ((strokeWidth <= 0) ? 1 : strokeWidth)).ToArray(); } renderer.DrawPath(pen, this.Path); } } }
/// <summary> /// Renders the <see cref="SvgDocument"/> in given size and returns the image as a <see cref="Bitmap"/>. /// If one of rasterWidth and rasterHeight is zero, the image is scaled preserving aspect ratio, /// otherwise the aspect ratio is ignored. /// </summary> /// <returns>A <see cref="Bitmap"/> containing the rendered document.</returns> public virtual Bitmap Draw(int rasterWidth, int rasterHeight) { var imageSize = GetDimensions(); var bitmapSize = imageSize; this.RasterizeDimensions(ref bitmapSize, rasterWidth, rasterHeight); if (bitmapSize.Width == 0 || bitmapSize.Height == 0) { return(null); } Bitmap bitmap = null; try { try { bitmap = new Bitmap((int)Math.Round(bitmapSize.Width), (int)Math.Round(bitmapSize.Height)); } catch (ArgumentException e) { // When processing too many files at one the system can run out of memory throw new SvgMemoryException("Cannot process SVG file, cannot allocate the required memory", e); } using (var renderer = SvgRenderer.FromImage(bitmap)) { renderer.ScaleTransform(bitmapSize.Width / imageSize.Width, bitmapSize.Height / imageSize.Height); var boundable = new GenericBoundable(0, 0, imageSize.Width, imageSize.Height); this.Draw(renderer, boundable); } } catch { if (bitmap != null) { bitmap.Dispose(); } throw; } return(bitmap); }
public override Brush GetBrush(SvgVisualElement owner, SvgRenderer renderer, float opacity) { // Need at least 2 colours to do the gradient fill if (this.Stops.Count < 2) { return(null); } PointF start; PointF end; RectangleF bounds = (this.GradientUnits == SvgCoordinateUnits.ObjectBoundingBox) ? owner.Bounds : owner.OwnerDocument.GetDimensions(); // Have start/end points been set? If not the gradient is horizontal if (!this.End.IsEmpty()) { // Get the points to work out an angle if (this.Start.IsEmpty()) { start = bounds.Location; } else { start = new PointF(this.Start.X.ToDeviceValue(owner), this.Start.Y.ToDeviceValue(owner, true)); } float x = (this.End.X.IsEmpty) ? start.X : this.End.X.ToDeviceValue(owner); end = new PointF(x, this.End.Y.ToDeviceValue(owner, true)); } else { // Default: horizontal start = bounds.Location; end = new PointF(bounds.Right, bounds.Top); } LinearGradientBrush gradient = new LinearGradientBrush(start, end, Color.Transparent, Color.Transparent); gradient.InterpolationColors = base.GetColourBlend(owner, opacity); // Needed to fix an issue where the gradient was being wrapped when though it had the correct bounds gradient.WrapMode = WrapMode.TileFlipX; return(gradient); }
private ColorBlend CalculateColorBlend(SvgRenderer renderer, float opacity, float specifiedRadius, float effectiveRadius) { var colorBlend = GetColorBlend(renderer, opacity, true); if (specifiedRadius >= effectiveRadius) { return(colorBlend); } for (var i = 0; i < colorBlend.Positions.Length - 1; i++) { colorBlend.Positions[i] = 1 - (specifiedRadius / effectiveRadius) * (1 - colorBlend.Positions[i]); } colorBlend.Positions = new[] { 0F }.Concat(colorBlend.Positions).ToArray(); colorBlend.Colors = new[] { colorBlend.Colors.First() }.Concat(colorBlend.Colors).ToArray(); return(colorBlend); }
/// <summary> /// Renders the <see cref="SvgDocument"/> into a given Bitmap <see cref="Bitmap"/>. /// </summary> public virtual void Draw(Bitmap bitmap) { //Trace.TraceInformation("Begin Render"); try { using (var renderer = SvgRenderer.FromImage(bitmap)) { renderer.SetBoundable(new GenericBoundable(0, 0, bitmap.Width, bitmap.Height)); this.Render(renderer); } } catch { throw; } //Trace.TraceInformation("End Render"); }
/// <summary> /// Renders the <see cref="SvgDocument"/> to the specified <see cref="Graphics"/>. /// </summary> /// <param name="graphics">The <see cref="Graphics"/> to be rendered to.</param> /// <param name="size">The <see cref="SizeF"/> to render the document. If <c>null</c> document is rendered at the default document size.</param> /// <exception cref="ArgumentNullException">The <paramref name="graphics"/> parameter cannot be <c>null</c>.</exception> public void Draw(Graphics graphics, SizeF?size) { if (graphics == null) { throw new ArgumentNullException("graphics"); } var renderer = SvgRenderer.FromGraphics(graphics); if (size.HasValue) { renderer.SetBoundable(new GenericBoundable(0, 0, size.Value.Width, size.Value.Height)); } else { renderer.SetBoundable(this); } this.Render(renderer); }
/// <summary> /// Applies the required transforms to <see cref="SvgRenderer"/>. /// </summary> /// <param name="renderer">The <see cref="SvgRenderer"/> to be transformed.</param> protected internal virtual void PushTransforms(SvgRenderer renderer) { _graphicsMatrix = renderer.Transform; // Return if there are no transforms if (this.Transforms == null || this.Transforms.Count == 0) { return; } Matrix transformMatrix = renderer.Transform; foreach (SvgTransform transformation in this.Transforms) { transformMatrix.Multiply(transformation.Matrix); } renderer.Transform = transformMatrix; }
public override Brush GetBrush(SvgVisualElement renderingElement, SvgRenderer renderer, float opacity) { LoadStops(renderingElement); if (IsInvalid) { return(null); } try { if (this.GradientUnits == SvgCoordinateUnits.ObjectBoundingBox) { renderer.Boundable(renderingElement); } var specifiedStart = CalculateStart(renderer); var specifiedEnd = CalculateEnd(renderer); var effectiveStart = specifiedStart; var effectiveEnd = specifiedEnd; if (NeedToExpandGradient(renderingElement, specifiedStart, specifiedEnd)) { var expansion = ExpandGradient(renderingElement, specifiedStart, specifiedEnd); effectiveStart = expansion.StartPoint; effectiveEnd = expansion.EndPoint; } return(new LinearGradientBrush(effectiveStart, effectiveEnd, System.Drawing.Color.Transparent, System.Drawing.Color.Transparent) { InterpolationColors = CalculateColorBlend(renderer, opacity, specifiedStart, effectiveStart, specifiedEnd, effectiveEnd), WrapMode = WrapMode.TileFlipX }); } finally { if (this.GradientUnits == SvgCoordinateUnits.ObjectBoundingBox) { renderer.PopBoundable(); } } }
/// <summary> /// Draws a string on a path at a specified location and with a specified font. /// </summary> internal void DrawString(SvgRenderer renderer, GraphicsPath path, float x, float y, Font font, string text) { PointF location = new PointF(x, y); // No way to do letter-spacing or word-spacing, so do manually if (this.LetterSpacing.Value > 0.0f || this.WordSpacing.Value > 0.0f) { // Cut up into words, or just leave as required string[] words = (this.WordSpacing.Value > 0.0f) ? text.Split(' ') : new string[] { text }; float wordSpacing = this.WordSpacing.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this); float letterSpacing = this.LetterSpacing.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this); float start = x; foreach (string word in words) { // Only do if there is line spacing, just write the word otherwise if (this.LetterSpacing.Value > 0.0f) { char[] characters = word.ToCharArray(); foreach (char currentCharacter in characters) { path.AddString(currentCharacter.ToString(), font.FontFamily, (int)font.Style, font.Size, location, StringFormat.GenericTypographic); location = new PointF(path.GetBounds().Width + start + letterSpacing, location.Y); } } else { path.AddString(word, font.FontFamily, (int)font.Style, font.Size, location, StringFormat.GenericTypographic); } // Move the location of the word to be written along location = new PointF(path.GetBounds().Width + start + wordSpacing, location.Y); } } else { if (!string.IsNullOrEmpty(text)) { path.AddString(text, font.FontFamily, (int)font.Style, font.Size, location, StringFormat.GenericTypographic); } } }
/// <summary> /// Gets the <see cref="GraphicsPath"/> for this element. /// </summary> /// <value></value> public override GraphicsPath Path(ISvgRenderer renderer) { //if there is a TSpan inside of this text element then path should not be null (even if this text is empty!) var nodes = GetContentNodes().Where(x => x is SvgContentNode && string.IsNullOrEmpty(x.Content.Trim(new[] { '\r', '\n', '\t' }))); if (_path == null || IsPathDirty || nodes.Count() == 1) { if (renderer != null && renderer is IGraphicsProvider) { SetPath(new TextDrawingState(renderer, this)); } else { using (var r = SvgRenderer.FromNull()) SetPath(new TextDrawingState(r, this)); } } return(_path); }
private ColorBlend CalculateColorBlend(SvgRenderer renderer, float opacity, PointF specifiedStart, PointF effectiveStart, PointF specifiedEnd, PointF effectiveEnd) { var colorBlend = GetColorBlend(renderer, opacity, false); var startDelta = CalculateDistance(specifiedStart, effectiveStart); var endDelta = CalculateDistance(specifiedEnd, effectiveEnd); if (!(startDelta > 0) && !(endDelta > 0)) { return(colorBlend); } var specifiedLength = CalculateDistance(specifiedStart, specifiedEnd); var specifiedUnitVector = new PointF((specifiedEnd.X - specifiedStart.X) / (float)specifiedLength, (specifiedEnd.Y - specifiedStart.Y) / (float)specifiedLength); var effectiveLength = CalculateDistance(effectiveStart, effectiveEnd); for (var i = 0; i < colorBlend.Positions.Length; i++) { var originalPoint = MovePointAlongVector(specifiedStart, specifiedUnitVector, (float)specifiedLength * colorBlend.Positions[i]); var distanceFromEffectiveStart = CalculateDistance(effectiveStart, originalPoint); colorBlend.Positions[i] = (float)Math.Round(Math.Max(0F, Math.Min((distanceFromEffectiveStart / effectiveLength), 1.0F)), 5); } if (startDelta > 0) { colorBlend.Positions = new[] { 0F }.Concat(colorBlend.Positions).ToArray(); colorBlend.Colors = new[] { colorBlend.Colors.First() }.Concat(colorBlend.Colors).ToArray(); } if (endDelta > 0) { colorBlend.Positions = colorBlend.Positions.Concat(new[] { 1F }).ToArray(); colorBlend.Colors = colorBlend.Colors.Concat(new[] { colorBlend.Colors.Last() }).ToArray(); } return(colorBlend); }
/// <summary> /// Renders the stroke of the <see cref="SvgVisualElement"/> to the specified <see cref="SvgRenderer"/> /// </summary> /// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param> protected internal override void RenderStroke(SvgRenderer renderer) { if (this.Stroke != null) { float strokeWidth = this.StrokeWidth.ToDeviceValue(renderer, UnitRenderingType.Other, this); using (Pen pen = new Pen(this.Stroke.GetBrush(this, renderer, this.StrokeOpacity), strokeWidth)) { if (this.StrokeDashArray != null && this.StrokeDashArray.Count > 0) { /* divide by stroke width - GDI behaviour that I don't quite understand yet.*/ pen.DashPattern = this.StrokeDashArray.ConvertAll(u => u.Value / ((strokeWidth <= 0) ? 1 : strokeWidth)).ToArray(); } var path = this.Path(renderer); renderer.DrawPath(pen, path); if (this.MarkerStart != null) { SvgMarker marker = this.OwnerDocument.GetElementById <SvgMarker>(this.MarkerStart.ToString()); marker.RenderMarker(renderer, this, path.PathPoints[0], path.PathPoints[0], path.PathPoints[1]); } if (this.MarkerMid != null) { SvgMarker marker = this.OwnerDocument.GetElementById <SvgMarker>(this.MarkerMid.ToString()); for (int i = 1; i <= path.PathPoints.Length - 2; i++) { marker.RenderMarker(renderer, this, path.PathPoints[i], path.PathPoints[i - 1], path.PathPoints[i], path.PathPoints[i + 1]); } } if (this.MarkerEnd != null) { SvgMarker marker = this.OwnerDocument.GetElementById <SvgMarker>(this.MarkerEnd.ToString()); marker.RenderMarker(renderer, this, path.PathPoints[path.PathPoints.Length - 1], path.PathPoints[path.PathPoints.Length - 2], path.PathPoints[path.PathPoints.Length - 1]); } } } }
/// <summary> /// Renders the stroke of the <see cref="SvgVisualElement"/> to the specified <see cref="SvgRenderer"/> /// </summary> /// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param> protected internal override void RenderStroke(SvgRenderer renderer) { if (this.Stroke != null) { float strokeWidth = this.StrokeWidth.ToDeviceValue(this); using (var pen = new Pen(this.Stroke.GetBrush(this, this.StrokeOpacity), strokeWidth)) { if (this.StrokeDashArray != null && this.StrokeDashArray.Count > 0) { /* divide by stroke width - GDI behaviour that I don't quite understand yet.*/ pen.DashPattern = this.StrokeDashArray.ConvertAll(u => u.Value / ((strokeWidth <= 0) ? 1 : strokeWidth)).ToArray(); } //hardcoded transformation matrix. I am not sure why this is not in proportion or rotated correctly (something to do with how the endcaps are determined in GDI) var transMatrix = new Matrix(); transMatrix.Rotate(-90f); transMatrix.Scale(.6f, .6f); if (this.MarkerStart != null) { var marker = this.OwnerDocument.GetElementById <SvgMarker>(this.MarkerStart.ToString()); var markerPath = marker.Path.Clone() as GraphicsPath; markerPath.Transform(transMatrix); pen.CustomStartCap = new CustomLineCap(markerPath, null); } if (this.MarkerEnd != null) { var marker = this.OwnerDocument.GetElementById <SvgMarker>(this.MarkerEnd.ToString()); var markerPath = marker.Path.Clone() as GraphicsPath; markerPath.Transform(transMatrix); pen.CustomEndCap = new CustomLineCap(markerPath, null); } renderer.DrawPath(pen, this.Path); } } }
public void SaveJPEG(String filepath, Int32 DPI = 300) { Int32 oldDPI = Ppi; Ppi = DPI; // Int32 m_rate = Convert.ToInt32(DPI.GetRatio(Ppi)); Int32 w = Convert.ToInt32(Width.ToDeviceValue()); Int32 h = Convert.ToInt32(Height.ToDeviceValue()); Bitmap bitmap = new Bitmap(w, h); SvgRenderer renderer = SvgRenderer.FromImage(bitmap); // ImageFormatConverter.StandardValuesCollection; // ImageConverter imageConverter = new ImageConverter.StandardValuesCollection; Render(renderer); bitmap.Save(filepath, ImageFormat.Jpeg); Ppi = oldDPI; }
public override Brush GetBrush(SvgVisualElement renderingElement, SvgRenderer renderer, float opacity) { GraphicsPath path = new GraphicsPath(); float left = this.CenterX.ToDeviceValue(renderingElement); float top = this.CenterY.ToDeviceValue(renderingElement, true); float radius = this.Radius.ToDeviceValue(renderingElement); RectangleF boundingBox = (this.GradientUnits == SvgCoordinateUnits.ObjectBoundingBox) ? renderingElement.Bounds : renderingElement.OwnerDocument.GetDimensions(); if (radius > 0) { path.AddEllipse(left - radius, top - radius, radius * 2, radius * 2); PathGradientBrush brush = new PathGradientBrush(path); ColorBlend blend = base.GetColourBlend(renderingElement, opacity); brush.InterpolationColors = blend; brush.CenterPoint = new PointF(this.FocalX.ToDeviceValue(renderingElement), this.FocalY.ToDeviceValue(renderingElement, true)); return(brush); } return(null); }
/// <summary> /// Renders the <see cref="SvgDocument"/> into a given Bitmap <see cref="Bitmap"/>. /// </summary> public virtual void Draw(Bitmap bitmap) { //Trace.TraceInformation("Begin Render"); try { using (var renderer = SvgRenderer.FromImage(bitmap)) { renderer.Boundable(new GenericBoundable(0, 0, bitmap.Width, bitmap.Height)); renderer.TextRenderingHint = TextRenderingHint.AntiAlias; renderer.TextContrast = 1; renderer.PixelOffsetMode = PixelOffsetMode.Half; this.Render(renderer); renderer.Save(); } } catch { throw; } //Trace.TraceInformation("End Render"); }
/// <summary> /// Recursive method to add up the paths of all children /// </summary> /// <param name="elem"></param> /// <param name="path"></param> protected GraphicsPath GetPaths(SvgElement elem, SvgRenderer renderer) { var ret = new GraphicsPath(); foreach (var child in elem.Children) { if (child is SvgVisualElement) { if (!(child is SvgGroup)) { var childPath = ((SvgVisualElement)child).Path(renderer); if (childPath != null) { childPath = (GraphicsPath)childPath.Clone(); if (child.Transforms != null) { childPath.Transform(child.Transforms.GetMatrix()); } ret.AddPath(childPath, false); } } else { var childPath = GetPaths(child, renderer); if (child.Transforms != null) { childPath.Transform(child.Transforms.GetMatrix()); } } } } return(ret); }
/// <summary> /// Renders the <see cref="SvgDocument"/> into a given Bitmap <see cref="Bitmap"/>. /// </summary> public virtual void Draw(Bitmap bitmap, bool wireframe = false) { //Trace.TraceInformation("Begin Render"); try { using (var renderer = SvgRenderer.FromImage(bitmap)) { renderer.Wireframe = wireframe; renderer.SetBoundable(new GenericBoundable(0, 0, bitmap.Width, bitmap.Height)); //EO, 2014-12-05: Requested to ensure proper zooming out (reduce size). Otherwise it clip the image. this.Overflow = SvgOverflow.Auto; this.Render(renderer); } } catch { throw; } //Trace.TraceInformation("End Render"); }
/// <summary> /// Resets the clipping region of the specified <see cref="SvgRenderer"/> back to where it was before the <see cref="SetClip"/> method was called. /// </summary> /// <param name="renderer">The <see cref="SvgRenderer"/> to have its clipping region reset.</param> void ISvgClipable.ResetClip(SvgRenderer renderer) { this.ResetClip(renderer); }
/// <summary> /// Resets the clipping region of the specified <see cref="SvgRenderer"/> back to where it was before the <see cref="SetClip"/> method was called. /// </summary> /// <param name="renderer">The <see cref="SvgRenderer"/> to have its clipping region reset.</param> protected internal virtual void ResetClip(SvgRenderer renderer) { if (this._previousClip != null) { renderer.Clip = this._previousClip; this._previousClip = null; } }
/// <summary> /// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object. /// </summary> /// <param name="graphics">The <see cref="Graphics"/> object to render to.</param> protected override void Render(SvgRenderer renderer) { if (this._radiusX.Value > 0.0f && this._radiusY.Value > 0.0f) { base.Render(renderer); } }
/// <summary> /// Creates a new <see cref="SvgRenderer"/> from the specified <see cref="Graphics"/>. /// </summary> /// <param name="graphics">The <see cref="Graphics"/> to create the renderer from.</param> public static SvgRenderer FromGraphics(Graphics graphics) { SvgRenderer renderer = new SvgRenderer(); renderer._innerGraphics = graphics; return renderer; }
/// <summary> /// Renders the fill of the <see cref="SvgVisualElement"/> to the specified <see cref="SvgRenderer"/> /// </summary> /// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param> protected internal virtual void RenderFill(SvgRenderer renderer) { if (this.Fill != null) { using (Brush brush = this.Fill.GetBrush(this, this.FillOpacity)) { if (brush != null) { renderer.FillPath(brush, this.Path); } } } }
static private int MeasureString(SvgRenderer renderer, string text, Font font) { GraphicsPath p = new GraphicsPath(); p.AddString(text, font.FontFamily, 0, font.Size, new PointF(0.0f, 0.0f), StringFormat.GenericTypographic); p.Transform(renderer.Transform); return (int)(p.GetBounds().Width + 1.0f); }
/// <summary> /// Renders the circle to the specified <see cref="Graphics"/> object. /// </summary> /// <param name="graphics">The graphics object.</param> protected override void Render(SvgRenderer renderer) { // Don't draw if there is no radius set if (this.Radius.Value > 0.0f) { base.Render(renderer); } }
/// <summary> /// Sets the clipping region of the specified <see cref="SvgRenderer"/>. /// </summary> /// <param name="renderer">The <see cref="SvgRenderer"/> to have its clipping region set.</param> protected internal virtual void SetClip(SvgRenderer renderer) { if (this.ClipPath != null) { SvgClipPath clipPath = this.OwnerDocument.GetElementById<SvgClipPath>(this.ClipPath.ToString()); this._previousClip = renderer.Clip; if (clipPath != null) { renderer.Clip = clipPath.GetClipRegion(this); } } }
/// <summary> /// Converts the current unit to one that can be used at render time. /// </summary> /// <param name="boundable">The container element used as the basis for calculations</param> /// <returns>The representation of the current unit in a device value (usually pixels).</returns> public float ToDeviceValue(SvgRenderer renderer, UnitRenderingType renderType, SvgElement owner) { // If it's already been calculated if (this._deviceValue.HasValue) { return this._deviceValue.Value; } if (this._value == 0.0f) { this._deviceValue = 0.0f; return this._deviceValue.Value; } // http://www.w3.org/TR/CSS21/syndata.html#values // http://www.w3.org/TR/SVG11/coords.html#Units const float cmInInch = 2.54f; int ppi = SvgDocument.PointsPerInch; var type = this.Type; var value = this.Value; // Deal with fractional pattern units var coordElem = owner as ISvgSupportsCoordinateUnits; if (coordElem != null && coordElem.GetUnits() == SvgCoordinateUnits.ObjectBoundingBox && type != SvgUnitType.Percentage) { type = SvgUnitType.Percentage; value *= 100; } var element = owner as SvgElement; if (element != null) { var pattern = element.Parents.OfType<SvgPatternServer>().FirstOrDefault(); if (pattern != null && pattern.PatternContentUnits == SvgCoordinateUnits.ObjectBoundingBox && type != SvgUnitType.Percentage) { type = SvgUnitType.Percentage; value *= 100; } } float points; Font currFont; switch (type) { case SvgUnitType.Em: currFont = GetFont(renderer, owner); if (currFont == null) { points = (float)(value * 9); _deviceValue = (points / 72.0f) * ppi; } else { _deviceValue = value * (currFont.SizeInPoints / 72.0f) * ppi; } break; case SvgUnitType.Ex: currFont = GetFont(renderer, owner); if (currFont == null) { points = (float)(value * 9); _deviceValue = (points * 0.5f / 72.0f) * ppi; } else { _deviceValue = value * 0.5f * (currFont.SizeInPoints / 72.0f) * ppi; } break; case SvgUnitType.Centimeter: _deviceValue = (float)((value / cmInInch) * ppi); break; case SvgUnitType.Inch: _deviceValue = value * ppi; break; case SvgUnitType.Millimeter: _deviceValue = (float)((value / 10) / cmInInch) * ppi; break; case SvgUnitType.Pica: _deviceValue = ((value * 12) / 72) * ppi; break; case SvgUnitType.Point: _deviceValue = (value / 72) * ppi; break; case SvgUnitType.Pixel: _deviceValue = value; break; case SvgUnitType.User: _deviceValue = value; break; case SvgUnitType.Percentage: // Can't calculate if there is no style owner var boundable = (renderer == null ? (owner == null ? null : owner.OwnerDocument) : renderer.Boundable()); if (boundable == null) { _deviceValue = value; break; } System.Drawing.SizeF size = boundable.Bounds.Size; switch (renderType) { case UnitRenderingType.Horizontal: _deviceValue = (size.Width / 100) * value; break; case UnitRenderingType.HorizontalOffset: _deviceValue = (size.Width / 100) * value + boundable.Location.X; break; case UnitRenderingType.Vertical: _deviceValue = (size.Height / 100) * value; break; case UnitRenderingType.VerticalOffset: _deviceValue = (size.Height / 100) * value + boundable.Location.Y; break; default: _deviceValue = (float)(Math.Sqrt(Math.Pow(size.Width, 2) + Math.Pow(size.Height, 2)) / Math.Sqrt(2) * value / 100.0); break; } break; default: _deviceValue = value; break; } return this._deviceValue.Value; }
public static System.Drawing.SizeF GetDeviceSize(SvgUnit width, SvgUnit height, SvgRenderer renderer, SvgElement owner) { return new System.Drawing.SizeF(width.ToDeviceValue(renderer, UnitRenderingType.HorizontalOffset, owner), height.ToDeviceValue(renderer, UnitRenderingType.VerticalOffset, owner)); }
/// <summary> /// Renders the stroke of the <see cref="SvgVisualElement"/> to the specified <see cref="SvgRenderer"/> /// </summary> /// <param name="renderer">The <see cref="SvgRenderer"/> object to render to.</param> protected internal virtual void RenderStroke(SvgRenderer renderer) { if (this.Stroke != null) { float strokeWidth = this.StrokeWidth.ToDeviceValue(this); using (var pen = new Pen(this.Stroke.GetBrush(this, this.StrokeOpacity), strokeWidth)) { if (this.StrokeDashArray != null && this.StrokeDashArray.Count > 0) { /* divide by stroke width - GDI behaviour that I don't quite understand yet.*/ pen.DashPattern = this.StrokeDashArray.ConvertAll(u => u.Value/((strokeWidth <= 0) ? 1 : strokeWidth)).ToArray(); } renderer.DrawPath(pen, this.Path); } } }
private Font GetFont(SvgRenderer renderer, SvgElement owner) { if (owner == null) return null; var visual = owner.ParentsAndSelf.OfType<SvgVisualElement>().FirstOrDefault(); return visual.GetFont(renderer); }
/// <summary> /// Get the font information based on data stored with the text object or inherited from the parent. /// </summary> /// <returns></returns> internal System.Drawing.Font GetFont(SvgRenderer renderer) { // Get the font-size float fontSize; var fontSizeUnit = this.FontSize; if (fontSizeUnit == SvgUnit.None) { fontSize = 1.0f; } else { fontSize = fontSizeUnit.ToDeviceValue(renderer, UnitRenderingType.Vertical, this); } var fontStyle = System.Drawing.FontStyle.Regular; // Get the font-weight switch (this.FontWeight) { case SvgFontWeight.bold: case SvgFontWeight.bolder: case SvgFontWeight.w600: case SvgFontWeight.w700: case SvgFontWeight.w800: case SvgFontWeight.w900: fontStyle |= System.Drawing.FontStyle.Bold; break; } // Get the font-style switch (this.FontStyle) { case SvgFontStyle.italic: case SvgFontStyle.oblique: fontStyle |= System.Drawing.FontStyle.Italic; break; } // Get the text-decoration switch (this.TextDecoration) { case SvgTextDecoration.lineThrough: fontStyle |= System.Drawing.FontStyle.Strikeout; break; case SvgTextDecoration.underline: fontStyle |= System.Drawing.FontStyle.Underline; break; } // Get the font-family string family = ValidateFontFamily(this.FontFamily) ?? DefaultFontFamily; return new System.Drawing.Font(family, fontSize, fontStyle, System.Drawing.GraphicsUnit.Pixel); }