internal SvgSvgElement(INode parent, XmlElement element) : base(parent, element) { this._stylableHelper = new SvgStylableHelper(this, element); this.ViewPort = SvgRect.Parse(element.GetAttribute("viewBox")); }
public rectangleData(SvgRect svg) { style = svg.Style; if (style == "") { Color cColor = svg.Stroke; strokeColor = Convert.ToString(cColor.R) + Convert.ToString(cColor.G) + Convert.ToString(cColor.B); strokeWidth = svg.StrokeWidth; Color fColor = svg.Fill; fillColor = Convert.ToString(fColor.R) + Convert.ToString(fColor.G) + Convert.ToString(fColor.B); } else { //get from style attribute extractStyle rStyle = new extractStyle(); rStyle.getStyle(style); Color sCol = ColorTranslator.FromHtml(rStyle.strokeColour); Color fCol = ColorTranslator.FromHtml(rStyle.fillColour); strokeColor = Convert.ToString(sCol.R) + Convert.ToString(sCol.G) + Convert.ToString(sCol.B); strokeWidth = rStyle.strokeWidth; fillColor = Convert.ToString(fCol.R) + Convert.ToString(fCol.G) + Convert.ToString(fCol.B); } xpos = Convert.ToDouble(svg.X); ypos = Convert.ToDouble(svg.Y); rHeight = Convert.ToDouble(svg.Height); rWidth = Convert.ToDouble(svg.Width); Id = svg.Id; }
private Transform FitToViewbox(SvgRect viewBox, Rect rectToFit) { SvgPreserveAspectRatioType alignment = SvgPreserveAspectRatioType.XMidYMid; double[] transformArray = FitToViewBox(alignment, viewBox, new SvgRect(rectToFit.X, rectToFit.Y, rectToFit.Width, rectToFit.Height)); double translateX = transformArray[0]; double translateY = transformArray[1]; double scaleX = transformArray[2]; double scaleY = transformArray[3]; Transform translateMatrix = null; Transform scaleMatrix = null; if (!translateX.Equals(0) || !translateY.Equals(0)) { translateMatrix = new TranslateTransform(translateX, translateY); } if (!scaleX.Equals(1.0f) || !scaleY.Equals(1.0f)) { scaleMatrix = new ScaleTransform(scaleX, scaleY); } if (translateMatrix != null && scaleMatrix != null) { // Create a TransformGroup to contain the transforms // and add the transforms to it. if (translateMatrix.Value.IsIdentity && scaleMatrix.Value.IsIdentity) { return(null); } if (translateMatrix.Value.IsIdentity) { return(scaleMatrix); } if (scaleMatrix.Value.IsIdentity) { return(translateMatrix); } TransformGroup transformGroup = new TransformGroup(); transformGroup.Children.Add(scaleMatrix); transformGroup.Children.Add(translateMatrix); return(transformGroup); } if (translateMatrix != null) { return(translateMatrix.Value.IsIdentity ? null : translateMatrix); } if (scaleMatrix != null) { return(scaleMatrix.Value.IsIdentity ? null : scaleMatrix); } return(null); }
public static RectangleF ToRectangle(SvgRect rect) { if (rect == null) { return(RectangleF.Empty); } return(new RectangleF((float)rect.X, (float)rect.Y, (float)rect.Width, (float)rect.Height)); }
private static SvgPath RectToPath(SvgRect rect) { return(new SvgPath { Fill = rect.Fill, Stroke = rect.Stroke, StrokeWidth = rect.StrokeWidth, Path = Math.Path.CreateRectanglePath(rect.X, rect.Y, rect.Width, rect.Height).ToPathCommands() }); }
private RectangleF CalculatePagePlacementRect(SvgRect bbox) { var x1 = (bbox.X * _pageViewport.ScaleX) + _pageViewport.OffsetX; var y1 = (bbox.Y * _pageViewport.ScaleY) + _pageViewport.OffsetY; var x2 = (bbox.Right * _pageViewport.ScaleX) + _pageViewport.OffsetX; var y2 = (bbox.Bottom * _pageViewport.ScaleY) + _pageViewport.OffsetY; var pageX = x1 + _pageViewport.PagePlacement.X; var pageY = _pageHeight - (y1 + _pageViewport.PagePlacement.Y); // invert the Y coordinate here for PDF space var pdfPagePlacementRect = new RectangleF(pageX, pageY, x2 - x1, y2 - y1); return(pdfPagePlacementRect); }
public override SvgBasicShape ToSVGLibShape(SvgDoc doc) { var res = new SvgRect(doc, rx.ToString() + "px", ry.ToString() + "px", width.ToString() + "px", height.ToString() + "px", w.ToString() + "px", System.Drawing.Color.FromArgb(fill.A, fill.R, fill.G, fill.B), System.Drawing.Color.FromArgb(stroke.A, stroke.R, stroke.G, stroke.B) ); return(res); }
private Transform FitToViewbox(SvgRect viewBox, Rect rectToFit) { SvgPreserveAspectRatioType alignment = SvgPreserveAspectRatioType.XMidYMid; double[] transformArray = FitToViewBox(alignment, viewBox, new SvgRect(rectToFit.X, rectToFit.Y, rectToFit.Width, rectToFit.Height)); double translateX = transformArray[0]; double translateY = transformArray[1]; double scaleX = transformArray[2]; double scaleY = transformArray[3]; Transform translateMatrix = null; Transform scaleMatrix = null; if (translateX != 0 || translateY != 0) { translateMatrix = new TranslateTransform(translateX, translateY); } if ((float)scaleX != 1.0f && (float)scaleY != 1.0f) { scaleMatrix = new ScaleTransform(scaleX, scaleY); } if (translateMatrix != null && scaleMatrix != null) { // Create a TransformGroup to contain the transforms // and add the transforms to it. TransformGroup transformGroup = new TransformGroup(); transformGroup.Children.Add(scaleMatrix); transformGroup.Children.Add(translateMatrix); return(transformGroup); } else if (translateMatrix != null) { return(translateMatrix); } else if (scaleMatrix != null) { return(scaleMatrix); } return(null); }
private void AddRect() { if (!IsDocPresent()) { return; } SvgElement ele = GetCurrentSvgElement(); if (ele == null) { return; } SvgRect rect = m_svg.AddRect(ele); AddNodeToTree(rect); }
public static DrawRectangle Create(SvgRect svg) { try { var dobj = new DrawRectangle(ParseSize(svg.X, Dpi.X), ParseSize(svg.Y, Dpi.Y), ParseSize(svg.Width, Dpi.X), ParseSize(svg.Height, Dpi.Y)); dobj.SetStyleFromSvg(svg); dobj.Name = svg.ShapeName; return(dobj); } catch (Exception ex) { ErrH.Log("DrawRectangle", "CreateRectangle:", ex.ToString(), ErrH._LogPriority.Info); return(null); } }
public override void AfterRender(WpfDrawingRenderer renderer) { Debug.Assert(_drawGroup != null); WpfDrawingContext context = renderer.Context; DrawingGroup currentGroup = context.Peek(); if (currentGroup == null || currentGroup != _drawGroup) { throw new InvalidOperationException("An existing group is expected."); } ISvgAnimatedEnumeration markerUnits = _markerElement.MarkerUnits; if (markerUnits.AnimVal.Equals((ushort)SvgMarkerUnit.StrokeWidth)) { var comparer = StringComparison.OrdinalIgnoreCase; string overflowAttr = _markerElement.GetAttribute("overflow"); if (string.IsNullOrWhiteSpace(overflowAttr) || overflowAttr.Equals("scroll", comparer) || overflowAttr.Equals("hidden", comparer)) { Geometry markerClip = this.ClipGeometry; if (markerClip == null || markerClip.IsEmpty()) { SvgRect clipRect = (SvgRect)_markerElement.ViewBox.AnimVal; if (clipRect != null && !clipRect.IsEmpty) { _drawGroup.ClipGeometry = new RectangleGeometry( new Rect(clipRect.X, clipRect.Y, clipRect.Width, clipRect.Height)); } else if (_markerElement.IsSizeDefined) { _drawGroup.ClipGeometry = new RectangleGeometry(new Rect(0, 0, _markerElement.MarkerWidth.AnimVal.Value, _markerElement.MarkerHeight.AnimVal.Value)); } } } } context.Pop(); base.AfterRender(renderer); }
private Transform GetAspectRatioTransform(SvgPreserveAspectRatio spar, SvgRect sourceBounds, SvgRect elementBounds) { double[] transformArray = spar.FitToViewBox(sourceBounds, elementBounds); double translateX = transformArray[0]; double translateY = transformArray[1]; double scaleX = transformArray[2]; double scaleY = transformArray[3]; Transform translateMatrix = null; Transform scaleMatrix = null; if ((float)translateX >= 0 && (float)translateY >= 0) { translateMatrix = new TranslateTransform(translateX, translateY); } if ((float)scaleX != 1.0f && (float)scaleY != 1.0) { scaleMatrix = new ScaleTransform(scaleX, scaleY); } if (translateMatrix != null && scaleMatrix != null) { // Create a TransformGroup to contain the transforms // and add the transforms to it. TransformGroup transformGroup = new TransformGroup(); transformGroup.Children.Add(scaleMatrix); transformGroup.Children.Add(translateMatrix); return(transformGroup); } else if (translateMatrix != null) { return(translateMatrix); } else if (scaleMatrix != null) { return(scaleMatrix); } return(null); }
public void ReadContent(XmlElement xmlElement, SvgReader svgReader) { _rect = null; foreach (var node in xmlElement.ChildNodes) { var childElement = node as XmlElement; if (childElement != null) { var svgNode = svgReader.CreateSvgNodeFromXml(childElement); if (svgNode is SvgRect) { svgReader.Read(svgNode, childElement); _rect = svgNode as SvgRect; } else if (childElement.Name == "svg") { Svg = childElement.OuterXml; } } if (_rect != null && Svg != null) { break; } } if (_rect != null && Svg != null) { X = _rect.X; Y = _rect.Y; Width = _rect.Width; Height = _rect.Height; Fill = _rect.Fill; Stroke = _rect.Stroke; StrokeWidth = _rect.StrokeWidth; } else { throw new SvgParseException(Resources.Exceptions.CanNotParseSvgVoSvg); } }
public void SetGamePropsFromSvg(SvgRect svg) { var el = svg as SvgElement; ArrayList types = new ArrayList(); ArrayList names = new ArrayList(); ArrayList values = new ArrayList(); el.FillAttributeList(types, names, values); for (var x = 0; x < names.Count; x++) { if (names[x].ToString() == "data-IsPassable") { IsPassable = bool.Parse(values[x].ToString()); } if (names[x].ToString() == "data-IsDeath") { IsDeath = bool.Parse(values[x].ToString()); } } }
public void ReadContent(XmlElement xmlElement, SvgReader svgReader) { Transform = SvgAttribute.ParseTransformAttribute(xmlElement.GetAttribute("transform")); _rect = null; foreach (var node in xmlElement.ChildNodes) { var childElement = node as XmlElement; if (childElement != null) { var svgNode = svgReader.CreateSvgNodeFromXml(childElement); svgReader.Read(svgNode, childElement); if (svgNode is SvgRect) { _rect = svgNode as SvgRect; } } if (_rect != null) { break; } } if (_rect != null) { X = _rect.X + _rect.StrokeWidth / 2; Y = _rect.Y + _rect.StrokeWidth / 2; Width = _rect.Width - _rect.StrokeWidth; Height = _rect.Height - _rect.StrokeWidth; Fill = _rect.Fill; Stroke = _rect.Stroke; StrokeWidth = _rect.StrokeWidth; } else { throw new SvgParseException(Resources.Exceptions.CanNotParseSvgVoContent); } }
private static void Render2D(IBarcode barcode, Stream outputStream) { var document = SvgDocument.Create(); document.ViewBox = new SvgViewBox { Left = 0, Top = 0, Width = barcode.Bounds.X + 2 * barcode.Margin, Height = barcode.Bounds.Y + 2 * barcode.Margin }; document.Fill = "#FFFFFF"; document.Stroke = "#000000"; document.StrokeWidth = .05; document.StrokeLineCap = SvgStrokeLineCap.Butt; SvgGroup group = document.AddGroup(); group.Fill = "#000000"; for (int y = 0; y < barcode.Bounds.Y; y++) { for (int x = 0; x < barcode.Bounds.X; x++) { if (barcode.At(x, y)) { SvgRect rect = group.AddRect(); rect.X = x + barcode.Margin; rect.Y = y + barcode.Margin; rect.Width = 1; rect.Height = 1; } } } document.Save(outputStream); }
protected void SetClip(GdiGraphics graphics) { if (_svgElement == null) { return; } SvgRenderingHint hint = _svgElement.RenderingHint; // todo: should we correct the clipping to adjust to the off-one-pixel drawing? graphics.TranslateClip(1, 1); #region Clip with clip // see http://www.w3.org/TR/SVG/masking.html#OverflowAndClipProperties if (_svgElement is ISvgSvgElement || _svgElement is ISvgMarkerElement || _svgElement is ISvgSymbolElement || _svgElement is ISvgPatternElement) { // check overflow property CssValue overflow = _svgElement.GetComputedCssValue("overflow", string.Empty) as CssValue; // TODO: clip can have "rect(10 10 auto 10)" CssPrimitiveValue clip = _svgElement.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 (_svgElement is ISvgSvgElement) { ISvgSvgElement svgElement = (ISvgSvgElement)_svgElement; 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 (_svgElement is ISvgSvgElement) { ISvgSvgElement svgElement = (ISvgSvgElement)_svgElement; SvgRect viewPort = svgElement.Viewport as SvgRect; clipRect = GdiConverter.ToRectangle(viewPort); } else if (_svgElement is ISvgMarkerElement || _svgElement is ISvgSymbolElement || _svgElement is ISvgPatternElement) { // TODO: what to do here? } } if (clipRect != RectangleF.Empty) { graphics.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 || hint == SvgRenderingHint.Image) { CssPrimitiveValue clipPath = _svgElement.GetComputedCssValue("clip-path", string.Empty) as CssPrimitiveValue; if (clipPath != null && clipPath.PrimitiveType == CssPrimitiveType.Uri) { string absoluteUri = _svgElement.ResolveUri(clipPath.GetStringValue()); SvgClipPathElement eClipPath = _svgElement.OwnerDocument.GetNodeByUri(absoluteUri) as SvgClipPathElement; if (eClipPath != null) { GraphicsPath gpClip = CreateClippingRegion(graphics, eClipPath); RectangleF clipBounds = gpClip != null?gpClip.GetBounds() : RectangleF.Empty; if (clipBounds.Width.Equals(0) || clipBounds.Height.Equals(0)) { return; } SvgUnitType pathUnits = (SvgUnitType)eClipPath.ClipPathUnits.AnimVal; if (pathUnits == SvgUnitType.ObjectBoundingBox) { SvgTransformableElement transElement = _svgElement 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); graphics.SetClip(gpClip); // offset clip graphics.TranslateClip((float)bbox.X, (float)bbox.Y); } else { throw new NotImplementedException("clip-path with SvgUnitType.ObjectBoundingBox " + "not supported for this type of element: " + _svgElement.GetType()); } } else { graphics.SetClip(gpClip); } gpClip.Dispose(); gpClip = null; } } } #endregion }
protected void FitToViewbox(WpfDrawingContext context, SvgElement svgElement, Rect elementBounds) { if (svgElement == null) { return; } ISvgFitToViewBox fitToView = svgElement as ISvgFitToViewBox; if (fitToView == null) { return; } SvgPreserveAspectRatio spar = (SvgPreserveAspectRatio)fitToView.PreserveAspectRatio.AnimVal; SvgRect viewBox = (SvgRect)fitToView.ViewBox.AnimVal; SvgRect rectToFit = new SvgRect(elementBounds.X, elementBounds.Y, elementBounds.Width, elementBounds.Height); double[] transformArray = spar.FitToViewBox(viewBox, rectToFit); double translateX = Math.Round(transformArray[0], 4); double translateY = Math.Round(transformArray[1], 4); double scaleX = Math.Round(transformArray[2], 4); double scaleY = Math.Round(transformArray[3], 4); Transform translateMatrix = null; Transform scaleMatrix = null; if (!translateX.Equals(0.0) || !translateY.Equals(0.0)) { translateMatrix = new TranslateTransform(translateX, translateY); } if (!scaleX.Equals(1.0) || !scaleY.Equals(1.0)) { scaleMatrix = new ScaleTransform(scaleX, scaleY); } if (translateMatrix != null && scaleMatrix != null) { // Create a TransformGroup to contain the transforms // and add the transforms to it. if (translateMatrix.Value.IsIdentity && scaleMatrix.Value.IsIdentity) { return; } if (translateMatrix.Value.IsIdentity) { this.Transform = scaleMatrix; return; } if (scaleMatrix.Value.IsIdentity) { this.Transform = translateMatrix; return; } TransformGroup transformGroup = new TransformGroup(); transformGroup.Children.Add(scaleMatrix); transformGroup.Children.Add(translateMatrix); this.Transform = transformGroup; } else if (translateMatrix != null) { this.Transform = translateMatrix; } else if (scaleMatrix != null) { this.Transform = scaleMatrix; } }
protected void SetClip(WpfDrawingContext context) { _clipPathUnits = SvgUnitType.UserSpaceOnUse; if (_svgElement == null) { return; } #region Clip with clip // see http://www.w3.org/TR/SVG/masking.html#OverflowAndClipProperties if (_svgElement is ISvgSvgElement || _svgElement is ISvgMarkerElement || _svgElement is ISvgSymbolElement || _svgElement is ISvgPatternElement) { // check overflow property CssValue overflow = _svgElement.GetComputedCssValue("overflow", string.Empty) as CssValue; // TODO: clip can have "rect(10 10 auto 10)" CssPrimitiveValue clip = _svgElement.GetComputedCssValue("clip", string.Empty) as CssPrimitiveValue; string sOverflow = null; if (overflow != null && !string.IsNullOrWhiteSpace(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") { Rect clipRect = Rect.Empty; if (clip != null && clip.PrimitiveType == CssPrimitiveType.Rect) { if (_svgElement is ISvgSvgElement) { ISvgSvgElement svgElement = (ISvgSvgElement)_svgElement; SvgRect viewPort = svgElement.Viewport as SvgRect; clipRect = WpfConvert.ToRect(viewPort); ICssRect clipShape = (CssRect)clip.GetRectValue(); if (clipShape.Top.PrimitiveType != CssPrimitiveType.Ident) { clipRect.Y += clipShape.Top.GetFloatValue(CssPrimitiveType.Number); } if (clipShape.Left.PrimitiveType != CssPrimitiveType.Ident) { clipRect.X += clipShape.Left.GetFloatValue(CssPrimitiveType.Number); } if (clipShape.Right.PrimitiveType != CssPrimitiveType.Ident) { clipRect.Width = (clipRect.Right - clipRect.X) - clipShape.Right.GetFloatValue(CssPrimitiveType.Number); } if (clipShape.Bottom.PrimitiveType != CssPrimitiveType.Ident) { clipRect.Height = (clipRect.Bottom - clipRect.Y) - clipShape.Bottom.GetFloatValue(CssPrimitiveType.Number); } } } else if (clip == null || (clip.PrimitiveType == CssPrimitiveType.Ident && clip.GetStringValue() == "auto")) { if (_svgElement is ISvgSvgElement) { ISvgSvgElement svgElement = (ISvgSvgElement)_svgElement; SvgRect viewPort = svgElement.Viewport as SvgRect; clipRect = WpfConvert.ToRect(viewPort); } else if (_svgElement is ISvgMarkerElement || _svgElement is ISvgSymbolElement || _svgElement is ISvgPatternElement) { // TODO: what to do here? } } if (clipRect != Rect.Empty) { _clipGeometry = new RectangleGeometry(clipRect); //gr.SetClip(clipRect); } } } } #endregion #region Clip with clip-path SvgRenderingHint hint = _svgElement.RenderingHint; if (hint == SvgRenderingHint.Image) { } // 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 || hint == SvgRenderingHint.Image) { CssPrimitiveValue clipPath = _svgElement.GetComputedCssValue("clip-path", string.Empty) as CssPrimitiveValue; if (clipPath != null && clipPath.PrimitiveType == CssPrimitiveType.Uri) { string absoluteUri = _svgElement.ResolveUri(clipPath.GetStringValue()); SvgClipPathElement eClipPath = _svgElement.OwnerDocument.GetNodeByUri(absoluteUri) as SvgClipPathElement; if (eClipPath != null) { GeometryCollection geomColl = CreateClippingRegion(eClipPath, context); if (geomColl == null || geomColl.Count == 0) { return; } Geometry gpClip = geomColl[0]; int geomCount = geomColl.Count; if (geomCount > 1) { //GeometryGroup clipGroup = new GeometryGroup(); //clipGroup.Children.Add(gpClip); for (int k = 1; k < geomCount; k++) { gpClip = Geometry.Combine(gpClip, geomColl[k], GeometryCombineMode.Union, null); //clipGroup.Children.Add(geomColl[k]); } //clipGroup.Children.Reverse(); //gpClip = clipGroup; } if (gpClip == null || gpClip.IsEmpty()) { return; } _clipPathUnits = (SvgUnitType)eClipPath.ClipPathUnits.AnimVal; //if (_clipPathUnits == SvgUnitType.ObjectBoundingBox) //{ // SvgTransformableElement transElement = _svgElement as SvgTransformableElement; // if (transElement != null) // { // ISvgRect bbox = transElement.GetBBox(); // // scale clipping path // gpClip.Transform = new ScaleTransform(bbox.Width, bbox.Height); // //gr.SetClip(gpClip); // // offset clip // //TODO--PAUL gr.TranslateClip((float)bbox.X, (float)bbox.Y); // _clipGeometry = gpClip; // } // else // { // throw new NotImplementedException("clip-path with SvgUnitType.ObjectBoundingBox " // + "not supported for this type of element: " + _svgElement.GetType()); // } //} //else { //gr.SetClip(gpClip); _clipGeometry = gpClip; } } } } #endregion }
private double[] FitToViewBox(SvgPreserveAspectRatioType alignment, SvgRect viewBox, SvgRect rectToFit) { double translateX = 0; double translateY = 0; double scaleX = 1; double scaleY = 1; if (!viewBox.IsEmpty) { // calculate scale values for non-uniform scaling scaleX = rectToFit.Width / viewBox.Width; scaleY = rectToFit.Height / viewBox.Height; if (alignment != SvgPreserveAspectRatioType.None) { // uniform scaling scaleX = Math.Max(scaleX, scaleY); scaleY = scaleX; if (alignment == SvgPreserveAspectRatioType.XMidYMax || alignment == SvgPreserveAspectRatioType.XMidYMid || alignment == SvgPreserveAspectRatioType.XMidYMin) { // align to the Middle X translateX = (rectToFit.X + rectToFit.Width / 2) - scaleX * (viewBox.X + viewBox.Width / 2); } else if (alignment == SvgPreserveAspectRatioType.XMaxYMax || alignment == SvgPreserveAspectRatioType.XMaxYMid || alignment == SvgPreserveAspectRatioType.XMaxYMin) { // align to the right X translateX = (rectToFit.Width - viewBox.Width * scaleX); } if (alignment == SvgPreserveAspectRatioType.XMaxYMid || alignment == SvgPreserveAspectRatioType.XMidYMid || alignment == SvgPreserveAspectRatioType.XMinYMid) { // align to the Middle Y translateY = (rectToFit.Y + rectToFit.Height / 2) - scaleY * (viewBox.Y + viewBox.Height / 2); } else if (alignment == SvgPreserveAspectRatioType.XMaxYMax || alignment == SvgPreserveAspectRatioType.XMidYMax || alignment == SvgPreserveAspectRatioType.XMinYMax) { // align to the bottom Y translateY = (rectToFit.Height - viewBox.Height * scaleY); } } else { translateX = -viewBox.X * scaleX; translateY = -viewBox.Y * scaleY; } } if (!SvgNumber.IsValid(translateX)) { translateX = 0; } if (!SvgNumber.IsValid(translateY)) { translateY = 0; } if (!SvgNumber.IsValid(scaleX)) { scaleX = 1; } if (!SvgNumber.IsValid(scaleY)) { scaleY = 1; } return(new double[] { translateX, translateY, scaleX, scaleY }); }
public override void AfterRender(WpfDrawingRenderer renderer) { Debug.Assert(_drawGroup != null); WpfDrawingContext context = renderer.Context; DrawingGroup currentGroup = context.Peek(); if (currentGroup == null || currentGroup != _drawGroup) { throw new InvalidOperationException("An existing group is expected."); } ISvgAnimatedEnumeration markerUnits = _markerElement.MarkerUnits; if (markerUnits.AnimVal.Equals((ushort)SvgMarkerUnit.StrokeWidth)) { var comparer = StringComparison.OrdinalIgnoreCase; string overflowAttr = _markerElement.GetAttribute("overflow"); if (string.IsNullOrWhiteSpace(overflowAttr) || overflowAttr.Equals("scroll", comparer) || overflowAttr.Equals("hidden", comparer)) { Geometry markerClip = this.ClipGeometry; if (markerClip == null || markerClip.IsEmpty()) { SvgRect clipRect = (SvgRect)_markerElement.ViewBox.AnimVal; if (clipRect != null && !clipRect.IsEmpty) { _drawGroup.ClipGeometry = new RectangleGeometry( new Rect(clipRect.X, clipRect.Y, clipRect.Width, clipRect.Height)); } else if (_markerElement.IsSizeDefined) { _drawGroup.ClipGeometry = new RectangleGeometry(new Rect(0, 0, _markerElement.MarkerWidth.AnimVal.Value, _markerElement.MarkerHeight.AnimVal.Value)); } else if (_hostElement != null) { // Special cases for zero-length 'path' and 'line' segments. var isLineSegment = false; if (_hostGeometry != null) { var bounds = _hostGeometry.Bounds; if (string.Equals(_hostElement.LocalName, "line", StringComparison.Ordinal)) { isLineSegment = true; } else if (string.Equals(_hostElement.LocalName, "rect", StringComparison.Ordinal)) { isLineSegment = bounds.Width.Equals(0) || bounds.Height.Equals(0); } else if (string.Equals(_hostElement.LocalName, "path", StringComparison.Ordinal)) { isLineSegment = bounds.Width.Equals(0) || bounds.Height.Equals(0); } } else { if (string.Equals(_hostElement.LocalName, "line", StringComparison.Ordinal)) { isLineSegment = true; } } if (isLineSegment) { bool isZeroWidthLine = false; if (_pathFigures != null) { if (_pathFigures.Count == 0) { isZeroWidthLine = true; } else { var pathWidth = 0.0d; foreach (PathFigure pathFigure in _pathFigures) { pathWidth += WpfConvert.GetPathFigureLength(pathFigure); } isZeroWidthLine = pathWidth.Equals(0.0d); } } if (isZeroWidthLine) { _drawGroup.ClipGeometry = new RectangleGeometry(new Rect(0, 0, _markerElement.MarkerWidth.AnimVal.Value, _markerElement.MarkerHeight.AnimVal.Value)); } } } } } } context.Pop(); base.AfterRender(renderer); }
private Transform GetAspectRatioTransform(SvgPreserveAspectRatio spar, SvgRect sourceBounds, SvgRect elementBounds) { double[] transformArray = spar.FitToViewBox(sourceBounds, elementBounds); double translateX = Math.Round(transformArray[0], 4); double translateY = Math.Round(transformArray[1], 4); double scaleX = Math.Round(transformArray[2], 4); double scaleY = Math.Round(transformArray[3], 4); // Cacxa if (this.Transform != null) { if (!scaleX.Equals(1.0) && !this.Transform.Value.OffsetX.Equals(0.0)) { translateX = translateX + this.Transform.Value.OffsetX * (1 - scaleX); } if (!scaleY.Equals(1.0) && !this.Transform.Value.OffsetY.Equals(0.0)) { translateY = translateY + this.Transform.Value.OffsetY * (1 - scaleY); } } Transform translateMatrix = null; Transform scaleMatrix = null; if (!translateX.Equals(0.0) || !translateY.Equals(0.0)) { translateMatrix = new TranslateTransform(translateX, translateY); } if (!scaleX.Equals(1.0) || !scaleY.Equals(1.0)) { scaleMatrix = new ScaleTransform(scaleX, scaleY); } if (translateMatrix != null && scaleMatrix != null) { // Create a TransformGroup to contain the transforms // and add the transforms to it. if (translateMatrix.Value.IsIdentity && scaleMatrix.Value.IsIdentity) { return(null); } if (translateMatrix.Value.IsIdentity) { return(scaleMatrix); } if (scaleMatrix.Value.IsIdentity) { return(translateMatrix); } TransformGroup transformGroup = new TransformGroup(); transformGroup.Children.Add(scaleMatrix); transformGroup.Children.Add(translateMatrix); return(transformGroup); } if (translateMatrix != null) { return(translateMatrix.Value.IsIdentity ? null : translateMatrix); } if (scaleMatrix != null) { return(scaleMatrix.Value.IsIdentity ? null : scaleMatrix); } return(null); }
public void PaintMarker(GdiGraphicsRenderer renderer, GdiGraphics gr, SvgMarkerPosition markerPos, SvgStyleableElement refElement) { ISharpMarkerHost markerHostElm = (ISharpMarkerHost)refElement; SvgMarkerElement markerElm = (SvgMarkerElement)_svgElement; SvgPointF[] vertexPositions = markerHostElm.MarkerPositions; if (vertexPositions == null) { return; } var comparer = StringComparison.OrdinalIgnoreCase; bool mayHaveCurves = markerHostElm.MayHaveCurves; 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; } int end = start + len; for (int i = start; i < end; i++) { SvgPointF point = vertexPositions[i]; GdiGraphicsContainer gc = gr.BeginContainer(); gr.TranslateTransform(point.X, point.Y); if (markerElm.OrientType.AnimVal.Equals((ushort)SvgMarkerOrient.Angle)) { double scaleValue = markerElm.OrientAngle.AnimVal.Value; if (!scaleValue.Equals(0)) { gr.RotateTransform((float)scaleValue); } } else { double angle; switch (markerPos) { case SvgMarkerPosition.Start: angle = markerHostElm.GetStartAngle(i); //angle = markerHostElm.GetStartAngle(i + 1); if (vertexPositions.Length >= 2) { SvgPointF pMarkerPoint1 = vertexPositions[start]; SvgPointF pMarkerPoint2 = vertexPositions[end]; float xDiff = pMarkerPoint2.X - pMarkerPoint1.X; float yDiff = pMarkerPoint2.Y - pMarkerPoint1.Y; double angleMarker = (float)(Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI); if (!angleMarker.Equals(angle)) { angle = angleMarker; } } 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 - 1); //double angle2 = markerHostElm.GetEndAngle(i); if (vertexPositions.Length >= 2) { SvgPointF pMarkerPoint1 = vertexPositions[start - 1]; SvgPointF pMarkerPoint2 = vertexPositions[start]; float xDiff = pMarkerPoint2.X - pMarkerPoint1.X; float yDiff = pMarkerPoint2.Y - pMarkerPoint1.Y; double angleMarker = (float)(Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI); if (!angleMarker.Equals(angle)) { angle = angleMarker; } } //if (mayHaveCurves) //{ // angle = this.GetAngleAt(start - 1, angle, markerPos, markerHostElm); //} break; } gr.RotateTransform((float)angle); } // 'viewBox' and 'preserveAspectRatio' attributes // viewBox -> viewport(0, 0, markerWidth, markerHeight) var 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)); //// Warning at this time, refX and refY are relative to the painted element's coordinate system. //// We need to move the reference point to the marker's coordinate system //float refX = (float)markerElm.RefX.AnimVal.Value; //float refY = (float)markerElm.RefY.AnimVal.Value; ////if (!(refX.Equals(0) && refY.Equals(0))) ////{ //// var points = new PointF[] { new PointF(refX, refY) }; //// gr.Transform.TransformPoints(points); //// refX = points[0].X; //// refY = points[0].Y; //// gr.TranslateTransform(-refX, -refY); ////} //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); //} //gr.TranslateTransform(-(float)(markerElm.RefX.AnimVal.Value * translateAndScale[2]), // -(float)(markerElm.RefY.AnimVal.Value * translateAndScale[3])); //gr.ScaleTransform((float)translateAndScale[2], (float)translateAndScale[3]); // compute an additional transform for 'strokeWidth' coordinate system ISvgAnimatedEnumeration markerUnits = markerElm.MarkerUnits; if (markerUnits.AnimVal.Equals((ushort)SvgMarkerUnit.StrokeWidth)) { SvgLength strokeWidthLength = new SvgLength(refElement, "stroke-width", SvgLengthSource.Css, SvgLengthDirection.Viewport, SvgConstants.ValOne); double strokeWidth = strokeWidthLength.Value; if (!strokeWidth.Equals(1)) { gr.ScaleTransform((float)strokeWidth, (float)strokeWidth); } } gr.TranslateTransform(-(float)(markerElm.RefX.AnimVal.Value * translateAndScale[2]), -(float)(markerElm.RefY.AnimVal.Value * translateAndScale[3])); if (!(translateAndScale[2].Equals(1) && translateAndScale[3].Equals(1))) { gr.ScaleTransform((float)translateAndScale[2], (float)translateAndScale[3]); } // gr.TranslateTransform(point.X, point.Y); RectangleF rectClip = RectangleF.Empty; if (markerUnits.AnimVal.Equals((ushort)SvgMarkerUnit.StrokeWidth)) { string overflowAttr = markerElm.GetAttribute("overflow"); if (string.IsNullOrWhiteSpace(overflowAttr) || overflowAttr.Equals("scroll", comparer) || overflowAttr.Equals(CssConstants.ValHidden, comparer)) { var markerClip = RectangleF.Empty; SvgRect clipRect = (SvgRect)markerElm.ViewBox.AnimVal; if (clipRect != null && !clipRect.IsEmpty) { rectClip = new RectangleF((float)clipRect.X, (float)clipRect.Y, (float)clipRect.Width, (float)clipRect.Height); } else if (markerElm.IsSizeDefined) { rectClip = new RectangleF(0, 0, (float)markerElm.MarkerWidth.AnimVal.Value, (float)markerElm.MarkerHeight.AnimVal.Value); } } } if (rectClip.IsEmpty) { SetClip(gr); } else { gr.SetClip(rectClip); } renderer.RenderChildren(markerElm); gr.EndContainer(gc); } }