public void Draw(Graphics gr, RectangleF rect, RectangleF source, ImageAttributes attributes = null) { if (IsSVG) { // largely based on function above now. Not sure when this version is used to test it really works if source is changed EnsureSVG(); GraphicsState state = gr.Save(); using (ISvgRenderer render = SvgRenderer.FromGraphics(gr)) { render.TranslateTransform(rect.Left, rect.Top, MatrixOrder.Prepend); render.ScaleTransform(rect.Width / source.Width, rect.Height / source.Height, MatrixOrder.Prepend); render.TranslateTransform(-source.Left, -source.Top); m_SVG.Draw(render); } gr.Restore(state); //RectangleF viewbox = m_SVG.ViewBox; //// we must prevent SVG applying any scaling as it's in the wrong sequence, and must be BEFORE the source adjustments //// therefore we perform the output scale now: (and below m_SVG.Draw uses the viewbox size, so will apply a (1,1) scaling) //// I think it's correct that this uses viewbox not bound (as above function) as we are implementing the SVG scaling for the viewbox ourselves now //gr.ScaleTransform(rect.Width / viewbox.Width, rect.Height / viewbox.Height); //gr.ScaleTransform(viewbox.Width / source.Width, viewbox.Height / source.Height); //gr.TranslateTransform(-(source.X - viewbox.X), -(source.Y - viewbox.Y)); //m_SVG.Draw(gr, new SizeF(viewbox.Width, viewbox.Height)); //gr.DrawRectangle(Pens.LightBlue, viewbox.X, viewbox.Y, viewbox.Width, viewbox.Height); //gr.Restore(state); ////gr.DrawRectangle(Pens.Salmon, rect.X, rect.Y, rect.Width, rect.Height); } else { gr.DrawImage(GetNetImage(), rect, source, attributes); } }
/// <summary> /// Applies the required transforms to <see cref="ISvgRenderer"/>. /// </summary> /// <param name="renderer">The <see cref="ISvgRenderer"/> to be transformed.</param> protected internal override bool PushTransforms(ISvgRenderer renderer) { if (!base.PushTransforms(renderer)) { return(false); } renderer.TranslateTransform(X.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this), Y.ToDeviceValue(renderer, UnitRenderingType.Vertical, this)); return(true); }
public void Draw(Graphics gr, RectangleF rect, ImageAttributes attributes = null) { if (IsSVG) { //EnsureSVG(); // either of these following lines can be used to test function below //Draw(gr, rect, new RectangleF(0, 0, m_SVG.Width, m_SVG.Height), attributes); //Draw(gr, new PointF[] { rect.Location, rect.TopRight(), rect.BottomLeft() }, new RectangleF(0, 0, m_SVG.Width, m_SVG.Height), attributes); //return; var state = gr.Save(); using (ISvgRenderer render = SvgRenderer.FromGraphics(gr)) { //render.Transform = gr.Transform; - redundant as it does this anyway. Doing this ...Clone might be useful so the original matrix didn't get corrupted, but safer to just store entire state anyway render.TranslateTransform(rect.Left, rect.Top, MatrixOrder.Prepend); render.ScaleTransform(rect.Width / m_SVG.Width, rect.Height / m_SVG.Height, MatrixOrder.Prepend); m_SVG.Draw(render); } gr.Restore(state); } else { gr.DrawImage(GetNetImage(), rect, attributes); } }
public void AddViewBoxTransform(SvgAspectRatio aspectRatio, ISvgRenderer renderer, SvgFragment frag) { var x = (frag == null ? 0 : frag.X.ToDeviceValue(renderer, UnitRenderingType.Horizontal, frag)); var y = (frag == null ? 0 : frag.Y.ToDeviceValue(renderer, UnitRenderingType.Vertical, frag)); if (this.Equals(SvgViewBox.Empty)) { renderer.TranslateTransform(x, y, MatrixOrder.Prepend); return; } var width = (frag == null ? this.Width : frag.Width.ToDeviceValue(renderer, UnitRenderingType.Horizontal, frag)); var height = (frag == null ? this.Height : frag.Height.ToDeviceValue(renderer, UnitRenderingType.Vertical, frag)); var fScaleX = width / this.Width; var fScaleY = height / this.Height; //(this.MinY < 0 ? -1 : 1) * var fMinX = -this.MinX * fScaleX; var fMinY = -this.MinY * fScaleY; if (aspectRatio == null) { aspectRatio = new SvgAspectRatio(SvgPreserveAspectRatio.xMidYMid, false); } if (aspectRatio.Align != SvgPreserveAspectRatio.none) { if (aspectRatio.Slice) { fScaleX = Math.Max(fScaleX, fScaleY); fScaleY = Math.Max(fScaleX, fScaleY); } else { fScaleX = Math.Min(fScaleX, fScaleY); fScaleY = Math.Min(fScaleX, fScaleY); } float fViewMidX = (this.Width / 2) * fScaleX; float fViewMidY = (this.Height / 2) * fScaleY; float fMidX = width / 2; float fMidY = height / 2; fMinX = -this.MinX * fScaleX; fMinY = -this.MinY * fScaleY; switch (aspectRatio.Align) { case SvgPreserveAspectRatio.xMinYMin: break; case SvgPreserveAspectRatio.xMidYMin: fMinX += fMidX - fViewMidX; break; case SvgPreserveAspectRatio.xMaxYMin: fMinX += width - this.Width * fScaleX; break; case SvgPreserveAspectRatio.xMinYMid: fMinY += fMidY - fViewMidY; break; case SvgPreserveAspectRatio.xMidYMid: fMinX += fMidX - fViewMidX; fMinY += fMidY - fViewMidY; break; case SvgPreserveAspectRatio.xMaxYMid: fMinX += width - this.Width * fScaleX; fMinY += fMidY - fViewMidY; break; case SvgPreserveAspectRatio.xMinYMax: fMinY += height - this.Height * fScaleY; break; case SvgPreserveAspectRatio.xMidYMax: fMinX += fMidX - fViewMidX; fMinY += height - this.Height * fScaleY; break; case SvgPreserveAspectRatio.xMaxYMax: fMinX += width - this.Width * fScaleX; fMinY += height - this.Height * fScaleY; break; default: break; } } renderer.SetClip(new Region(new RectangleF(x, y, width, height)), CombineMode.Intersect); renderer.TranslateTransform(x, y, MatrixOrder.Prepend); renderer.TranslateTransform(fMinX, fMinY, MatrixOrder.Prepend); renderer.ScaleTransform(fScaleX, fScaleY, MatrixOrder.Prepend); }
/// <summary> /// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object. /// </summary> protected override void Render(ISvgRenderer renderer) { if (!Visible || !Displayable) { return; } if (Width.Value > 0.0f && Height.Value > 0.0f && this.Href != null) { var img = GetImage(); if (img != null) { RectangleF srcRect; var bmp = img as Bitmap; var svg = img as SvgFragment; if (bmp != null) { srcRect = new RectangleF(0, 0, bmp.Width, bmp.Height); } else if (svg != null) { srcRect = new RectangleF(new PointF(0, 0), svg.GetDimensions()); } else { return; } var destClip = new RectangleF(this.Location.ToDeviceValue(renderer, this), new SizeF(Width.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this), Height.ToDeviceValue(renderer, UnitRenderingType.Vertical, this))); RectangleF destRect = destClip; this.PushTransforms(renderer); renderer.SetClip(new Region(destClip), CombineMode.Intersect); this.SetClip(renderer); if (AspectRatio != null && AspectRatio.Align != SvgPreserveAspectRatio.none) { var fScaleX = destClip.Width / srcRect.Width; var fScaleY = destClip.Height / srcRect.Height; var xOffset = 0.0f; var yOffset = 0.0f; if (AspectRatio.Slice) { fScaleX = Math.Max(fScaleX, fScaleY); fScaleY = Math.Max(fScaleX, fScaleY); } else { fScaleX = Math.Min(fScaleX, fScaleY); fScaleY = Math.Min(fScaleX, fScaleY); } switch (AspectRatio.Align) { case SvgPreserveAspectRatio.xMinYMin: break; case SvgPreserveAspectRatio.xMidYMin: xOffset = (destClip.Width - srcRect.Width * fScaleX) / 2; break; case SvgPreserveAspectRatio.xMaxYMin: xOffset = (destClip.Width - srcRect.Width * fScaleX); break; case SvgPreserveAspectRatio.xMinYMid: yOffset = (destClip.Height - srcRect.Height * fScaleY) / 2; break; case SvgPreserveAspectRatio.xMidYMid: xOffset = (destClip.Width - srcRect.Width * fScaleX) / 2; yOffset = (destClip.Height - srcRect.Height * fScaleY) / 2; break; case SvgPreserveAspectRatio.xMaxYMid: xOffset = (destClip.Width - srcRect.Width * fScaleX); yOffset = (destClip.Height - srcRect.Height * fScaleY) / 2; break; case SvgPreserveAspectRatio.xMinYMax: yOffset = (destClip.Height - srcRect.Height * fScaleY); break; case SvgPreserveAspectRatio.xMidYMax: xOffset = (destClip.Width - srcRect.Width * fScaleX) / 2; yOffset = (destClip.Height - srcRect.Height * fScaleY); break; case SvgPreserveAspectRatio.xMaxYMax: xOffset = (destClip.Width - srcRect.Width * fScaleX); yOffset = (destClip.Height - srcRect.Height * fScaleY); break; } destRect = new RectangleF(destClip.X + xOffset, destClip.Y + yOffset, srcRect.Width * fScaleX, srcRect.Height * fScaleY); } if (bmp != null) { renderer.DrawImage(bmp, destRect, srcRect, GraphicsUnit.Pixel); bmp.Dispose(); } else if (svg != null) { var currOffset = new PointF(renderer.Transform.OffsetX, renderer.Transform.OffsetY); renderer.TranslateTransform(-currOffset.X, -currOffset.Y); renderer.ScaleTransform(destRect.Width / srcRect.Width, destRect.Height / srcRect.Height); renderer.TranslateTransform(currOffset.X + destRect.X, currOffset.Y + destRect.Y); renderer.SetBoundable(new GenericBoundable(srcRect)); svg.RenderElement(renderer); renderer.PopBoundable(); } this.ResetClip(renderer); this.PopTransforms(renderer); } // TODO: cache images... will need a shared context for this // TODO: support preserveAspectRatio, etc } }
/// <summary> /// Renders the <see cref="SvgElement"/> and contents to the specified <see cref="Graphics"/> object. /// </summary> protected override void Render(ISvgRenderer renderer) { if (!(Visible && Displayable && Width.Value > 0f && Height.Value > 0f && Href != null)) { return; } var img = GetImage(Href); var bmp = img as Image; var svg = img as SvgFragment; if (bmp == null && svg == null) { return; } try { if (PushTransforms(renderer)) { RectangleF srcRect; if (bmp != null) { srcRect = new RectangleF(0f, 0f, bmp.Width, bmp.Height); } else { srcRect = new RectangleF(new PointF(0f, 0f), svg.GetDimensions()); } var destClip = new RectangleF(Location.ToDeviceValue(renderer, this), new SizeF(Width.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this), Height.ToDeviceValue(renderer, UnitRenderingType.Vertical, this))); var destRect = destClip; renderer.SetClip(new Region(destClip), CombineMode.Intersect); SetClip(renderer); var aspectRatio = AspectRatio; if (aspectRatio.Align != SvgPreserveAspectRatio.none) { var fScaleX = destClip.Width / srcRect.Width; var fScaleY = destClip.Height / srcRect.Height; var xOffset = 0f; var yOffset = 0f; if (aspectRatio.Slice) { fScaleX = Math.Max(fScaleX, fScaleY); fScaleY = Math.Max(fScaleX, fScaleY); } else { fScaleX = Math.Min(fScaleX, fScaleY); fScaleY = Math.Min(fScaleX, fScaleY); } switch (aspectRatio.Align) { case SvgPreserveAspectRatio.xMinYMin: break; case SvgPreserveAspectRatio.xMidYMin: xOffset = (destClip.Width - srcRect.Width * fScaleX) / 2; break; case SvgPreserveAspectRatio.xMaxYMin: xOffset = (destClip.Width - srcRect.Width * fScaleX); break; case SvgPreserveAspectRatio.xMinYMid: yOffset = (destClip.Height - srcRect.Height * fScaleY) / 2; break; case SvgPreserveAspectRatio.xMidYMid: xOffset = (destClip.Width - srcRect.Width * fScaleX) / 2; yOffset = (destClip.Height - srcRect.Height * fScaleY) / 2; break; case SvgPreserveAspectRatio.xMaxYMid: xOffset = (destClip.Width - srcRect.Width * fScaleX); yOffset = (destClip.Height - srcRect.Height * fScaleY) / 2; break; case SvgPreserveAspectRatio.xMinYMax: yOffset = (destClip.Height - srcRect.Height * fScaleY); break; case SvgPreserveAspectRatio.xMidYMax: xOffset = (destClip.Width - srcRect.Width * fScaleX) / 2; yOffset = (destClip.Height - srcRect.Height * fScaleY); break; case SvgPreserveAspectRatio.xMaxYMax: xOffset = (destClip.Width - srcRect.Width * fScaleX); yOffset = (destClip.Height - srcRect.Height * fScaleY); break; } destRect = new RectangleF(destClip.X + xOffset, destClip.Y + yOffset, srcRect.Width * fScaleX, srcRect.Height * fScaleY); } if (bmp != null) { var opacity = FixOpacityValue(Opacity); if (opacity == 1f) { renderer.DrawImage(bmp, destRect, srcRect, GraphicsUnit.Pixel); } else { renderer.DrawImage(bmp, destRect, srcRect, GraphicsUnit.Pixel, opacity); } } else { renderer.TranslateTransform(destRect.X, destRect.Y, MatrixOrder.Prepend); renderer.ScaleTransform(destRect.Width / srcRect.Width, destRect.Height / srcRect.Height, MatrixOrder.Prepend); try { renderer.SetBoundable(new GenericBoundable(srcRect)); svg.RenderElement(renderer); } finally { renderer.PopBoundable(); } } ResetClip(renderer); } } finally { PopTransforms(renderer); if (bmp != null) { bmp.Dispose(); } } // TODO: cache images... will need a shared context for this }
public void AddViewBoxTransform(SvgAspectRatio aspectRatio, ISvgRenderer renderer, SvgFragment frag) { var x = frag == null ? 0f : frag.X.ToDeviceValue(renderer, UnitRenderingType.Horizontal, frag); var y = frag == null ? 0f : frag.Y.ToDeviceValue(renderer, UnitRenderingType.Vertical, frag); if (Equals(Empty)) { renderer.TranslateTransform(x, y, MatrixOrder.Prepend); return; } var width = frag == null ? Width : frag.Width.ToDeviceValue(renderer, UnitRenderingType.Horizontal, frag); var height = frag == null ? Height : frag.Height.ToDeviceValue(renderer, UnitRenderingType.Vertical, frag); var fScaleX = width / Width; var fScaleY = height / Height; //(MinY < 0 ? -1 : 1) * var fMinX = -MinX * fScaleX; var fMinY = -MinY * fScaleY; aspectRatio ??= new SvgAspectRatio(SvgPreserveAspectRatio.xMidYMid); if (aspectRatio.Align != SvgPreserveAspectRatio.none) { if (aspectRatio.Slice) { fScaleX = Math.Max(fScaleX, fScaleY); fScaleY = Math.Max(fScaleX, fScaleY); } else { fScaleX = Math.Min(fScaleX, fScaleY); fScaleY = Math.Min(fScaleX, fScaleY); } var fViewMidX = (Width / 2) * fScaleX; var fViewMidY = (Height / 2) * fScaleY; var fMidX = width / 2; var fMidY = height / 2; fMinX = -MinX * fScaleX; fMinY = -MinY * fScaleY; switch (aspectRatio.Align) { case SvgPreserveAspectRatio.xMinYMin: break; case SvgPreserveAspectRatio.xMidYMin: fMinX += fMidX - fViewMidX; break; case SvgPreserveAspectRatio.xMaxYMin: fMinX += width - Width * fScaleX; break; case SvgPreserveAspectRatio.xMinYMid: fMinY += fMidY - fViewMidY; break; case SvgPreserveAspectRatio.xMidYMid: fMinX += fMidX - fViewMidX; fMinY += fMidY - fViewMidY; break; case SvgPreserveAspectRatio.xMaxYMid: fMinX += width - Width * fScaleX; fMinY += fMidY - fViewMidY; break; case SvgPreserveAspectRatio.xMinYMax: fMinY += height - Height * fScaleY; break; case SvgPreserveAspectRatio.xMidYMax: fMinX += fMidX - fViewMidX; fMinY += height - Height * fScaleY; break; case SvgPreserveAspectRatio.xMaxYMax: fMinX += width - Width * fScaleX; fMinY += height - Height * fScaleY; break; default: break; } } renderer.TranslateTransform(x, y, MatrixOrder.Prepend); renderer.TranslateTransform(fMinX, fMinY, MatrixOrder.Prepend); renderer.ScaleTransform(fScaleX, fScaleY, MatrixOrder.Prepend); }
public void AddViewBoxTransform(SvgAspectRatio aspectRatio, ISvgRenderer renderer, SvgFragment frag) { var x = (frag == null ? 0 : frag.X.ToDeviceValue(renderer, UnitRenderingType.Horizontal, frag)); var y = (frag == null ? 0 : frag.Y.ToDeviceValue(renderer, UnitRenderingType.Vertical, frag)); if (this.Equals(SvgViewBox.Empty)) { renderer.TranslateTransform(x, y); return; } var width = (frag == null ? this.Width : frag.Width.ToDeviceValue(renderer, UnitRenderingType.Horizontal, frag)); var height = (frag == null ? this.Height : frag.Height.ToDeviceValue(renderer, UnitRenderingType.Vertical, frag)); var fScaleX = width / this.Width; var fScaleY = height / this.Height; //(this.MinY < 0 ? -1 : 1) * var fMinX = -this.MinX * fScaleX; var fMinY = -this.MinY * fScaleY; if (aspectRatio == null) aspectRatio = new SvgAspectRatio(SvgPreserveAspectRatio.xMidYMid, false); if (aspectRatio.Align != SvgPreserveAspectRatio.none) { if (aspectRatio.Slice) { fScaleX = Math.Max(fScaleX, fScaleY); fScaleY = Math.Max(fScaleX, fScaleY); } else { fScaleX = Math.Min(fScaleX, fScaleY); fScaleY = Math.Min(fScaleX, fScaleY); } float fViewMidX = (this.Width / 2) * fScaleX; float fViewMidY = (this.Height / 2) * fScaleY; float fMidX = width / 2; float fMidY = height / 2; fMinX = -this.MinX * fScaleX; fMinY = -this.MinY * fScaleY; switch (aspectRatio.Align) { case SvgPreserveAspectRatio.xMinYMin: break; case SvgPreserveAspectRatio.xMidYMin: fMinX += fMidX - fViewMidX; break; case SvgPreserveAspectRatio.xMaxYMin: fMinX += width - this.Width * fScaleX; break; case SvgPreserveAspectRatio.xMinYMid: fMinY += fMidY - fViewMidY; break; case SvgPreserveAspectRatio.xMidYMid: fMinX += fMidX - fViewMidX; fMinY += fMidY - fViewMidY; break; case SvgPreserveAspectRatio.xMaxYMid: fMinX += width - this.Width * fScaleX; fMinY += fMidY - fViewMidY; break; case SvgPreserveAspectRatio.xMinYMax: fMinY += height - this.Height * fScaleY; break; case SvgPreserveAspectRatio.xMidYMax: fMinX += fMidX - fViewMidX; fMinY += height - this.Height * fScaleY; break; case SvgPreserveAspectRatio.xMaxYMax: fMinX += width - this.Width * fScaleX; fMinY += height - this.Height * fScaleY; break; default: break; } } renderer.SetClip(new Region(new RectangleF(x, y, width, height)), CombineMode.Intersect); renderer.ScaleTransform(fScaleX, fScaleY, MatrixOrder.Prepend); renderer.TranslateTransform(x, y); renderer.TranslateTransform(fMinX, fMinY); }
public void TranslateTransform(float dx, float dy, MatrixOrder order = MatrixOrder.Append) { _svgRendererImplementation.TranslateTransform(dx, dy, order); }