public override void BeforeRender(GdiGraphicsRenderer renderer) { if (_uniqueColor.IsEmpty) { _uniqueColor = renderer.GetNextColor(element); } GdiGraphicsWrapper graphics = renderer.GraphicsWrapper; _graphicsContainer = graphics.BeginContainer(); SetQuality(graphics); Transform(graphics); }
protected void FitToViewbox(GdiGraphicsWrapper graphics, RectangleF elmRect) { if (element is ISvgFitToViewBox) { ISvgFitToViewBox fitToVBElm = (ISvgFitToViewBox)element; SvgPreserveAspectRatio spar = (SvgPreserveAspectRatio)fitToVBElm.PreserveAspectRatio.AnimVal; double[] translateAndScale = spar.FitToViewBox( (SvgRect)fitToVBElm.ViewBox.AnimVal, new SvgRect(elmRect.X, elmRect.Y, elmRect.Width, elmRect.Height)); graphics.TranslateTransform((float)translateAndScale[0], (float)translateAndScale[1]); graphics.ScaleTransform((float)translateAndScale[2], (float)translateAndScale[3]); } }
public override void AfterRender(GdiGraphicsRenderer renderer) { if (renderer == null) { return; } GdiGraphicsWrapper graphics = renderer.GraphicsWrapper; if (graphics == null) { return; } graphics.EndContainer(_graphicsContainer); }
protected void Transform(GdiGraphicsWrapper gr) { if (element is ISvgTransformable) { if (_transformMatrix == null) { ISvgTransformable transElm = (ISvgTransformable)element; SvgTransformList svgTList = (SvgTransformList)transElm.Transform.AnimVal; SvgMatrix svgMatrix = ((SvgTransformList)transElm.Transform.AnimVal).TotalMatrix; _transformMatrix = new Matrix((float)svgMatrix.A, (float)svgMatrix.B, (float)svgMatrix.C, (float)svgMatrix.D, (float)svgMatrix.E, (float)svgMatrix.F); } gr.Transform = _transformMatrix; } }
/// <summary> /// AfterRender - Dispose of Graphics object created for rendering. /// </summary> private void RendererAfterRender() { if (graphics != null) { // Check if we only invalidated a rect if (invalidRect != SvgRectF.Empty) { // We actually drew everything on invalidatedRasterImage and now we // need to copy that to rasterImage Graphics tempGraphics = Graphics.FromImage(rasterImage); tempGraphics.DrawImage(invalidatedRasterImage, invalidRect.X, invalidRect.Y, GdiConverter.ToRectangle(invalidRect), GraphicsUnit.Pixel); tempGraphics.Dispose(); tempGraphics = null; // If we currently have an idMapRaster here, then we need to create // a temporary graphics object to draw the invalidated portion from // our main graphics window onto it. if (idMapRaster != null) { tempGraphics = Graphics.FromImage(idMapRaster); tempGraphics.DrawImage(graphics.IdMapRaster, invalidRect.X, invalidRect.Y, GdiConverter.ToRectangle(invalidRect), GraphicsUnit.Pixel); tempGraphics.Dispose(); tempGraphics = null; } else { idMapRaster = graphics.IdMapRaster; } // We have updated the invalid region invalidRect = SvgRectF.Empty; } else { if (idMapRaster != null && idMapRaster != graphics.IdMapRaster) { idMapRaster.Dispose(); } idMapRaster = graphics.IdMapRaster; } graphics.Dispose(); graphics = null; } }
protected static void PaintMarkers(GdiGraphicsRenderer renderer, SvgStyleableElement styleElm, GdiGraphicsWrapper gr) { // OPTIMIZE if (styleElm is ISharpMarkerHost) { string markerStartUrl = ExtractMarkerUrl(styleElm.GetPropertyValue("marker-start", "marker")); string markerMiddleUrl = ExtractMarkerUrl(styleElm.GetPropertyValue("marker-mid", "marker")); string markerEndUrl = ExtractMarkerUrl(styleElm.GetPropertyValue("marker-end", "marker")); if (markerStartUrl.Length > 0) { GdiMarkerRendering grNode = CreateByUri(styleElm.OwnerDocument, styleElm.BaseURI, markerStartUrl) as GdiMarkerRendering; if (grNode != null) { grNode.PaintMarker(renderer, gr, SvgMarkerPosition.Start, styleElm); } } if (markerMiddleUrl.Length > 0) { // TODO markerMiddleUrl != markerStartUrl GdiMarkerRendering grNode = CreateByUri(styleElm.OwnerDocument, styleElm.BaseURI, markerMiddleUrl) as GdiMarkerRendering; if (grNode != null) { grNode.PaintMarker(renderer, gr, SvgMarkerPosition.Mid, styleElm); } } if (markerEndUrl.Length > 0) { // TODO: markerEndUrl != markerMiddleUrl GdiMarkerRendering grNode = CreateByUri(styleElm.OwnerDocument, styleElm.BaseURI, markerEndUrl) as GdiMarkerRendering; if (grNode != null) { grNode.PaintMarker(renderer, gr, SvgMarkerPosition.End, styleElm); } } } }
public override void Render(GdiGraphicsRenderer renderer) { GdiGraphicsWrapper graphics = renderer.GraphicsWrapper; SvgSvgElement svgElm = (SvgSvgElement)element; float x = (float)svgElm.X.AnimVal.Value; float y = (float)svgElm.Y.AnimVal.Value; float width = (float)svgElm.Width.AnimVal.Value; float height = (float)svgElm.Height.AnimVal.Value; RectangleF elmRect = new RectangleF(x, y, width, height); //if (element.ParentNode is SvgElement) //{ // // TODO: should it be moved with x and y? //} FitToViewbox(graphics, elmRect); }
public override void Render(GdiGraphicsRenderer renderer) { _graphics = renderer.GraphicsWrapper; SvgRenderingHint hint = element.RenderingHint; if (hint == SvgRenderingHint.Clipping) { return; } if (element.ParentNode is SvgClipPathElement) { return; } SvgTextElement textElement = element as SvgTextElement; if (textElement == null) { return; } string sVisibility = textElement.GetPropertyValue("visibility"); string sDisplay = textElement.GetPropertyValue("display"); if (String.Equals(sVisibility, "hidden") || String.Equals(sDisplay, "none")) { return; } Clip(_graphics); PointF ctp = new PointF(0, 0); // current text position ctp = GetCurrentTextPosition(textElement, ctp); string sBaselineShift = textElement.GetPropertyValue("baseline-shift").Trim(); double shiftBy = 0; if (sBaselineShift.Length > 0) { float textFontSize = GetComputedFontSize(textElement); if (sBaselineShift.EndsWith("%")) { shiftBy = SvgNumber.ParseNumber(sBaselineShift.Substring(0, sBaselineShift.Length - 1)) / 100 * textFontSize; } else if (sBaselineShift == "sub") { shiftBy = -0.6F * textFontSize; } else if (sBaselineShift == "super") { shiftBy = 0.6F * textFontSize; } else if (sBaselineShift == "baseline") { shiftBy = 0; } else { shiftBy = SvgNumber.ParseNumber(sBaselineShift); } } XmlNodeType nodeType = XmlNodeType.None; foreach (XmlNode child in element.ChildNodes) { SvgStyleableElement stylable = child as SvgStyleableElement; if (stylable != null) { sVisibility = stylable.GetPropertyValue("visibility"); sDisplay = stylable.GetPropertyValue("display"); if (String.Equals(sVisibility, "hidden") || String.Equals(sDisplay, "none")) { continue; } } nodeType = child.NodeType; if (nodeType == XmlNodeType.Text) { ctp.Y -= (float)shiftBy; AddGraphicsPath(textElement, ref ctp, GetText(textElement, child)); ctp.Y += (float)shiftBy; } else if (nodeType == XmlNodeType.Element) { string nodeName = child.Name; if (String.Equals(nodeName, "tref")) { AddTRefElementPath((SvgTRefElement)child, ref ctp); } else if (String.Equals(nodeName, "tspan")) { AddTSpanElementPath((SvgTSpanElement)child, ref ctp); } } } PaintMarkers(renderer, textElement, _graphics); _graphics = null; }
protected void SetQuality(GdiGraphicsWrapper gr) { Graphics graphics = gr.Graphics; string colorRendering = ((SvgElement)element).GetComputedStringValue("color-rendering", String.Empty); switch (colorRendering) { case "optimizeSpeed": graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed; break; case "optimizeQuality": graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; break; default: // "auto" // todo: could use AssumeLinear for slightly better graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.Default; break; } if (element is SvgTextContentElement) { // Unfortunately the text rendering hints are not applied because the // text path is recorded and painted to the Graphics object as a path // not as text. string textRendering = ((SvgElement)element).GetComputedStringValue("text-rendering", String.Empty); switch (textRendering) { case "optimizeSpeed": graphics.SmoothingMode = SmoothingMode.HighSpeed; //graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixel; break; case "optimizeLegibility": graphics.SmoothingMode = SmoothingMode.HighQuality; //graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; break; case "geometricPrecision": graphics.SmoothingMode = SmoothingMode.AntiAlias; //graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; break; default: // "auto" graphics.SmoothingMode = SmoothingMode.AntiAlias; //graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault; break; } } else { string shapeRendering = ((SvgElement)element).GetComputedStringValue("shape-rendering", String.Empty); switch (shapeRendering) { case "optimizeSpeed": graphics.SmoothingMode = SmoothingMode.HighSpeed; break; case "crispEdges": graphics.SmoothingMode = SmoothingMode.None; break; case "geometricPrecision": graphics.SmoothingMode = SmoothingMode.HighQuality; break; default: // "auto" graphics.SmoothingMode = SmoothingMode.AntiAlias; break; } } }
protected void Clip(GdiGraphicsWrapper gr) { if (element == null) { return; } SvgRenderingHint hint = element.RenderingHint; // todo: should we correct the clipping to adjust to the off-one-pixel drawing? gr.TranslateClip(1, 1); #region Clip with clip // see http://www.w3.org/TR/SVG/masking.html#OverflowAndClipProperties if (element is ISvgSvgElement || element is ISvgMarkerElement || element is ISvgSymbolElement || element is ISvgPatternElement) { // check overflow property CssValue overflow = ((SvgElement)element).GetComputedCssValue("overflow", String.Empty) as CssValue; // TODO: clip can have "rect(10 10 auto 10)" CssPrimitiveValue clip = ((SvgElement)element).GetComputedCssValue("clip", String.Empty) as CssPrimitiveValue; string sOverflow = null; if (overflow != null || overflow.CssText == "") { sOverflow = overflow.CssText; } else { if (this is ISvgSvgElement) sOverflow = "hidden"; } if (sOverflow != null) { // "If the 'overflow' property has a value other than hidden or scroll, the property has no effect (i.e., a clipping rectangle is not created)." if (sOverflow == "hidden" || sOverflow == "scroll") { RectangleF clipRect = RectangleF.Empty; if (clip != null && clip.PrimitiveType == CssPrimitiveType.Rect) { if (element is ISvgSvgElement) { ISvgSvgElement svgElement = (ISvgSvgElement)element; SvgRect viewPort = svgElement.Viewport as SvgRect; clipRect = GdiConverter.ToRectangle(viewPort); ICssRect clipShape = (CssRect)clip.GetRectValue(); if (clipShape.Top.PrimitiveType != CssPrimitiveType.Ident) clipRect.Y += (float)clipShape.Top.GetFloatValue(CssPrimitiveType.Number); if (clipShape.Left.PrimitiveType != CssPrimitiveType.Ident) clipRect.X += (float)clipShape.Left.GetFloatValue(CssPrimitiveType.Number); if (clipShape.Right.PrimitiveType != CssPrimitiveType.Ident) clipRect.Width = (clipRect.Right - clipRect.X) - (float)clipShape.Right.GetFloatValue(CssPrimitiveType.Number); if (clipShape.Bottom.PrimitiveType != CssPrimitiveType.Ident) clipRect.Height = (clipRect.Bottom - clipRect.Y) - (float)clipShape.Bottom.GetFloatValue(CssPrimitiveType.Number); } } else if (clip == null || (clip.PrimitiveType == CssPrimitiveType.Ident && clip.GetStringValue() == "auto")) { if (element is ISvgSvgElement) { ISvgSvgElement svgElement = (ISvgSvgElement)element; SvgRect viewPort = svgElement.Viewport as SvgRect; clipRect = GdiConverter.ToRectangle(viewPort); } else if (element is ISvgMarkerElement || element is ISvgSymbolElement || element is ISvgPatternElement) { // TODO: what to do here? } } if (clipRect != RectangleF.Empty) { gr.SetClip(clipRect); } } } } #endregion #region Clip with clip-path // see: http://www.w3.org/TR/SVG/masking.html#EstablishingANewClippingPath if (hint == SvgRenderingHint.Shape || hint == SvgRenderingHint.Text || hint == SvgRenderingHint.Clipping || hint == SvgRenderingHint.Masking || hint == SvgRenderingHint.Containment) { CssPrimitiveValue clipPath = ((SvgElement)element).GetComputedCssValue("clip-path", String.Empty) as CssPrimitiveValue; if (clipPath != null && clipPath.PrimitiveType == CssPrimitiveType.Uri) { string absoluteUri = ((SvgElement)element).ResolveUri(clipPath.GetStringValue()); SvgClipPathElement eClipPath = element.OwnerDocument.GetNodeByUri(absoluteUri) as SvgClipPathElement; if (eClipPath != null) { GraphicsPath gpClip = CreateClippingRegion(eClipPath); RectangleF clipBounds = gpClip != null ? gpClip.GetBounds() : RectangleF.Empty; if (clipBounds.Width == 0 || clipBounds.Height == 0) { return; } SvgUnitType pathUnits = (SvgUnitType)eClipPath.ClipPathUnits.AnimVal; if (pathUnits == SvgUnitType.ObjectBoundingBox) { SvgTransformableElement transElement = element as SvgTransformableElement; if (transElement != null) { ISvgRect bbox = transElement.GetBBox(); // scale clipping path Matrix matrix = new Matrix(); matrix.Scale((float)bbox.Width, (float)bbox.Height); gpClip.Transform(matrix); gr.SetClip(gpClip); // offset clip gr.TranslateClip((float)bbox.X, (float)bbox.Y); } else { throw new NotImplementedException("clip-path with SvgUnitType.ObjectBoundingBox " + "not supported for this type of element: " + element.GetType()); } } else { gr.SetClip(gpClip); } gpClip.Dispose(); gpClip = null; } } } #endregion }
protected void Clip(GdiGraphicsWrapper gr) { if (element == null) { return; } SvgRenderingHint hint = element.RenderingHint; // todo: should we correct the clipping to adjust to the off-one-pixel drawing? gr.TranslateClip(1, 1); #region Clip with clip // see http://www.w3.org/TR/SVG/masking.html#OverflowAndClipProperties if (element is ISvgSvgElement || element is ISvgMarkerElement || element is ISvgSymbolElement || element is ISvgPatternElement) { // check overflow property CssValue overflow = ((SvgElement)element).GetComputedCssValue("overflow", String.Empty) as CssValue; // TODO: clip can have "rect(10 10 auto 10)" CssPrimitiveValue clip = ((SvgElement)element).GetComputedCssValue("clip", String.Empty) as CssPrimitiveValue; string sOverflow = null; if (overflow != null || overflow.CssText == "") { sOverflow = overflow.CssText; } else { if (this is ISvgSvgElement) { sOverflow = "hidden"; } } if (sOverflow != null) { // "If the 'overflow' property has a value other than hidden or scroll, the property has no effect (i.e., a clipping rectangle is not created)." if (sOverflow == "hidden" || sOverflow == "scroll") { RectangleF clipRect = RectangleF.Empty; if (clip != null && clip.PrimitiveType == CssPrimitiveType.Rect) { if (element is ISvgSvgElement) { ISvgSvgElement svgElement = (ISvgSvgElement)element; SvgRect viewPort = svgElement.Viewport as SvgRect; clipRect = GdiConverter.ToRectangle(viewPort); ICssRect clipShape = (CssRect)clip.GetRectValue(); if (clipShape.Top.PrimitiveType != CssPrimitiveType.Ident) { clipRect.Y += (float)clipShape.Top.GetFloatValue(CssPrimitiveType.Number); } if (clipShape.Left.PrimitiveType != CssPrimitiveType.Ident) { clipRect.X += (float)clipShape.Left.GetFloatValue(CssPrimitiveType.Number); } if (clipShape.Right.PrimitiveType != CssPrimitiveType.Ident) { clipRect.Width = (clipRect.Right - clipRect.X) - (float)clipShape.Right.GetFloatValue(CssPrimitiveType.Number); } if (clipShape.Bottom.PrimitiveType != CssPrimitiveType.Ident) { clipRect.Height = (clipRect.Bottom - clipRect.Y) - (float)clipShape.Bottom.GetFloatValue(CssPrimitiveType.Number); } } } else if (clip == null || (clip.PrimitiveType == CssPrimitiveType.Ident && clip.GetStringValue() == "auto")) { if (element is ISvgSvgElement) { ISvgSvgElement svgElement = (ISvgSvgElement)element; SvgRect viewPort = svgElement.Viewport as SvgRect; clipRect = GdiConverter.ToRectangle(viewPort); } else if (element is ISvgMarkerElement || element is ISvgSymbolElement || element is ISvgPatternElement) { // TODO: what to do here? } } if (clipRect != RectangleF.Empty) { gr.SetClip(clipRect); } } } } #endregion #region Clip with clip-path // see: http://www.w3.org/TR/SVG/masking.html#EstablishingANewClippingPath if (hint == SvgRenderingHint.Shape || hint == SvgRenderingHint.Text || hint == SvgRenderingHint.Clipping || hint == SvgRenderingHint.Masking || hint == SvgRenderingHint.Containment) { CssPrimitiveValue clipPath = ((SvgElement)element).GetComputedCssValue("clip-path", String.Empty) as CssPrimitiveValue; if (clipPath != null && clipPath.PrimitiveType == CssPrimitiveType.Uri) { string absoluteUri = ((SvgElement)element).ResolveUri(clipPath.GetStringValue()); SvgClipPathElement eClipPath = element.OwnerDocument.GetNodeByUri(absoluteUri) as SvgClipPathElement; if (eClipPath != null) { GraphicsPath gpClip = CreateClippingRegion(eClipPath); RectangleF clipBounds = gpClip != null?gpClip.GetBounds() : RectangleF.Empty; if (clipBounds.Width == 0 || clipBounds.Height == 0) { return; } SvgUnitType pathUnits = (SvgUnitType)eClipPath.ClipPathUnits.AnimVal; if (pathUnits == SvgUnitType.ObjectBoundingBox) { SvgTransformableElement transElement = element as SvgTransformableElement; if (transElement != null) { ISvgRect bbox = transElement.GetBBox(); // scale clipping path Matrix matrix = new Matrix(); matrix.Scale((float)bbox.Width, (float)bbox.Height); gpClip.Transform(matrix); gr.SetClip(gpClip); // offset clip gr.TranslateClip((float)bbox.X, (float)bbox.Y); } else { throw new NotImplementedException("clip-path with SvgUnitType.ObjectBoundingBox " + "not supported for this type of element: " + element.GetType()); } } else { gr.SetClip(gpClip); } gpClip.Dispose(); gpClip = null; } } } #endregion }
public override void Render(GdiGraphicsRenderer renderer) { GdiGraphicsWrapper graphics = renderer.GraphicsWrapper; SvgImageElement iElement = (SvgImageElement)element; ImageAttributes imageAttributes = new ImageAttributes(); string sOpacity = iElement.GetPropertyValue("opacity"); if (sOpacity != null && sOpacity.Length > 0) { double opacity = SvgNumber.ParseNumber(sOpacity); ColorMatrix myColorMatrix = new ColorMatrix(); myColorMatrix.Matrix00 = 1.00f; // Red myColorMatrix.Matrix11 = 1.00f; // Green myColorMatrix.Matrix22 = 1.00f; // Blue myColorMatrix.Matrix33 = (float)opacity; // alpha myColorMatrix.Matrix44 = 1.00f; // w imageAttributes.SetColorMatrix(myColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); } float width = (float)iElement.Width.AnimVal.Value; float height = (float)iElement.Height.AnimVal.Value; Rectangle destRect = new Rectangle(Convert.ToInt32(iElement.X.AnimVal.Value), Convert.ToInt32(iElement.Y.AnimVal.Value), Convert.ToInt32(width), Convert.ToInt32(height)); Image image = null; if (iElement.IsSvgImage) { SvgWindow wnd = GetSvgWindow(); _embeddedRenderer.BackColor = Color.Empty; _embeddedRenderer.Render(wnd.Document); image = _embeddedRenderer.RasterImage; } else { image = GetBitmap(iElement); } if (image != null) { graphics.DrawImage(this, image, destRect, 0f, 0f, image.Width, image.Height, GraphicsUnit.Pixel, imageAttributes); image.Dispose(); image = null; } if (_embeddedRenderer != null) { _embeddedRenderer.Dispose(); _embeddedRenderer = null; } if (imageAttributes != null) { imageAttributes.Dispose(); imageAttributes = null; } }
public override void Render(GdiGraphicsRenderer renderer) { _graphics = renderer.GraphicsWrapper; SvgRenderingHint hint = element.RenderingHint; if (hint == SvgRenderingHint.Clipping) { return; } if (element.ParentNode is SvgClipPathElement) { return; } SvgTextElement textElement = element as SvgTextElement; if (textElement == null) { return; } string sVisibility = textElement.GetPropertyValue("visibility"); string sDisplay = textElement.GetPropertyValue("display"); if (String.Equals(sVisibility, "hidden") || String.Equals(sDisplay, "none")) { return; } Clip(_graphics); PointF ctp = new PointF(0, 0); // current text position ctp = GetCurrentTextPosition(textElement, ctp); string sBaselineShift = textElement.GetPropertyValue("baseline-shift").Trim(); double shiftBy = 0; if (sBaselineShift.Length > 0) { float textFontSize = GetComputedFontSize(textElement); if (sBaselineShift.EndsWith("%")) { shiftBy = SvgNumber.ParseNumber(sBaselineShift.Substring(0, sBaselineShift.Length - 1)) / 100 * textFontSize; } else if (sBaselineShift == "sub") { shiftBy = -0.6F * textFontSize; } else if (sBaselineShift == "super") { shiftBy = 0.6F * textFontSize; } else if (sBaselineShift == "baseline") { shiftBy = 0; } else { shiftBy = SvgNumber.ParseNumber(sBaselineShift); } } XmlNodeType nodeType = XmlNodeType.None; foreach (XmlNode child in element.ChildNodes) { nodeType = child.NodeType; if (nodeType == XmlNodeType.Text) { ctp.Y -= (float)shiftBy; AddGraphicsPath(textElement, ref ctp, GetText(textElement, child)); ctp.Y += (float)shiftBy; } else if (nodeType == XmlNodeType.Element) { string nodeName = child.Name; if (String.Equals(nodeName, "tref")) { AddTRefElementPath((SvgTRefElement)child, ref ctp); } else if (String.Equals(nodeName, "tspan")) { AddTSpanElementPath((SvgTSpanElement)child, ref ctp); } } } PaintMarkers(renderer, textElement, _graphics); _graphics = null; }
public static GdiGraphics Create(Image image, bool isStatic) { return(GdiGraphicsWrapper.FromImage(image, isStatic)); }
public override void Render(GdiGraphicsRenderer renderer) { GdiGraphicsWrapper graphics = renderer.GraphicsWrapper; SvgImageElement iElement = (SvgImageElement)element; ImageAttributes imageAttributes = new ImageAttributes(); string sOpacity = iElement.GetPropertyValue("opacity"); if (sOpacity != null && sOpacity.Length > 0) { double opacity = SvgNumber.ParseNumber(sOpacity); ColorMatrix myColorMatrix = new ColorMatrix(); myColorMatrix.Matrix00 = 1.00f; // Red myColorMatrix.Matrix11 = 1.00f; // Green myColorMatrix.Matrix22 = 1.00f; // Blue myColorMatrix.Matrix33 = (float)opacity; // alpha myColorMatrix.Matrix44 = 1.00f; // w imageAttributes.SetColorMatrix(myColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); } float width = (float)iElement.Width.AnimVal.Value; float height = (float)iElement.Height.AnimVal.Value; //Rectangle destRect = new Rectangle(Convert.ToInt32(iElement.X.AnimVal.Value), // Convert.ToInt32(iElement.Y.AnimVal.Value), // Convert.ToInt32(width), Convert.ToInt32(height)); RectangleF destRect = new RectangleF((float)iElement.X.AnimVal.Value, (float)iElement.Y.AnimVal.Value, (float)iElement.Width.AnimVal.Value, (float)iElement.Height.AnimVal.Value); Image image = null; if (iElement.IsSvgImage) { SvgWindow wnd = GetSvgWindow(); _embeddedRenderer.BackColor = Color.Empty; _embeddedRenderer.Render(wnd.Document); image = _embeddedRenderer.RasterImage; } else { image = GetBitmap(iElement); } if (image != null) { //graphics.DrawImage(this, image, destRect, 0f, 0f, // image.Width, image.Height, GraphicsUnit.Pixel, imageAttributes); // code extracted from FitToViewbox SvgPreserveAspectRatio spar = (SvgPreserveAspectRatio)iElement.PreserveAspectRatio.AnimVal ?? new SvgPreserveAspectRatio("none", iElement); double[] translateAndScale = spar.FitToViewBox(new SvgRect(0, 0, image.Width, image.Height), new SvgRect(destRect.X, destRect.Y, destRect.Width, destRect.Height)); graphics.TranslateTransform((float)translateAndScale[0], (float)translateAndScale[1]); graphics.ScaleTransform((float)translateAndScale[2], (float)translateAndScale[3]); graphics.DrawImage(this, image, new Rectangle(0, 0, image.Width, image.Height), 0f, 0f, image.Width, image.Height, GraphicsUnit.Pixel, imageAttributes); image.Dispose(); image = null; } if (_embeddedRenderer != null) { _embeddedRenderer.Dispose(); _embeddedRenderer = null; } if (imageAttributes != null) { imageAttributes.Dispose(); imageAttributes = null; } }
public void PaintMarker(GdiGraphicsRenderer renderer, GdiGraphicsWrapper gr, SvgMarkerPosition markerPos, SvgStyleableElement refElement) { ISharpMarkerHost markerHostElm = (ISharpMarkerHost)refElement; SvgMarkerElement markerElm = (SvgMarkerElement)element; SvgPointF[] vertexPositions = markerHostElm.MarkerPositions; int start; int len; // Choose which part of the position array to use switch (markerPos) { case SvgMarkerPosition.Start: start = 0; len = 1; break; case SvgMarkerPosition.Mid: start = 1; len = vertexPositions.Length - 2; break; default: // == MarkerPosition.End start = vertexPositions.Length - 1; len = 1; break; } for (int i = start; i < start + len; i++) { SvgPointF point = vertexPositions[i]; GdiGraphicsContainer gc = gr.BeginContainer(); gr.TranslateTransform(point.X, point.Y); if (markerElm.OrientType.AnimVal.Equals((ushort)SvgMarkerOrient.Angle)) { gr.RotateTransform((float)markerElm.OrientAngle.AnimVal.Value); } else { double angle; switch (markerPos) { case SvgMarkerPosition.Start: angle = markerHostElm.GetStartAngle(i + 1); break; case SvgMarkerPosition.Mid: //angle = (markerHostElm.GetEndAngle(i) + markerHostElm.GetStartAngle(i + 1)) / 2; angle = SvgNumber.CalcAngleBisection(markerHostElm.GetEndAngle(i), markerHostElm.GetStartAngle(i + 1)); break; default: angle = markerHostElm.GetEndAngle(i); break; } gr.RotateTransform((float)angle); } if (markerElm.MarkerUnits.AnimVal.Equals((ushort)SvgMarkerUnit.StrokeWidth)) { SvgLength strokeWidthLength = new SvgLength(refElement, "stroke-width", SvgLengthSource.Css, SvgLengthDirection.Viewport, "1"); float strokeWidth = (float)strokeWidthLength.Value; gr.ScaleTransform(strokeWidth, strokeWidth); } SvgPreserveAspectRatio spar = (SvgPreserveAspectRatio)markerElm.PreserveAspectRatio.AnimVal; double[] translateAndScale = spar.FitToViewBox((SvgRect)markerElm.ViewBox.AnimVal, new SvgRect(0, 0, markerElm.MarkerWidth.AnimVal.Value, markerElm.MarkerHeight.AnimVal.Value)); gr.TranslateTransform(-(float)(markerElm.RefX.AnimVal.Value * translateAndScale[2]), -(float)(markerElm.RefY.AnimVal.Value * translateAndScale[3])); gr.ScaleTransform((float)translateAndScale[2], (float)translateAndScale[3]); Clip(gr); renderer.RenderChildren(markerElm); gr.EndContainer(gc); } }
/// <summary> /// AfterRender - Dispose of Graphics object created for rendering. /// </summary> private void RendererAfterRender() { if (graphics != null) { // Check if we only invalidated a rect if (invalidRect != SvgRectF.Empty) { // We actually drew everything on invalidatedRasterImage and now we // need to copy that to rasterImage Graphics tempGraphics = Graphics.FromImage(rasterImage); tempGraphics.DrawImage(invalidatedRasterImage, invalidRect.X, invalidRect.Y, GdiConverter.ToRectangle(invalidRect), GraphicsUnit.Pixel); tempGraphics.Dispose(); tempGraphics = null; // If we currently have an idMapRaster here, then we need to create // a temporary graphics object to draw the invalidated portion from // our main graphics window onto it. if (idMapRaster != null) { tempGraphics = Graphics.FromImage(idMapRaster); tempGraphics.DrawImage(graphics.IdMapRaster, invalidRect.X, invalidRect.Y, GdiConverter.ToRectangle(invalidRect), GraphicsUnit.Pixel); tempGraphics.Dispose(); tempGraphics = null; } else { idMapRaster = graphics.IdMapRaster; } // We have updated the invalid region invalidRect = SvgRectF.Empty; } else { if (idMapRaster != null && idMapRaster != graphics.IdMapRaster) idMapRaster.Dispose(); idMapRaster = graphics.IdMapRaster; } graphics.Dispose(); graphics = null; } }
/// <summary> /// BeforeRender - Make sure we have a Graphics object to render to. /// If we don't have one, then create one to match the SvgWindow's /// physical dimensions. /// </summary> private void RendererBeforeRender() { // Testing for null here allows "advanced" developers to create their own Graphics object for rendering if (graphics == null) { // Get the current SVGWindow's width and height int innerWidth = (int)window.InnerWidth; int innerHeight = (int)window.InnerHeight; // Make sure we have an actual area to render to if (innerWidth > 0 && innerHeight > 0) { // See if we already have a rasterImage that matches the current SVGWindow dimensions if (rasterImage == null || rasterImage.Width != innerWidth || rasterImage.Height != innerHeight) { // Nope, so create one if (rasterImage != null) { rasterImage.Dispose(); rasterImage = null; } rasterImage = new Bitmap(innerWidth, innerHeight); } // Maybe we are only repainting an invalidated section if (invalidRect != SvgRectF.Empty) { // TODO: Worry about pan... if (invalidRect.X < 0) invalidRect.X = 0; if (invalidRect.Y < 0) invalidRect.Y = 0; if (invalidRect.Right > innerWidth) invalidRect.Width = innerWidth - invalidRect.X; if (invalidRect.Bottom > innerHeight) invalidRect.Height = innerHeight - invalidRect.Y; if (invalidatedRasterImage == null || invalidatedRasterImage.Width < invalidRect.Right || invalidatedRasterImage.Height < invalidRect.Bottom) { // Nope, so create one if (invalidatedRasterImage != null) { invalidatedRasterImage.Dispose(); invalidatedRasterImage = null; } invalidatedRasterImage = new Bitmap((int)invalidRect.Right, (int)invalidRect.Bottom); } // Make a GraphicsWrapper object from the regionRasterImage and clear it to the background color graphics = GdiGraphicsWrapper.FromImage(invalidatedRasterImage, false); graphics.Clear(backColor); } else { // Make a GraphicsWrapper object from the rasterImage and clear it to the background color graphics = GdiGraphicsWrapper.FromImage(rasterImage, false); graphics.Clear(backColor); } } } }
/// <summary> /// BeforeRender - Make sure we have a Graphics object to render to. /// If we don't have one, then create one to match the SvgWindow's /// physical dimensions. /// </summary> private void RendererBeforeRender() { // Testing for null here allows "advanced" developers to create their own Graphics object for rendering if (graphics == null) { // Get the current SVGWindow's width and height int innerWidth = (int)window.InnerWidth; int innerHeight = (int)window.InnerHeight; // Make sure we have an actual area to render to if (innerWidth > 0 && innerHeight > 0) { // See if we already have a rasterImage that matches the current SVGWindow dimensions if (rasterImage == null || rasterImage.Width != innerWidth || rasterImage.Height != innerHeight) { // Nope, so create one if (rasterImage != null) { rasterImage.Dispose(); rasterImage = null; } rasterImage = new Bitmap(innerWidth, innerHeight); } // Maybe we are only repainting an invalidated section if (invalidRect != SvgRectF.Empty) { // TODO: Worry about pan... if (invalidRect.X < 0) { invalidRect.X = 0; } if (invalidRect.Y < 0) { invalidRect.Y = 0; } if (invalidRect.Right > innerWidth) { invalidRect.Width = innerWidth - invalidRect.X; } if (invalidRect.Bottom > innerHeight) { invalidRect.Height = innerHeight - invalidRect.Y; } if (invalidatedRasterImage == null || invalidatedRasterImage.Width < invalidRect.Right || invalidatedRasterImage.Height < invalidRect.Bottom) { // Nope, so create one if (invalidatedRasterImage != null) { invalidatedRasterImage.Dispose(); invalidatedRasterImage = null; } invalidatedRasterImage = new Bitmap((int)invalidRect.Right, (int)invalidRect.Bottom); } // Make a GraphicsWrapper object from the regionRasterImage and clear it to the background color graphics = GdiGraphicsWrapper.FromImage(invalidatedRasterImage, false); graphics.Clear(backColor); } else { // Make a GraphicsWrapper object from the rasterImage and clear it to the background color graphics = GdiGraphicsWrapper.FromImage(rasterImage, false); graphics.Clear(backColor); } } } }
public void PaintMarker(GdiGraphicsRenderer renderer, GdiGraphicsWrapper gr, SvgMarkerPosition markerPos, SvgStyleableElement refElement) { ISharpMarkerHost markerHostElm = (ISharpMarkerHost)refElement; SvgMarkerElement markerElm = (SvgMarkerElement) element; SvgPointF[] vertexPositions = markerHostElm.MarkerPositions; int start; int len; // Choose which part of the position array to use switch (markerPos) { case SvgMarkerPosition.Start: start = 0; len = 1; break; case SvgMarkerPosition.Mid: start = 1; len = vertexPositions.Length - 2; break; default: // == MarkerPosition.End start = vertexPositions.Length-1; len = 1; break; } for (int i = start; i < start+len; i++) { SvgPointF point = vertexPositions[i]; GdiGraphicsContainer gc = gr.BeginContainer(); gr.TranslateTransform(point.X, point.Y); if (markerElm.OrientType.AnimVal.Equals(SvgMarkerOrient.Angle)) { gr.RotateTransform((float)markerElm.OrientAngle.AnimVal.Value); } else { double angle; switch(markerPos) { case SvgMarkerPosition.Start: angle = markerHostElm.GetStartAngle(i + 1); break; case SvgMarkerPosition.Mid: //angle = (markerHostElm.GetEndAngle(i) + markerHostElm.GetStartAngle(i + 1)) / 2; angle = SvgNumber.CalcAngleBisection(markerHostElm.GetEndAngle(i), markerHostElm.GetStartAngle(i + 1)); break; default: angle = markerHostElm.GetEndAngle(i); break; } gr.RotateTransform((float)angle); } if (markerElm.MarkerUnits.AnimVal.Equals(SvgMarkerUnit.StrokeWidth)) { SvgLength strokeWidthLength = new SvgLength(refElement, "stroke-width", SvgLengthSource.Css, SvgLengthDirection.Viewport, "1"); float strokeWidth = (float)strokeWidthLength.Value; gr.ScaleTransform(strokeWidth, strokeWidth); } SvgPreserveAspectRatio spar = (SvgPreserveAspectRatio)markerElm.PreserveAspectRatio.AnimVal; double[] translateAndScale = spar.FitToViewBox((SvgRect)markerElm.ViewBox.AnimVal, new SvgRect(0, 0, markerElm.MarkerWidth.AnimVal.Value, markerElm.MarkerHeight.AnimVal.Value)); gr.TranslateTransform(-(float)(markerElm.RefX.AnimVal.Value * translateAndScale[2]), -(float)(markerElm.RefY.AnimVal.Value * translateAndScale[3])); gr.ScaleTransform((float)translateAndScale[2], (float)translateAndScale[3]); Clip(gr); renderer.RenderChildren(markerElm); gr.EndContainer(gc); } }
public override void Render(GdiGraphicsRenderer renderer) { GdiGraphicsWrapper graphics = renderer.GraphicsWrapper; SvgRenderingHint hint = element.RenderingHint; if (hint != SvgRenderingHint.Shape || hint == SvgRenderingHint.Clipping) { return; } if (element.ParentNode is SvgClipPathElement) { return; } SvgStyleableElement styleElm = (SvgStyleableElement)element; string sVisibility = styleElm.GetPropertyValue("visibility"); string sDisplay = styleElm.GetPropertyValue("display"); if (string.Equals(sVisibility, "hidden") || string.Equals(sDisplay, "none")) { return; } GraphicsPath gp = CreatePath(element); if (gp != null) { Clip(graphics); GdiSvgPaint fillPaint = new GdiSvgPaint(styleElm, "fill"); Brush brush = fillPaint.GetBrush(gp); GdiSvgPaint strokePaint = new GdiSvgPaint(styleElm, "stroke"); Pen pen = strokePaint.GetPen(gp); if (brush != null) { if (brush is PathGradientBrush) { GdiGradientFill gps = fillPaint.PaintFill as GdiGradientFill; graphics.SetClip(gps.GetRadialGradientRegion(gp.GetBounds()), CombineMode.Exclude); SolidBrush tempBrush = new SolidBrush(((PathGradientBrush)brush).InterpolationColors.Colors[0]); graphics.FillPath(this, tempBrush, gp); tempBrush.Dispose(); graphics.ResetClip(); } graphics.FillPath(this, brush, gp); brush.Dispose(); brush = null; } if (pen != null) { if (pen.Brush is PathGradientBrush) { GdiGradientFill gps = strokePaint.PaintFill as GdiGradientFill; GdiGraphicsContainer container = graphics.BeginContainer(); graphics.SetClip(gps.GetRadialGradientRegion(gp.GetBounds()), CombineMode.Exclude); SolidBrush tempBrush = new SolidBrush(((PathGradientBrush)pen.Brush).InterpolationColors.Colors[0]); Pen tempPen = new Pen(tempBrush, pen.Width); graphics.DrawPath(this, tempPen, gp); tempPen.Dispose(); tempBrush.Dispose(); graphics.EndContainer(container); } graphics.DrawPath(this, pen, gp); pen.Dispose(); pen = null; } gp.Dispose(); gp = null; } PaintMarkers(renderer, styleElm, graphics); }