protected static bool IsPresentationMarker(SvgStyleableElement styleElm) { if (!string.IsNullOrWhiteSpace(styleElm.GetAttribute("marker"))) { return(true); } SvgElement parentElm = styleElm.ParentNode as SvgElement; if (parentElm == null) { return(false); } switch (parentElm.LocalName) { case "g": if (!string.IsNullOrWhiteSpace(parentElm.GetAttribute("marker"))) { return(true); } break; case "use": if (!string.IsNullOrWhiteSpace(parentElm.GetAttribute("marker"))) { return(true); } //TODO--PAUL break; } return(false); }
private WpfSvgPaint GetDeferredFill() { var nodeList = _element.OwnerDocument.SelectNodes("//*[@fill='currentColor']"); if (nodeList == null || nodeList.Count == 0) { return(null); } // Try a shortcut... SvgStyleableElement svgElement = _element.ParentNode as SvgStyleableElement; if (svgElement != null && svgElement.HasAttribute("fill") && string.Equals("currentColor", svgElement.GetAttribute("fill"))) { string color = svgElement.GetAttribute("color"); if (!string.IsNullOrWhiteSpace(color)) { return(new WpfSvgPaint(_context, svgElement, "color")); } } foreach (XmlNode nodeItem in nodeList) { svgElement = nodeItem as SvgStyleableElement; if (svgElement == null) { continue; } var childNodeList = svgElement.GetElementsByTagName(_element.LocalName); if (childNodeList != null && childNodeList.Count != 0) { foreach (var childNode in childNodeList) { if (childNode == _element) { string color = svgElement.GetAttribute("color"); if (!string.IsNullOrWhiteSpace(color)) { return(new WpfSvgPaint(_context, svgElement, "color")); } } } } } return(null); }
private double GetMiterLimit(double strokeWidth) { // Use this to prevent the default value of "4" being used... string miterLimitAttr = _element.GetAttribute("stroke-miterlimit"); if (String.IsNullOrEmpty(miterLimitAttr)) { string strokeLinecap = _element.GetAttribute("stroke-linecap"); if (String.Equals(strokeLinecap, "round", StringComparison.OrdinalIgnoreCase)) { return(1.0d); } return(-1.0d); } string miterLimitStr = _element.GetPropertyValue("stroke-miterlimit"); if (String.IsNullOrEmpty(miterLimitStr) || (float)(strokeWidth) <= 0) { return(-1.0d); } double miterLimit = SvgNumber.ParseNumber(miterLimitStr); if (miterLimit < 1) { throw new SvgException(SvgExceptionType.SvgInvalidValueErr, "stroke-miterlimit can not be less then 1"); } //if (miterLimit < 1.0d) //{ // return -1.0d; //} double ratioLimit = miterLimit / strokeWidth; if (ratioLimit >= 1.8d) { return(miterLimit); } else { return(1.0d); } }
public static bool TryGetMiterLimit(SvgStyleableElement element, double strokeWidth, out double miterLimit) { string miterLimitAttr = element.GetAttribute("stroke-miterlimit"); if (string.IsNullOrWhiteSpace(miterLimitAttr)) { string strokeLinecap = element.GetAttribute("stroke-linecap"); if (string.Equals(strokeLinecap, "round", StringComparison.OrdinalIgnoreCase)) { miterLimit = 1.0d; return(true); } miterLimit = -1.0d; return(false); } string miterLimitStr = element.GetPropertyValue("stroke-miterlimit"); if (string.IsNullOrWhiteSpace(miterLimitStr) || strokeWidth <= 0) { miterLimit = -1.0d; return(false); } miterLimit = SvgNumber.ParseNumber(miterLimitStr); if (miterLimit < 1) { return(false); } double ratioLimit = miterLimit / strokeWidth; if (ratioLimit < 1.8d) { miterLimit = 1.0d; } return(true); }
public static bool TryGetFillRule(SvgStyleableElement element, out FillRule fillRule) { string fillRuleStr = element.GetPropertyValue("fill-rule"); string clipRule = element.GetAttribute("clip-rule"); if (!string.IsNullOrWhiteSpace(clipRule) && string.Equals(clipRule, "evenodd") || string.Equals(clipRule, CssConstants.ValNonzero)) { fillRuleStr = clipRule; } if (StringComparer.InvariantCultureIgnoreCase.Equals(fillRuleStr, "evenodd")) { fillRule = FillRule.EvenOdd; return(true); } else if (StringComparer.InvariantCultureIgnoreCase.Equals(fillRuleStr, CssConstants.ValNonzero)) { fillRule = FillRule.Nonzero; return(true); } fillRule = FillRule.EvenOdd; return(false); }
public static Brush CreateViewportBrush(SvgStyleableElement svgElm) { string prop = svgElm.GetAttribute("viewport-fill"); string opacity = svgElm.GetAttribute("viewport-fill-opacity"); // no auto-inherit if (string.Equals(prop, "inherit", StringComparison.OrdinalIgnoreCase)) // if explicitly defined... { prop = svgElm.GetPropertyValue("viewport-fill"); } if (string.Equals(opacity, "inherit", StringComparison.OrdinalIgnoreCase)) // if explicitly defined... { opacity = svgElm.GetPropertyValue("viewport-fill-opacity"); } if (!string.IsNullOrWhiteSpace(prop)) { if (string.Equals(prop, "currentColor", StringComparison.OrdinalIgnoreCase)) { var svgParent = svgElm.ParentNode as SvgStyleableElement; if (svgParent != null) { prop = svgParent.GetPropertyValue(CssConstants.PropColor, "viewport-fill"); } } Color color = Colors.Transparent; // no auto-inherited... WpfSvgColor svgColor = new WpfSvgColor(svgElm, "viewport-fill"); color = svgColor.Color; if (color.A == 255) { double alpha = 255; if (!string.IsNullOrWhiteSpace(opacity)) { alpha *= SvgNumber.ParseNumber(opacity); } alpha = Math.Min(alpha, 255); alpha = Math.Max(alpha, 0); color = Color.FromArgb((byte)Convert.ToInt32(alpha), color.R, color.G, color.B); } var brush = new SolidColorBrush(color); double opacityValue = 1; if (!string.IsNullOrWhiteSpace(opacity) && double.TryParse(opacity, out opacityValue)) { brush.Opacity = opacityValue; } return(brush); } else { Color color = Colors.Black; // the default color... double alpha = 255; if (!string.IsNullOrWhiteSpace(opacity)) { alpha *= SvgNumber.ParseNumber(opacity); } alpha = Math.Min(alpha, 255); alpha = Math.Max(alpha, 0); color = Color.FromArgb((byte)Convert.ToInt32(alpha), color.R, color.G, color.B); return(new SolidColorBrush(color)); } }
private void AggregateChildren(SvgAElement aElement, WpfDrawingContext context, float opacity) { _isAggregated = false; if (aElement == null || aElement.ChildNodes == null) { return; } string aggregatedFill = aElement.GetAttribute("fill"); bool isFillFound = !String.IsNullOrEmpty(aggregatedFill); SvgStyleableElement paintElement = null; if (isFillFound) { paintElement = aElement; } XmlNode targetNode = aElement; // Check if the children of the link are wrapped in a Group Element... if (aElement.ChildNodes.Count == 1) { SvgGElement groupElement = aElement.ChildNodes[0] as SvgGElement; if (groupElement != null) { targetNode = groupElement; } } WpfDrawingSettings settings = context.Settings; GeometryCollection geomColl = new GeometryCollection(); foreach (XmlNode node in targetNode.ChildNodes) { if (node.NodeType != XmlNodeType.Element) { continue; } // Handle a case where the clip element has "use" element as a child... if (String.Equals(node.LocalName, "use")) { SvgUseElement useElement = (SvgUseElement)node; XmlElement refEl = useElement.ReferencedElement; if (refEl != null) { XmlElement refElParent = (XmlElement)refEl.ParentNode; useElement.OwnerDocument.Static = true; useElement.CopyToReferencedElement(refEl); refElParent.RemoveChild(refEl); useElement.AppendChild(refEl); foreach (XmlNode useChild in useElement.ChildNodes) { if (useChild.NodeType != XmlNodeType.Element) { continue; } SvgStyleableElement element = useChild as SvgStyleableElement; if (element != null && element.RenderingHint == SvgRenderingHint.Shape) { Geometry childPath = WpfRendering.CreateGeometry(element, settings.OptimizePath); if (childPath != null) { if (isFillFound) { string elementFill = element.GetAttribute("fill"); if (!String.IsNullOrEmpty(elementFill) && !String.Equals(elementFill, aggregatedFill, StringComparison.OrdinalIgnoreCase)) { return; } } else { aggregatedFill = element.GetAttribute("fill"); isFillFound = !String.IsNullOrEmpty(aggregatedFill); if (isFillFound) { paintElement = element; } } geomColl.Add(childPath); } } } useElement.RemoveChild(refEl); useElement.RestoreReferencedElement(refEl); refElParent.AppendChild(refEl); useElement.OwnerDocument.Static = false; } } //else if (String.Equals(node.LocalName, "g")) //{ //} else { SvgStyleableElement element = node as SvgStyleableElement; if (element != null && element.RenderingHint == SvgRenderingHint.Shape) { Geometry childPath = WpfRendering.CreateGeometry(element, settings.OptimizePath); if (childPath != null) { if (isFillFound) { string elementFill = element.GetAttribute("fill"); if (!String.IsNullOrEmpty(elementFill) && !String.Equals(elementFill, aggregatedFill, StringComparison.OrdinalIgnoreCase)) { return; } } else { aggregatedFill = element.GetAttribute("fill"); isFillFound = !String.IsNullOrEmpty(aggregatedFill); if (isFillFound) { paintElement = element; } } geomColl.Add(childPath); } } } } if (geomColl.Count == 0 || paintElement == null) { return; } _aggregatedFill = paintElement; _aggregatedGeom = geomColl; _isAggregated = true; }
private void RenderPath(WpfDrawingRenderer renderer) { WpfDrawingContext context = renderer.Context; SvgRenderingHint hint = _svgElement.RenderingHint; if (hint != SvgRenderingHint.Shape || hint == SvgRenderingHint.Clipping) { return; } var parentNode = _svgElement.ParentNode; // We do not directly render the contents of the clip-path, unless specifically requested... if (string.Equals(parentNode.LocalName, "clipPath") && !context.RenderingClipRegion) { return; } SvgStyleableElement styleElm = (SvgStyleableElement)_svgElement; //string sVisibility = styleElm.GetPropertyValue("visibility"); //string sDisplay = styleElm.GetPropertyValue("display"); //if (string.Equals(sVisibility, "hidden") || string.Equals(sDisplay, "none")) //{ // return; //} DrawingGroup drawGroup = context.Peek(); Debug.Assert(drawGroup != null); Geometry geometry = CreateGeometry(_svgElement, context.OptimizePath); string elementId = this.GetElementName(); string elementClass = this.GetElementClass(); GeometryDrawing drawing = null; if (geometry == null || geometry.IsEmpty()) { return; } var bounds = geometry.Bounds; if (string.Equals(_svgElement.LocalName, "line", StringComparison.Ordinal)) { _isLineSegment = true; } else if (string.Equals(_svgElement.LocalName, "rect", StringComparison.Ordinal)) { _isLineSegment = bounds.Width.Equals(0) || bounds.Height.Equals(0); } else if (string.Equals(_svgElement.LocalName, "path", StringComparison.Ordinal)) { _isLineSegment = bounds.Width.Equals(0) || bounds.Height.Equals(0); } context.UpdateBounds(geometry.Bounds); // SetClip(context); WpfSvgPaint fillPaint = new WpfSvgPaint(context, styleElm, "fill"); string fileValue = styleElm.GetAttribute("fill"); Brush brush = fillPaint.GetBrush(geometry, _setBrushOpacity); bool isFillTransmable = fillPaint.IsFillTransformable; WpfSvgPaint strokePaint = new WpfSvgPaint(context, styleElm, "stroke"); Pen pen = strokePaint.GetPen(geometry, _setBrushOpacity); // By the SVG Specifications: // Keyword 'objectBoundingBox' should not be used when the geometry of the applicable // element has no width or no height, such as the case of a horizontal or vertical line, // even when the line has actual thickness when viewed due to having a non-zero stroke // width since stroke width is ignored for bounding box calculations. When the geometry // of the applicable element has no width or height and 'objectBoundingBox' is specified, // then the given effect (e.g., a gradient) will be ignored. if (pen != null && _isLineSegment && strokePaint.FillType == WpfFillType.Gradient) { WpfGradientFill gradientFill = (WpfGradientFill)strokePaint.PaintServer; if (gradientFill.IsUserSpace == false) { bool invalidGrad = false; if (string.Equals(_svgElement.LocalName, "line", StringComparison.Ordinal)) { LineGeometry lineGeometry = geometry as LineGeometry; if (lineGeometry != null) { invalidGrad = SvgObject.IsEqual(lineGeometry.EndPoint.X, lineGeometry.StartPoint.X) || SvgObject.IsEqual(lineGeometry.EndPoint.Y, lineGeometry.StartPoint.Y); } } else { invalidGrad = true; } if (invalidGrad) { // Brush is not likely inherited, we need to support fallback too WpfSvgPaint fallbackPaint = strokePaint.WpfFallback; if (fallbackPaint != null) { pen.Brush = fallbackPaint.GetBrush(geometry, _setBrushOpacity); } else { var scopePaint = strokePaint.GetScopeStroke(); if (scopePaint != null) { if (scopePaint != strokePaint) { pen.Brush = scopePaint.GetBrush(geometry, _setBrushOpacity); } else { pen.Brush = null; } } else { pen.Brush = null; } } } } } if (_paintContext != null) { _paintContext.Fill = fillPaint; _paintContext.Stroke = strokePaint; _paintContext.Tag = geometry; } if (brush != null || pen != null) { Transform transform = this.Transform; if (transform != null && !transform.Value.IsIdentity) { geometry.Transform = transform; if (brush != null && isFillTransmable) { Transform brushTransform = brush.Transform; if (brushTransform == null || brushTransform == Transform.Identity) { brush.Transform = transform; } else { TransformGroup groupTransform = new TransformGroup(); groupTransform.Children.Add(brushTransform); groupTransform.Children.Add(transform); brush.Transform = groupTransform; } } if (pen != null && pen.Brush != null) { Transform brushTransform = pen.Brush.Transform; if (brushTransform == null || brushTransform == Transform.Identity) { pen.Brush.Transform = transform; } else { TransformGroup groupTransform = new TransformGroup(); groupTransform.Children.Add(brushTransform); groupTransform.Children.Add(transform); pen.Brush.Transform = groupTransform; } } } else { transform = null; // render any identity transform useless... } drawing = new GeometryDrawing(brush, pen, geometry); if (!string.IsNullOrWhiteSpace(elementId) && !context.IsRegisteredId(elementId)) { SvgObject.SetName(drawing, elementId); context.RegisterId(elementId); if (context.IncludeRuntime) { SvgObject.SetId(drawing, elementId); } } if (!string.IsNullOrWhiteSpace(elementClass) && context.IncludeRuntime) { SvgObject.SetClass(drawing, elementClass); } Brush maskBrush = this.Masking; Geometry clipGeom = this.ClipGeometry; if (clipGeom != null || maskBrush != null) { //Geometry clipped = Geometry.Combine(geometry, clipGeom, // GeometryCombineMode.Exclude, null); //if (clipped != null && !clipped.IsEmpty()) //{ // geometry = clipped; //} DrawingGroup clipMaskGroup = new DrawingGroup(); Rect geometryBounds = geometry.Bounds; if (clipGeom != null) { clipMaskGroup.ClipGeometry = clipGeom; SvgUnitType clipUnits = this.ClipUnits; if (clipUnits == SvgUnitType.ObjectBoundingBox) { Rect drawingBounds = geometryBounds; if (transform != null) { drawingBounds = transform.TransformBounds(drawingBounds); } TransformGroup transformGroup = new TransformGroup(); // Scale the clip region (at (0, 0)) and translate to the top-left corner of the target. transformGroup.Children.Add(new ScaleTransform(drawingBounds.Width, drawingBounds.Height)); transformGroup.Children.Add(new TranslateTransform(drawingBounds.X, drawingBounds.Y)); clipGeom.Transform = transformGroup; } else { if (transform != null) { clipGeom.Transform = transform; } } } if (maskBrush != null) { DrawingBrush drawingBrush = (DrawingBrush)maskBrush; SvgUnitType maskUnits = this.MaskUnits; SvgUnitType maskContentUnits = this.MaskContentUnits; if (maskUnits == SvgUnitType.ObjectBoundingBox) { Rect drawingBounds = geometryBounds; if (transform != null) { drawingBounds = transform.TransformBounds(drawingBounds); } DrawingGroup maskGroup = drawingBrush.Drawing as DrawingGroup; if (maskGroup != null) { DrawingCollection maskDrawings = maskGroup.Children; for (int i = 0; i < maskDrawings.Count; i++) { Drawing maskDrawing = maskDrawings[i]; GeometryDrawing maskGeomDraw = maskDrawing as GeometryDrawing; if (maskGeomDraw != null) { if (maskGeomDraw.Brush != null) { ConvertColors(maskGeomDraw.Brush); } if (maskGeomDraw.Pen != null) { ConvertColors(maskGeomDraw.Pen.Brush); } } } } if (maskContentUnits == SvgUnitType.ObjectBoundingBox) { TransformGroup transformGroup = new TransformGroup(); // Scale the clip region (at (0, 0)) and translate to the top-left corner of the target. var scaleTransform = new ScaleTransform(drawingBounds.Width, drawingBounds.Height); transformGroup.Children.Add(scaleTransform); var translateTransform = new TranslateTransform(drawingBounds.X, drawingBounds.Y); transformGroup.Children.Add(translateTransform); Matrix scaleMatrix = new Matrix(); Matrix translateMatrix = new Matrix(); scaleMatrix.Scale(drawingBounds.Width, drawingBounds.Height); translateMatrix.Translate(drawingBounds.X, drawingBounds.Y); Matrix matrix = Matrix.Multiply(scaleMatrix, translateMatrix); //maskBrush.Transform = transformGroup; maskBrush.Transform = new MatrixTransform(matrix); } else { drawingBrush.Viewbox = drawingBounds; drawingBrush.ViewboxUnits = BrushMappingMode.Absolute; drawingBrush.Stretch = Stretch.Uniform; drawingBrush.Viewport = drawingBounds; drawingBrush.ViewportUnits = BrushMappingMode.Absolute; } } else { if (transform != null) { maskBrush.Transform = transform; } } clipMaskGroup.OpacityMask = maskBrush; } clipMaskGroup.Children.Add(drawing); drawGroup.Children.Add(clipMaskGroup); } else { drawGroup.Children.Add(drawing); } } // If this is not the child of a "marker", then try rendering a marker... if (!string.Equals(parentNode.LocalName, "marker")) { RenderMarkers(renderer, styleElm, context); } // Register this drawing with the Drawing-Document... if (drawing != null) { this.Rendered(drawing); } }
public override void BeforeRender(WpfDrawingRenderer renderer) { base.BeforeRender(renderer); if (renderer == null) { return; } _isLineSegment = false; _setBrushOpacity = true; WpfDrawingContext context = renderer.Context; //SetQuality(context); //SetTransform(context); //SetMask(context); // _drawGroup = new DrawingGroup(); SvgStyleableElement styleElm = (SvgStyleableElement)_svgElement; float opacityValue = -1; bool isStyleOpacity = false; string opacity = styleElm.GetAttribute("opacity"); if (string.IsNullOrWhiteSpace(opacity)) { opacity = styleElm.GetPropertyValue("opacity"); if (!string.IsNullOrWhiteSpace(opacity)) { isStyleOpacity = true; } } if (!string.IsNullOrWhiteSpace(opacity)) { opacityValue = (float)SvgNumber.ParseNumber(opacity); opacityValue = Math.Min(opacityValue, 1); opacityValue = Math.Max(opacityValue, 0); if (isStyleOpacity && (opacityValue >= 0 && opacityValue < 1)) { _setBrushOpacity = false; if (styleElm.HasAttribute("fill-opacity") || (styleElm.HasAttribute("style") && styleElm.GetAttribute("style").Contains("fill-opacity"))) { _setBrushOpacity = true; } } } //string eVisibility = _svgElement.GetAttribute("visibility"); //string eDisplay = _svgElement.GetAttribute("display"); //if (string.Equals(eVisibility, "hidden") || string.Equals(eDisplay, "none")) //{ // opacityValue = 0; //} //else //{ // string sVisibility = styleElm.GetPropertyValue("visibility"); // string sDisplay = styleElm.GetPropertyValue("display"); // if (string.Equals(sVisibility, "hidden") || string.Equals(sDisplay, "none")) // { // opacityValue = 0; // } //} string sVisibility = styleElm.GetPropertyValue("visibility"); if (string.IsNullOrWhiteSpace(sVisibility)) { sVisibility = _svgElement.GetAttribute("visibility"); } string sDisplay = styleElm.GetPropertyValue("display"); if (string.IsNullOrWhiteSpace(sDisplay)) { sDisplay = _svgElement.GetAttribute("display"); } if (string.Equals(sVisibility, "hidden") || string.Equals(sDisplay, "none")) { opacityValue = 0; } Transform pathTransform = this.Transform; if (pathTransform != null && !pathTransform.Value.IsIdentity) { if (_drawGroup == null) { _drawGroup = new DrawingGroup(); } _drawGroup.Transform = pathTransform; } else { pathTransform = null; // render any identity transform useless... } Geometry pathClip = this.ClipGeometry; if (pathClip != null && !pathClip.IsEmpty()) { if (_drawGroup == null) { _drawGroup = new DrawingGroup(); } _drawGroup.ClipGeometry = pathClip; } else { pathClip = null; // render any empty geometry useless... } Brush pathMask = this.Masking; if (pathMask != null) { if (_drawGroup == null) { _drawGroup = new DrawingGroup(); } _drawGroup.OpacityMask = pathMask; } if (pathTransform != null || pathClip != null || pathMask != null || (opacityValue >= 0 && opacityValue < 1)) { if (_drawGroup == null) { _drawGroup = new DrawingGroup(); } if ((opacityValue >= 0 && opacityValue < 1)) { _drawGroup.Opacity = opacityValue; } DrawingGroup curGroup = _context.Peek(); Debug.Assert(curGroup != null); if (curGroup != null) { curGroup.Children.Add(_drawGroup); context.Push(_drawGroup); } } else { _drawGroup = null; } if (_drawGroup != null) { string elementClass = this.GetElementClass(); if (!string.IsNullOrWhiteSpace(elementClass) && context.IncludeRuntime) { SvgObject.SetClass(_drawGroup, elementClass); } string elementId = this.GetElementName(); if (!string.IsNullOrWhiteSpace(elementId) && !context.IsRegisteredId(elementId)) { SvgObject.SetName(_drawGroup, elementId); context.RegisterId(elementId); if (context.IncludeRuntime) { SvgObject.SetId(_drawGroup, elementId); } } } }
private void RenderPath(WpfDrawingRenderer renderer) { WpfDrawingContext context = renderer.Context; SvgRenderingHint hint = _svgElement.RenderingHint; if (hint != SvgRenderingHint.Shape || hint == SvgRenderingHint.Clipping) { return; } var parentNode = _svgElement.ParentNode; // We do not directly render the contents of the clip-path, unless specifically requested... if (string.Equals(parentNode.LocalName, "clipPath") && !context.RenderingClipRegion) { return; } SvgStyleableElement styleElm = (SvgStyleableElement)_svgElement; string sVisibility = styleElm.GetPropertyValue("visibility"); string sDisplay = styleElm.GetPropertyValue("display"); if (string.Equals(sVisibility, "hidden") || string.Equals(sDisplay, "none")) { return; } DrawingGroup drawGroup = context.Peek(); Debug.Assert(drawGroup != null); Geometry geometry = CreateGeometry(_svgElement, context.OptimizePath); string elementId = this.GetElementName(); string elementClass = this.GetElementClass(); if (geometry != null && !geometry.IsEmpty()) { context.UpdateBounds(geometry.Bounds); // SetClip(context); WpfSvgPaint fillPaint = new WpfSvgPaint(context, styleElm, "fill"); string fileValue = styleElm.GetAttribute("fill"); Brush brush = fillPaint.GetBrush(geometry); bool isFillTransmable = fillPaint.IsFillTransformable; WpfSvgPaint strokePaint = new WpfSvgPaint(context, styleElm, "stroke"); Pen pen = strokePaint.GetPen(geometry); if (_paintContext != null) { _paintContext.Fill = fillPaint; _paintContext.Stroke = strokePaint; _paintContext.Tag = geometry; } if (brush != null || pen != null) { Transform transform = this.Transform; if (transform != null && !transform.Value.IsIdentity) { geometry.Transform = transform; if (brush != null && isFillTransmable) { Transform brushTransform = brush.Transform; if (brushTransform == null || brushTransform == Transform.Identity) { brush.Transform = transform; } else { TransformGroup groupTransform = new TransformGroup(); groupTransform.Children.Add(brushTransform); groupTransform.Children.Add(transform); brush.Transform = groupTransform; } } if (pen != null && pen.Brush != null) { Transform brushTransform = pen.Brush.Transform; if (brushTransform == null || brushTransform == Transform.Identity) { pen.Brush.Transform = transform; } else { TransformGroup groupTransform = new TransformGroup(); groupTransform.Children.Add(brushTransform); groupTransform.Children.Add(transform); pen.Brush.Transform = groupTransform; } } } else { transform = null; // render any identity transform useless... } GeometryDrawing drawing = new GeometryDrawing(brush, pen, geometry); if (!string.IsNullOrWhiteSpace(elementId) && !context.IsRegisteredId(elementId)) { SvgObject.SetName(drawing, elementId); context.RegisterId(elementId); if (context.IncludeRuntime) { SvgObject.SetId(drawing, elementId); } } if (!string.IsNullOrWhiteSpace(elementClass) && context.IncludeRuntime) { SvgObject.SetClass(drawing, elementClass); } Brush maskBrush = this.Masking; Geometry clipGeom = this.ClipGeometry; if (clipGeom != null || maskBrush != null) { //Geometry clipped = Geometry.Combine(geometry, clipGeom, // GeometryCombineMode.Exclude, null); //if (clipped != null && !clipped.IsEmpty()) //{ // geometry = clipped; //} DrawingGroup clipMaskGroup = new DrawingGroup(); Rect geometryBounds = geometry.Bounds; if (clipGeom != null) { clipMaskGroup.ClipGeometry = clipGeom; SvgUnitType clipUnits = this.ClipUnits; if (clipUnits == SvgUnitType.ObjectBoundingBox) { Rect drawingBounds = geometryBounds; if (transform != null) { drawingBounds = transform.TransformBounds(drawingBounds); } TransformGroup transformGroup = new TransformGroup(); // Scale the clip region (at (0, 0)) and translate to the top-left corner of the target. transformGroup.Children.Add(new ScaleTransform(drawingBounds.Width, drawingBounds.Height)); transformGroup.Children.Add(new TranslateTransform(drawingBounds.X, drawingBounds.Y)); clipGeom.Transform = transformGroup; } else { if (transform != null) { clipGeom.Transform = transform; } } } if (maskBrush != null) { DrawingBrush drawingBrush = (DrawingBrush)maskBrush; SvgUnitType maskUnits = this.MaskUnits; SvgUnitType maskContentUnits = this.MaskContentUnits; if (maskUnits == SvgUnitType.ObjectBoundingBox) { Rect drawingBounds = geometryBounds; if (transform != null) { drawingBounds = transform.TransformBounds(drawingBounds); } DrawingGroup maskGroup = drawingBrush.Drawing as DrawingGroup; if (maskGroup != null) { DrawingCollection maskDrawings = maskGroup.Children; for (int i = 0; i < maskDrawings.Count; i++) { Drawing maskDrawing = maskDrawings[i]; GeometryDrawing maskGeomDraw = maskDrawing as GeometryDrawing; if (maskGeomDraw != null) { if (maskGeomDraw.Brush != null) { ConvertColors(maskGeomDraw.Brush); } if (maskGeomDraw.Pen != null) { ConvertColors(maskGeomDraw.Pen.Brush); } } } } if (maskContentUnits == SvgUnitType.ObjectBoundingBox) { TransformGroup transformGroup = new TransformGroup(); // Scale the clip region (at (0, 0)) and translate to the top-left corner of the target. var scaleTransform = new ScaleTransform(drawingBounds.Width, drawingBounds.Height); transformGroup.Children.Add(scaleTransform); var translateTransform = new TranslateTransform(drawingBounds.X, drawingBounds.Y); transformGroup.Children.Add(translateTransform); Matrix scaleMatrix = new Matrix(); Matrix translateMatrix = new Matrix(); scaleMatrix.Scale(drawingBounds.Width, drawingBounds.Height); translateMatrix.Translate(drawingBounds.X, drawingBounds.Y); Matrix matrix = Matrix.Multiply(scaleMatrix, translateMatrix); //maskBrush.Transform = transformGroup; maskBrush.Transform = new MatrixTransform(matrix); } else { drawingBrush.Viewbox = drawingBounds; drawingBrush.ViewboxUnits = BrushMappingMode.Absolute; drawingBrush.Stretch = Stretch.Uniform; drawingBrush.Viewport = drawingBounds; drawingBrush.ViewportUnits = BrushMappingMode.Absolute; } } else { if (transform != null) { maskBrush.Transform = transform; } } clipMaskGroup.OpacityMask = maskBrush; } clipMaskGroup.Children.Add(drawing); drawGroup.Children.Add(clipMaskGroup); } else { drawGroup.Children.Add(drawing); } } } // If this is not the child of a "marker", then try rendering a marker... if (!string.Equals(parentNode.LocalName, "marker")) { RenderMarkers(renderer, styleElm, context); } }
public Pen GetPen(Geometry geometry, bool setOpacity = true) { double strokeWidth = GetStrokeWidth(); if (strokeWidth.Equals(0.0d)) { return(null); } WpfSvgPaintContext paintContext = null; SvgPaintType paintType = this.PaintType; WpfSvgPaint stroke; if (paintType == SvgPaintType.None) { return(null); } if (paintType == SvgPaintType.CurrentColor) { stroke = new WpfSvgPaint(_context, _element, CssConstants.PropColor); } else if (paintType == SvgPaintType.ContextFill) { paintContext = GetFillContext(); if (paintContext != null) { stroke = paintContext.Fill; } else { stroke = this; } } else if (paintType == SvgPaintType.ContextStroke) { paintContext = GetStrokeContext(); if (paintContext != null) { stroke = paintContext.Stroke; } else { stroke = this; } } else { stroke = this; } Brush brush = stroke.GetBrush(geometry, CssConstants.PropStroke, setOpacity); if (brush == null) { WpfSvgPaint fallbackPaint = stroke.WpfFallback; if (fallbackPaint != null) { brush = fallbackPaint.GetBrush(geometry, CssConstants.PropStroke, setOpacity); } } Pen pen = new Pen(brush, strokeWidth); if (_element.HasAttribute(CssConstants.PropStrokeOpacity)) { double opacityValue = -1; string opacity = _element.GetAttribute(CssConstants.PropStrokeOpacity); if (!string.IsNullOrWhiteSpace(opacity)) { opacityValue = SvgNumber.ParseNumber(opacity); opacityValue = Math.Min(opacityValue, 1); opacityValue = Math.Max(opacityValue, 0); if (opacityValue >= 0 && opacityValue < 1) { brush.Opacity = opacityValue; } } } var lineCap = this.GetLineCap(); pen.StartLineCap = pen.EndLineCap = lineCap; pen.LineJoin = GetLineJoin(); double miterLimit = GetMiterLimit(strokeWidth); if (miterLimit > 0) { pen.MiterLimit = miterLimit; } //pen.MiterLimit = 1.0f; DoubleCollection dashArray = GetDashArray(strokeWidth); if (dashArray != null && dashArray.Count != 0) { bool isValidDashes = true; int nonZeroCount = 0; // Specs: If all of the values in the list are zero, then the stroke is // rendered as a solid line without any dashing. // If any value in the list is negative, the dash-array value is invalid. for (int i = 0; i < dashArray.Count; i++) { if (dashArray[i] < 0.0d) { isValidDashes = false; break; } if (dashArray[i].Equals(0.0d) == false) { nonZeroCount++; } } isValidDashes = isValidDashes && nonZeroCount != 0; if (isValidDashes) { DashStyle dashStyle = new DashStyle(dashArray, GetDashOffset(strokeWidth)); pen.DashStyle = dashStyle; // This is the one that works well for the XAML, the default is not Flat as // stated in the documentations... //pen.DashCap = PenLineCap.Flat; pen.DashCap = lineCap; } } return(pen); }
public override void Render(WpfDrawingRenderer renderer) { WpfDrawingContext context = renderer.Context; SvgRenderingHint hint = _svgElement.RenderingHint; if (hint != SvgRenderingHint.Shape || hint == SvgRenderingHint.Clipping) { return; } // We do not directly render the contents of the clip-path, unless specifically requested... if (String.Equals(_svgElement.ParentNode.LocalName, "clipPath") && !context.RenderingClipRegion) { return; } SvgStyleableElement styleElm = (SvgStyleableElement)_svgElement; string sVisibility = styleElm.GetPropertyValue("visibility"); string sDisplay = styleElm.GetPropertyValue("display"); if (String.Equals(sVisibility, "hidden") || String.Equals(sDisplay, "none")) { return; } DrawingGroup drawGroup = context.Peek(); Debug.Assert(drawGroup != null); Geometry geometry = CreateGeometry(_svgElement, context.OptimizePath); if (geometry != null && !geometry.IsEmpty()) { SetClip(context); WpfSvgPaint fillPaint = new WpfSvgPaint(context, styleElm, "fill"); string fileValue = styleElm.GetAttribute("fill"); Brush brush = fillPaint.GetBrush(); WpfSvgPaint strokePaint = new WpfSvgPaint(context, styleElm, "stroke"); Pen pen = strokePaint.GetPen(); if (brush != null || pen != null) { Transform transform = this.Transform; if (transform != null && !transform.Value.IsIdentity) { geometry.Transform = transform; if (brush != null) { Transform brushTransform = brush.Transform; if (brushTransform == null || brushTransform == Transform.Identity) { brush.Transform = transform; } } } else { transform = null; // render any identity transform useless... } GeometryDrawing drawing = new GeometryDrawing(brush, pen, geometry); string elementId = this.GetElementName(); if (!String.IsNullOrEmpty(elementId) && !context.IsRegisteredId(elementId)) { drawing.SetValue(FrameworkElement.NameProperty, elementId); context.RegisterId(elementId); if (context.IncludeRuntime) { SvgObject.SetId(drawing, elementId); } } Brush maskBrush = this.Masking; Geometry clipGeom = this.ClipGeometry; if (clipGeom != null || maskBrush != null) { //Geometry clipped = Geometry.Combine(geometry, clipGeom, // GeometryCombineMode.Exclude, null); //if (clipped != null && !clipped.IsEmpty()) //{ // geometry = clipped; //} DrawingGroup clipMaskGroup = new DrawingGroup(); Rect geometryBounds = geometry.Bounds; if (clipGeom != null) { clipMaskGroup.ClipGeometry = clipGeom; SvgUnitType clipUnits = this.ClipUnits; if (clipUnits == SvgUnitType.ObjectBoundingBox) { Rect drawingBounds = geometryBounds; if (transform != null) { drawingBounds = transform.TransformBounds(drawingBounds); } TransformGroup transformGroup = new TransformGroup(); // Scale the clip region (at (0, 0)) and translate to the top-left corner of the target. transformGroup.Children.Add( new ScaleTransform(drawingBounds.Width, drawingBounds.Height)); transformGroup.Children.Add( new TranslateTransform(drawingBounds.X, drawingBounds.Y)); clipGeom.Transform = transformGroup; } else { if (transform != null) { clipGeom.Transform = transform; } } } if (maskBrush != null) { SvgUnitType maskUnits = this.MaskUnits; if (maskUnits == SvgUnitType.ObjectBoundingBox) { Rect drawingBounds = geometryBounds; if (transform != null) { drawingBounds = transform.TransformBounds(drawingBounds); } TransformGroup transformGroup = new TransformGroup(); // Scale the clip region (at (0, 0)) and translate to the top-left corner of the target. transformGroup.Children.Add( new ScaleTransform(drawingBounds.Width, drawingBounds.Height)); transformGroup.Children.Add( new TranslateTransform(drawingBounds.X, drawingBounds.Y)); DrawingGroup maskGroup = ((DrawingBrush)maskBrush).Drawing as DrawingGroup; if (maskGroup != null) { DrawingCollection maskDrawings = maskGroup.Children; for (int i = 0; i < maskDrawings.Count; i++) { Drawing maskDrawing = maskDrawings[i]; GeometryDrawing maskGeomDraw = maskDrawing as GeometryDrawing; if (maskGeomDraw != null) { if (maskGeomDraw.Brush != null) { ConvertColors(maskGeomDraw.Brush); } if (maskGeomDraw.Pen != null) { ConvertColors(maskGeomDraw.Pen.Brush); } } } } //if (transformGroup != null) //{ // drawingBounds = transformGroup.TransformBounds(drawingBounds); //} //maskBrush.Viewbox = drawingBounds; //maskBrush.ViewboxUnits = BrushMappingMode.Absolute; //maskBrush.Stretch = Stretch.Uniform; //maskBrush.Viewport = drawingBounds; //maskBrush.ViewportUnits = BrushMappingMode.Absolute; maskBrush.Transform = transformGroup; } else { if (transform != null) { maskBrush.Transform = transform; } } clipMaskGroup.OpacityMask = maskBrush; } clipMaskGroup.Children.Add(drawing); drawGroup.Children.Add(clipMaskGroup); } else { drawGroup.Children.Add(drawing); } } } RenderMarkers(renderer, styleElm, context); }