public WpfRendering(SvgElement element) : base(element) { _maskUnits = SvgUnitType.UserSpaceOnUse; _clipPathUnits = SvgUnitType.UserSpaceOnUse; _maskContentUnits = SvgUnitType.UserSpaceOnUse; }
public SvgContextMapper(int height, int width, SvgUnitType unitType, Font font) { Height = height; Width = width; UnitType = unitType; Font = font; }
/// <summary> /// Adjust SVG to fit content with return of SvgDocument /// </summary> /// <param name="svgXml"></param> /// <param name="docWidth">Desired document width</param> /// <param name="docUnits"></param> /// <returns></returns> public static SvgDocument AdjustSvgDocumentToFitContent( string svgXml, float docWidth, SvgUnitType docUnits) { string svgXml2 = null; SvgDocument doc = null; RectangleF bb = new RectangleF(); if (Lex.IsUndefined(svgXml)) { return(null); } try { doc = SvgDocument.FromSvg <SvgDocument>(svgXml); SizeF dr = doc.GetDimensions(); // document dimensions in current units (e.g. pixel, inch, millimeter...) SvgViewBox vb = doc.ViewBox; // internal coord view box (viewport) (undefined initially) //SvgAspectRatio aspectRatio = doc.AspectRatio; // aspect of the viewport. //RectangleF docBounds = doc.Bounds; // bounds of the svg element //SvgUnit docLeft = doc.X; // left position //SvgUnit docTop = doc.Y; // top position //SvgUnit docHeight = doc.Height; // height //SvgUnit docWidth = doc.Width; // width RectangleF b = doc.Bounds; // unitless bounds of the document svg elements float dy = 5, dx = 5; // padding around the doc elements (this is arbitrary, needs work) //if (b.Width > 0 && b.Height > 0) // add padding keeping aspect ration (not necessary) // dx = dy * (b.Width / b.Height); bb = new RectangleF(b.X - dx, b.Y - dy, b.Width + 2 * dx, b.Height + 2 * dy); float bbLeft = bb.Left; float bbTop = bb.Top; float bbWidth = bb.Width; if (bbWidth <= 0) { bbWidth = 1; // avoid possible zero divide } float bbHeight = bb.Height; SvgViewBox vb2 = new SvgViewBox(bbLeft, bbTop, bbWidth, bbHeight); // adjust the view box to just contain the image elements doc.ViewBox = vb2; docUnits = doc.Width.Type; doc.Width = new SvgUnit(docUnits, docWidth); float docHeight = docWidth * (bbHeight / bbWidth); doc.Height = new SvgUnit(docUnits, docHeight); doc.X = new SvgUnit(docUnits, 0); doc.Y = new SvgUnit(docUnits, 0); if (DebugMx.True && ClientState.IsDeveloper) // debug - dump xml and bitmap { try { FileUtil.WriteFile(@"c:\downloads\SvgUtilTestXml.html", svgXml); //bmp.Save(@"c:\downloads\SvgUtilTestBmp.bmp"); } catch (Exception ex) { ex = ex; } } return(doc); } catch (Exception ex) { return(null); // ignore exceptions for now } }
public SvgCoordinateContext MapPoint(Point point, double rotation, SvgUnitType unitType) { if (point.Y < 0) { point.Y = Math.Abs(point.Y) - _offset.X; } else { point.Y = Height - point.Y; } var svgStartX = new SvgUnit(unitType, (float)point.X); var svgStartY = new SvgUnit(unitType, (float)point.Y); var context = new SvgCoordinateContext { X = svgStartX, Y = svgStartY, Rotation = new SvgRotate((float)-rotation, svgStartX, svgStartY) }; return context; }
/// <summary> /// Initializes a new instance of the <see cref="SvgUnit"/> struct. /// </summary> /// <param name="value">The value.</param> public SvgUnit(float value) { this._value = value; this._type = SvgUnitType.User; this._isEmpty = (this._value == 0.0f); this._deviceValue = null; }
private Brush GetLinearGradientBrush(SvgLinearGradientElement res, Transform viewBoxTransform = null) { GradientStopCollection gradientStops = GetGradientStops(res.Stops); if (gradientStops == null || gradientStops.Count == 0) { return(null); } double x1 = res.X1.AnimVal.Value; double x2 = res.X2.AnimVal.Value; double y1 = res.Y1.AnimVal.Value; double y2 = res.Y2.AnimVal.Value; LinearGradientBrush brush = new LinearGradientBrush(gradientStops, new Point(x1, y1), new Point(x2, y2)); SvgSpreadMethod spreadMethod = SvgSpreadMethod.Pad; if (res.SpreadMethod != null) { spreadMethod = (SvgSpreadMethod)res.SpreadMethod.AnimVal; if (spreadMethod != SvgSpreadMethod.None) { brush.SpreadMethod = WpfConvert.ToSpreadMethod(spreadMethod); } } SvgUnitType mappingMode = SvgUnitType.ObjectBoundingBox; if (res.GradientUnits != null) { mappingMode = (SvgUnitType)res.GradientUnits.AnimVal; if (mappingMode == SvgUnitType.ObjectBoundingBox) { brush.MappingMode = BrushMappingMode.RelativeToBoundingBox; } else if (mappingMode == SvgUnitType.UserSpaceOnUse) { brush.MappingMode = BrushMappingMode.Absolute; _isUserSpace = true; } } string colorInterpolation = res.GetPropertyValue("color-interpolation"); if (!string.IsNullOrWhiteSpace(colorInterpolation)) { if (string.Equals(colorInterpolation, "linearRGB", StringComparison.OrdinalIgnoreCase)) { brush.ColorInterpolationMode = ColorInterpolationMode.ScRgbLinearInterpolation; } else { brush.ColorInterpolationMode = ColorInterpolationMode.SRgbLinearInterpolation; } } MatrixTransform transform = GetTransformMatrix(res); if (transform != null && !transform.Matrix.IsIdentity) { if (viewBoxTransform != null && !viewBoxTransform.Value.IsIdentity) { TransformGroup group = new TransformGroup(); group.Children.Add(viewBoxTransform); group.Children.Add(transform); brush.Transform = group; } else { brush.Transform = transform; } } else { float fLeft = (float)res.X1.AnimVal.Value; float fRight = (float)res.X2.AnimVal.Value; float fTop = (float)res.Y1.AnimVal.Value; float fBottom = (float)res.Y2.AnimVal.Value; if (mappingMode == SvgUnitType.ObjectBoundingBox) { if (!fTop.Equals(fBottom) && !fLeft.Equals(fRight)) { var drawingBrush = new DrawingBrush(); drawingBrush.Stretch = Stretch.Fill; drawingBrush.Viewbox = new Rect(0, 0, 1, 1); var DrawingRect = new GeometryDrawing(brush, null, new RectangleGeometry(new Rect(0, 0, 1, 1))); drawingBrush.Drawing = DrawingRect; return(drawingBrush); } } if (fTop.Equals(fBottom)) { } else { if (fLeft.Equals(fRight)) { } else { if (fLeft < fRight) { if (viewBoxTransform != null && !viewBoxTransform.Value.IsIdentity) { brush.Transform = viewBoxTransform; } } else { if (viewBoxTransform != null && !viewBoxTransform.Value.IsIdentity) { brush.Transform = viewBoxTransform; } } } } } return(brush); }
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, _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) { LineGeometry lineGeometry = geometry as LineGeometry; WpfGradientFill gradientFill = (WpfGradientFill)strokePaint.PaintServer; if (gradientFill.IsUserSpace == false && lineGeometry != null) { bool invalidGrad = SvgObject.IsEqual(lineGeometry.EndPoint.X, lineGeometry.StartPoint.X) || SvgObject.IsEqual(lineGeometry.EndPoint.Y, lineGeometry.StartPoint.Y); 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... } 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); } }
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 Brush GetLinearGradientBrush(SvgLinearGradientElement res, Transform viewBoxTransform = null) { double x1 = res.X1.AnimVal.Value; double x2 = res.X2.AnimVal.Value; double y1 = res.Y1.AnimVal.Value; double y2 = res.Y2.AnimVal.Value; GradientStopCollection gradientStops = GetGradientStops(res.Stops); if (gradientStops == null || gradientStops.Count == 0) { return(null); } LinearGradientBrush brush = new LinearGradientBrush(gradientStops, new Point(x1, y1), new Point(x2, y2)); SvgSpreadMethod spreadMethod = SvgSpreadMethod.Pad; if (res.SpreadMethod != null) { spreadMethod = (SvgSpreadMethod)res.SpreadMethod.AnimVal; if (spreadMethod != SvgSpreadMethod.None) { brush.SpreadMethod = WpfConvert.ToSpreadMethod(spreadMethod); } } SvgUnitType mappingMode = SvgUnitType.ObjectBoundingBox; if (res.GradientUnits != null) { mappingMode = (SvgUnitType)res.GradientUnits.AnimVal; if (mappingMode == SvgUnitType.ObjectBoundingBox) { brush.MappingMode = BrushMappingMode.RelativeToBoundingBox; } else if (mappingMode == SvgUnitType.UserSpaceOnUse) { brush.MappingMode = BrushMappingMode.Absolute; _isUserSpace = true; //if (viewBoxTransform == null || viewBoxTransform.Value.IsIdentity) //{ // if (!elementBounds.IsEmpty) // { // viewBoxTransform = FitToViewbox(new SvgRect(x1, y1, // Math.Abs(x2 - x1), Math.Abs(y2 - y1)), elementBounds); // } //} } } string colorInterpolation = res.GetPropertyValue("color-interpolation"); if (!string.IsNullOrWhiteSpace(colorInterpolation)) { if (colorInterpolation == "linearRGB") { brush.ColorInterpolationMode = ColorInterpolationMode.ScRgbLinearInterpolation; } else { brush.ColorInterpolationMode = ColorInterpolationMode.SRgbLinearInterpolation; } } MatrixTransform transform = GetTransformMatrix(res); if (transform != null && !transform.Matrix.IsIdentity) { if (viewBoxTransform != null && !viewBoxTransform.Value.IsIdentity) { TransformGroup group = new TransformGroup(); group.Children.Add(viewBoxTransform); group.Children.Add(transform); brush.Transform = group; } else { brush.Transform = transform; //brush.StartPoint = new Point(0, 0.5); //brush.EndPoint = new Point(1, 0.5); } //brush.StartPoint = new Point(0, 0); //brush.EndPoint = new Point(1, 1); } else { float fLeft = (float)res.X1.AnimVal.Value; float fRight = (float)res.X2.AnimVal.Value; float fTop = (float)res.Y1.AnimVal.Value; float fBottom = (float)res.Y2.AnimVal.Value; if (mappingMode == SvgUnitType.ObjectBoundingBox) { if (!fTop.Equals(fBottom) && !fLeft.Equals(fRight)) { var drawingBrush = new DrawingBrush(); drawingBrush.Stretch = Stretch.Fill; drawingBrush.Viewbox = new Rect(0, 0, 1, 1); var DrawingRect = new GeometryDrawing(brush, null, new RectangleGeometry(new Rect(0, 0, 1, 1))); drawingBrush.Drawing = DrawingRect; return(drawingBrush); } } if (fTop.Equals(fBottom)) { //mode = LinearGradientMode.Horizontal; //brush.StartPoint = new Point(0, 0.5); //brush.EndPoint = new Point(1, 0.5); } else { if (fLeft.Equals(fRight)) { //mode = LinearGradientMode.Vertical; //brush.StartPoint = new Point(0.5, 0); //brush.EndPoint = new Point(0.5, 1); } else { if (fLeft < fRight) { if (viewBoxTransform != null && !viewBoxTransform.Value.IsIdentity) { //TransformGroup group = new TransformGroup(); //group.Children.Add(viewBoxTransform); //group.Children.Add(new RotateTransform(45, 0.5, 0.5)); //brush.Transform = group; brush.Transform = viewBoxTransform; } //else //{ // brush.RelativeTransform = new RotateTransform(45, 0.5, 0.5); //} //mode = LinearGradientMode.ForwardDiagonal; //brush.EndPoint = new Point(x1, y1 + 1); //brush.StartPoint = new Point(0, 0); //brush.EndPoint = new Point(1, 1); } else { //mode = LinearGradientMode.BackwardDiagonal; if (viewBoxTransform != null && !viewBoxTransform.Value.IsIdentity) { //TransformGroup group = new TransformGroup(); //group.Children.Add(viewBoxTransform); //group.Children.Add(new RotateTransform(-45, 0.5, 0.5)); //brush.Transform = group; brush.Transform = viewBoxTransform; } //else //{ // brush.RelativeTransform = new RotateTransform(-45, 0.5, 0.5); //} //brush.StartPoint = new Point(0, 0); //brush.EndPoint = new Point(1, 1); } } } } return(brush); }
public override void BeforeRender(WpfDrawingRenderer renderer) { if (renderer == null) { return; } _maskUnits = SvgUnitType.UserSpaceOnUse; _clipPathUnits = SvgUnitType.UserSpaceOnUse; _maskContentUnits = SvgUnitType.UserSpaceOnUse; WpfDrawingContext context = renderer.Context; SetQuality(context); SetTransform(context); SetClip(context); SetMask(context); }
public override void AfterRender(WpfDrawingRenderer renderer) { _clipGeometry = null; _transformMatrix = null; _maskBrush = null; _maskUnits = SvgUnitType.UserSpaceOnUse; _clipPathUnits = SvgUnitType.UserSpaceOnUse; _maskContentUnits = SvgUnitType.UserSpaceOnUse; }
/// <summary> /// Sets unit type attribute /// </summary> /// <param name="name">Attribute name</param> /// <param name="unitType">New unit type</param> public unsafe void SetAttributeValue(string name, SvgUnitType unitType) { SetAttributeValue(name, SvgAttributePodType.UnitType, new IntPtr(&unitType), sizeof(SvgUnitType)); }
private void button1_Click(object sender, EventArgs e) { /* * L 最低 * M 低 * Q 中等 * H 高 */ FolderBrowserDialog fileDialog = new FolderBrowserDialog { Description = @"请选择保存输出图件的文件夹", ShowNewFolderButton = true, SelectedPath = Environment.CurrentDirectory, }; if (fileDialog.ShowDialog() == DialogResult.OK) { List <QRCodeUrlInfo> qRCodeUrlInfos = new List <QRCodeUrlInfo>(); try { qRCodeUrlInfos = JsonConvert.DeserializeObject <List <QRCodeUrlInfo> >(textBox1.Text); } catch (Exception ex) { MessageBox.Show(ex.Message); } try { string elStr = comboBox1.SelectedItem.ToString().Split(' ')[0]; foreach (QRCodeUrlInfo qRCodeUrlInfo in qRCodeUrlInfos) { WebClient wc = new WebClient(); string xxx = System.Web.HttpUtility.UrlEncode(qRCodeUrlInfo.Url, Encoding.UTF8); string url = "http://www.liantu.com/savevector.php?text=" + xxx + "&el=" + elStr + "&m=15&vt=svg"; string svgFileFullName = fileDialog.SelectedPath + "\\" + qRCodeUrlInfo.Name + ".svg"; string svgTempFileFullName = fileDialog.SelectedPath + "\\" + qRCodeUrlInfo.Name + ".Temp.svg"; wc.DownloadFile(url, svgTempFileFullName); SvgDocument svgDoc = SvgDocument.Open(svgTempFileFullName); SvgUnit minX = SvgUnit.None; SvgUnit minY = SvgUnit.None; SvgUnit maxX = SvgUnit.None; SvgUnit maxY = SvgUnit.None; SvgUnit recWidth = SvgUnit.None; #region 获取真实边框大小 foreach (SvgElement element in svgDoc.Children) { if (element is SvgDefinitionList) { if (element.Children.Count > 0) { if (element.Children[0] is SvgRectangle) { SvgRectangle svgRectangle = element.Children[0] as SvgRectangle; recWidth = svgRectangle.Width; } } SvgDefinitionList svgDefinitionList = element as SvgDefinitionList; } if (element is SvgGroup) { if (element.Children.Count > 0) { if (element.Children[0] is SvgUse) { SvgUse svgUse = element.Children[0] as SvgUse; if (minX.IsNone || minY.IsNone) { minX = svgUse.X; minY = svgUse.Y; } else if (minX.Value > svgUse.X) { minX = svgUse.X; } else if (minY.Value > svgUse.Y) { minY = svgUse.Y; } } if (element.Children[element.Children.Count - 1] is SvgUse) { SvgUse svgUse = element.Children[element.Children.Count - 1] as SvgUse; if (maxX.IsNone || maxY.IsNone) { maxX = svgUse.X; maxY = svgUse.Y; } else if (maxX.Value < svgUse.X) { maxX = svgUse.X; } else if (maxY.Value < svgUse.Y) { maxY = svgUse.Y; } } } } } maxX.Value = maxX.Value - minX.Value + recWidth.Value; maxY.Value = maxY.Value - minY.Value + recWidth.Value; SvgUnitType svgUnitType = minX.Type; #endregion int rowNum = Convert.ToInt32(Math.Floor(maxX.Value / recWidth.Value)); #region 进行位置计算 foreach (SvgElement element in svgDoc.Children) { if (element is SvgRectangle) { SvgRectangle svgRectangle = element as SvgRectangle; svgRectangle.Width = maxX; svgRectangle.Height = maxY; } if (element is SvgGroup) { foreach (SvgElement element2 in element.Children) { SvgUse svgUse = element2 as SvgUse; if (svgUse != null) { svgUse.X = new SvgUnit(svgUnitType, svgUse.X.Value - minX.Value); svgUse.Y = new SvgUnit(svgUnitType, svgUse.Y.Value - minY.Value); } } } } #endregion for (int i = 0; i < svgDoc.Children.Count; i++) { if (svgDoc.Children[i] is SvgRectangle) { SvgRectangle svgRectangle = svgDoc.Children[i] as SvgRectangle; svgRectangle.Width = new SvgUnit(svgUnitType, maxX.Value - recWidth.Value - recWidth.Value); svgRectangle.Height = new SvgUnit(svgUnitType, maxY.Value - recWidth.Value - recWidth.Value); } if (svgDoc.Children[i] is SvgGroup) { SvgElement element = svgDoc.Children[i] as SvgElement; string attribute = string.Empty; element.TryGetAttribute("fill", out attribute); for (int j = element.Children.Count; j > 0; j--) { SvgUse svgUse = element.Children[j - 1] as SvgUse; if (((int)svgUse.Y.Value) + ((int)recWidth.Value) == ((int)maxY.Value) ||// 最后一行 ((int)svgUse.Y.Value) == 0 || // 第一行 ((int)svgUse.X.Value) + ((int)recWidth.Value) == ((int)maxX.Value) || // 最后一列 ((int)svgUse.X.Value) == 0) // 第一列 { // 最后一行 element.Children.RemoveAt(j - 1); } else { if (svgUse != null) { svgUse.X = new SvgUnit(svgUnitType, svgUse.X.Value - recWidth.Value); svgUse.Y = new SvgUnit(svgUnitType, svgUse.Y.Value - recWidth.Value); } } } } } svgDoc.Width = new SvgUnit(svgUnitType, maxX.Value - recWidth.Value - recWidth.Value); svgDoc.Height = new SvgUnit(svgUnitType, maxY.Value - recWidth.Value - recWidth.Value); svgDoc.ViewBox = new SvgViewBox(0, 0, svgDoc.Width.Value, svgDoc.Height.Value); var svgXml = svgDoc.GetXML(); File.WriteAllText(svgFileFullName, svgXml); File.Delete(svgTempFileFullName); } MessageBox.Show(@"导出完成"); } catch (Exception ex) { MessageBox.Show(ex.Message); } } }
public SvgCoordinateContext MapPoint(Point point, SvgUnitType unitType) { return(MapPoint(point, 0, unitType)); }
protected void Clip(GdiGraphics gr) { if (_svgElement == null) { return; } SvgRenderingHint hint = _svgElement.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 (_svgElement is ISvgSvgElement || _svgElement is ISvgMarkerElement || _svgElement is ISvgSymbolElement || _svgElement is ISvgPatternElement) { // check overflow property CssValue overflow = ((SvgElement)_svgElement).GetComputedCssValue("overflow", string.Empty) as CssValue; // TODO: clip can have "rect(10 10 auto 10)" CssPrimitiveValue clip = ((SvgElement)_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) { 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)_svgElement).GetComputedCssValue("clip-path", string.Empty) as CssPrimitiveValue; if (clipPath != null && clipPath.PrimitiveType == CssPrimitiveType.Uri) { string absoluteUri = ((SvgElement)_svgElement).ResolveUri(clipPath.GetStringValue()); SvgClipPathElement eClipPath = _svgElement.OwnerDocument.GetNodeByUri(absoluteUri) as SvgClipPathElement; if (eClipPath != null) { GraphicsPath gpClip = CreateClippingRegion(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); 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: " + _svgElement.GetType()); } } else { gr.SetClip(gpClip); } gpClip.Dispose(); gpClip = null; } } } #endregion }
private Brush GetRadialGradientBrush(SvgRadialGradientElement res) { double centerX = res.Cx.AnimVal.Value; double centerY = res.Cy.AnimVal.Value; double focusX = res.Fx.AnimVal.Value; double focusY = res.Fy.AnimVal.Value; double radius = res.R.AnimVal.Value; GradientStopCollection gradientStops = GetGradientStops(res.Stops); if (gradientStops == null || gradientStops.Count == 0) { return(null); } RadialGradientBrush brush = new RadialGradientBrush(gradientStops); brush.RadiusX = radius; brush.RadiusY = radius; brush.Center = new Point(centerX, centerY); brush.GradientOrigin = new Point(focusX, focusY); if (res.SpreadMethod != null) { SvgSpreadMethod spreadMethod = (SvgSpreadMethod)res.SpreadMethod.AnimVal; if (spreadMethod != SvgSpreadMethod.None) { brush.SpreadMethod = WpfConvert.ToSpreadMethod(spreadMethod); } } if (res.GradientUnits != null) { SvgUnitType mappingMode = (SvgUnitType)res.GradientUnits.AnimVal; if (mappingMode == SvgUnitType.ObjectBoundingBox) { brush.MappingMode = BrushMappingMode.RelativeToBoundingBox; } else if (mappingMode == SvgUnitType.UserSpaceOnUse) { brush.MappingMode = BrushMappingMode.Absolute; if (res.Fx.AnimVal.UnitType == SvgLengthType.Percentage) { brush.GradientOrigin = brush.Center; } _isUserSpace = true; } } MatrixTransform transform = GetTransformMatrix(res); if (transform != null && !transform.Matrix.IsIdentity) { brush.Transform = transform; } string colorInterpolation = res.GetPropertyValue("color-interpolation"); if (!string.IsNullOrWhiteSpace(colorInterpolation)) { if (colorInterpolation == "linearRGB") { brush.ColorInterpolationMode = ColorInterpolationMode.SRgbLinearInterpolation; } else { brush.ColorInterpolationMode = ColorInterpolationMode.ScRgbLinearInterpolation; } } return(brush); }
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 || 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 = CombinedGeometry.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 }
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(geometry); 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 { TransformGroup groupTransform = new TransformGroup(); groupTransform.Children.Add(brushTransform); groupTransform.Children.Add(transform); brush.Transform = groupTransform; } } } 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); }
protected void SetMask(WpfDrawingContext context) { _maskUnits = SvgUnitType.UserSpaceOnUse; _maskContentUnits = SvgUnitType.UserSpaceOnUse; CssPrimitiveValue maskPath = _svgElement.GetComputedCssValue( "mask", String.Empty) as CssPrimitiveValue; if (maskPath != null && maskPath.PrimitiveType == CssPrimitiveType.Uri) { string absoluteUri = _svgElement.ResolveUri(maskPath.GetStringValue()); SvgMaskElement maskElement = _svgElement.OwnerDocument.GetNodeByUri(absoluteUri) as SvgMaskElement; if (maskElement != null) { WpfDrawingRenderer renderer = new WpfDrawingRenderer(); renderer.Window = _svgElement.OwnerDocument.Window as SvgWindow; WpfDrawingSettings settings = context.Settings.Clone(); settings.TextAsGeometry = true; WpfDrawingContext maskContext = new WpfDrawingContext(true, settings); //maskContext.Initialize(null, context.FontFamilyVisitor, null); maskContext.Initialize(context.LinkVisitor, context.FontFamilyVisitor, context.ImageVisitor); renderer.RenderMask(maskElement, maskContext); Drawing image = renderer.Drawing; Rect bounds = new Rect(0, 0, 1, 1); //Rect destRect = GetMaskDestRect(maskElement, bounds); //destRect = bounds; //DrawingImage drawImage = new DrawingImage(image); //DrawingVisual drawingVisual = new DrawingVisual(); //DrawingContext drawingContext = drawingVisual.RenderOpen(); //drawingContext.DrawDrawing(image); //drawingContext.Close(); //RenderTargetBitmap drawImage = new RenderTargetBitmap((int)200, // (int)200, 96, 96, PixelFormats.Pbgra32); //drawImage.Render(drawingVisual); //ImageBrush imageBrush = new ImageBrush(drawImage); //imageBrush.Viewbox = image.Bounds; //imageBrush.Viewport = image.Bounds; //imageBrush.ViewboxUnits = BrushMappingMode.Absolute; //imageBrush.ViewportUnits = BrushMappingMode.Absolute; //imageBrush.TileMode = TileMode.None; //imageBrush.Stretch = Stretch.None; //this.Masking = imageBrush; DrawingBrush maskBrush = new DrawingBrush(image); //tb.Viewbox = new Rect(0, 0, destRect.Width, destRect.Height); //tb.Viewport = new Rect(0, 0, destRect.Width, destRect.Height); maskBrush.Viewbox = image.Bounds; maskBrush.Viewport = image.Bounds; maskBrush.ViewboxUnits = BrushMappingMode.Absolute; maskBrush.ViewportUnits = BrushMappingMode.Absolute; maskBrush.TileMode = TileMode.None; maskBrush.Stretch = Stretch.Uniform; ////maskBrush.AlignmentX = AlignmentX.Center; ////maskBrush.AlignmentY = AlignmentY.Center; this.Masking = maskBrush; _maskUnits = (SvgUnitType)maskElement.MaskUnits.AnimVal; _maskContentUnits = (SvgUnitType)maskElement.MaskContentUnits.AnimVal; } } }
protected void SetMask(WpfDrawingContext context) { _maskUnits = SvgUnitType.UserSpaceOnUse; _maskContentUnits = SvgUnitType.UserSpaceOnUse; CssPrimitiveValue maskPath = _svgElement.GetComputedCssValue("mask", string.Empty) as CssPrimitiveValue; SvgMaskElement maskElement = null; if (maskPath != null && maskPath.PrimitiveType == CssPrimitiveType.Uri) { string absoluteUri = _svgElement.ResolveUri(maskPath.GetStringValue()); maskElement = _svgElement.OwnerDocument.GetNodeByUri(absoluteUri) as SvgMaskElement; } else if (string.Equals(_svgElement.ParentNode.LocalName, "use")) { var parentElement = _svgElement.ParentNode as SvgElement; maskPath = parentElement.GetComputedCssValue("mask", string.Empty) as CssPrimitiveValue; if (maskPath != null && maskPath.PrimitiveType == CssPrimitiveType.Uri) { string absoluteUri = _svgElement.ResolveUri(maskPath.GetStringValue()); maskElement = _svgElement.OwnerDocument.GetNodeByUri(absoluteUri) as SvgMaskElement; } } if (maskElement != null) { WpfDrawingRenderer renderer = new WpfDrawingRenderer(); renderer.Window = _svgElement.OwnerDocument.Window as SvgWindow; WpfDrawingSettings settings = context.Settings.Clone(); settings.TextAsGeometry = true; WpfDrawingContext maskContext = new WpfDrawingContext(true, settings); //maskContext.Initialize(null, context.FontFamilyVisitor, null); maskContext.Initialize(context.LinkVisitor, context.FontFamilyVisitor, context.ImageVisitor); renderer.RenderMask(maskElement, maskContext); DrawingGroup maskDrawing = renderer.Drawing; Rect bounds = new Rect(0, 0, 1, 1); //Rect destRect = GetMaskDestRect(maskElement, bounds); //destRect = bounds; //DrawingImage drawImage = new DrawingImage(image); //DrawingVisual drawingVisual = new DrawingVisual(); //DrawingContext drawingContext = drawingVisual.RenderOpen(); //drawingContext.DrawDrawing(image); //drawingContext.Close(); //RenderTargetBitmap drawImage = new RenderTargetBitmap((int)200, // (int)200, 96, 96, PixelFormats.Pbgra32); //drawImage.Render(drawingVisual); //ImageBrush imageBrush = new ImageBrush(drawImage); //imageBrush.Viewbox = image.Bounds; //imageBrush.Viewport = image.Bounds; //imageBrush.ViewboxUnits = BrushMappingMode.Absolute; //imageBrush.ViewportUnits = BrushMappingMode.Absolute; //imageBrush.TileMode = TileMode.None; //imageBrush.Stretch = Stretch.None; //this.Masking = imageBrush; DrawingBrush maskBrush = new DrawingBrush(maskDrawing); //tb.Viewbox = new Rect(0, 0, destRect.Width, destRect.Height); //tb.Viewport = new Rect(0, 0, destRect.Width, destRect.Height); maskBrush.Viewbox = maskDrawing.Bounds; maskBrush.Viewport = maskDrawing.Bounds; maskBrush.ViewboxUnits = BrushMappingMode.Absolute; maskBrush.ViewportUnits = BrushMappingMode.Absolute; maskBrush.TileMode = TileMode.None; maskBrush.Stretch = Stretch.Uniform; ////maskBrush.AlignmentX = AlignmentX.Center; ////maskBrush.AlignmentY = AlignmentY.Center; this.Masking = maskBrush; _maskUnits = (SvgUnitType)maskElement.MaskUnits.AnimVal; _maskContentUnits = (SvgUnitType)maskElement.MaskContentUnits.AnimVal; } }
public static LinearGradientBrush ConstructBrush(SvgLinearGradientElement gradient, Rect bounds, Matrix transform) { if (gradient.Stops.Count == 0) { return(null); } double x1 = gradient.X1.AnimVal.Value; double x2 = gradient.X2.AnimVal.Value; double y1 = gradient.Y1.AnimVal.Value; double y2 = gradient.Y2.AnimVal.Value; GradientStopCollection gradientStops = ToGradientStops(gradient.Stops); LinearGradientBrush brush = new LinearGradientBrush(gradientStops, new Point(x1, y1), new Point(x2, y2)); SvgSpreadMethod spreadMethod = SvgSpreadMethod.Pad; if (gradient.SpreadMethod != null) { spreadMethod = (SvgSpreadMethod)gradient.SpreadMethod.AnimVal; if (TryGetSpreadMethod(spreadMethod, out GradientSpreadMethod sm)) { brush.SpreadMethod = sm; } } SvgUnitType mappingMode = SvgUnitType.ObjectBoundingBox; if (gradient.GradientUnits != null) { mappingMode = (SvgUnitType)gradient.GradientUnits.AnimVal; if (mappingMode == SvgUnitType.ObjectBoundingBox) { brush.MappingMode = BrushMappingMode.RelativeToBoundingBox; } else if (mappingMode == SvgUnitType.UserSpaceOnUse) { brush.MappingMode = BrushMappingMode.Absolute; brush.StartPoint.Offset(bounds.X, bounds.Y); brush.EndPoint.Offset(bounds.X, bounds.Y); } } Matrix brushTransform = ToWpfMatrix(((SvgTransformList)gradient.GradientTransform.AnimVal).TotalMatrix); if (mappingMode == SvgUnitType.UserSpaceOnUse) { brushTransform *= transform; } if (!brushTransform.IsIdentity) { brush.Transform = new MatrixTransform(brushTransform); } string colorInterpolation = gradient.GetPropertyValue("color-interpolation"); if (!string.IsNullOrWhiteSpace(colorInterpolation)) { if (colorInterpolation == "linearRGB") { brush.ColorInterpolationMode = ColorInterpolationMode.ScRgbLinearInterpolation; } else { brush.ColorInterpolationMode = ColorInterpolationMode.SRgbLinearInterpolation; } } return(brush); }
private Brush GetRadialGradientBrush(SvgRadialGradientElement res) { var refElem = res.ReferencedElement; double centerX = res.Cx.AnimVal.Value; double centerY = res.Cy.AnimVal.Value; // 'fx', 'fy', and 'fr' define the start circle for the radial gradient. double focusX = res.Fx.AnimVal.Value; double focusY = res.Fy.AnimVal.Value; double radius = res.R.AnimVal.Value; var lengthUnit = res.Cx.AnimVal.UnitType; // If attribute 'fx' is not specified, 'fx' will coincide with the presentational // value of 'cx' for the element whether the value for 'cx' was inherited or not. if (lengthUnit == SvgLengthType.Percentage) { if (!res.HasAttribute("fx") && (refElem == null || !refElem.HasAttribute("fx"))) { focusX = centerX; } else if (focusX.Equals(0.0)) { focusX = centerX; if (focusX > 0 && focusX >= radius) { focusX = (centerX > radius) ? centerX - radius : focusX = radius; } } else { if (focusX > 0 && focusX >= radius) { focusX = (centerX > radius) ? centerX - radius : focusX = radius; } } } lengthUnit = res.Cy.AnimVal.UnitType; // If attribute 'fy' is not specified, 'fy' will coincide with the presentational // value of 'cy' for the element whether the value for 'cy' was inherited or not. if (lengthUnit == SvgLengthType.Percentage) { if (!res.HasAttribute("fy") && (refElem == null || !refElem.HasAttribute("fy"))) { focusY = centerY; } else if (focusY.Equals(0.0)) { focusY = centerY; if (focusY > 0 && focusY >= radius) { focusY = (centerY > radius) ? centerY - radius : focusY = radius; } } else { if (focusY > 0 && focusY >= radius) { focusY = (centerY > radius) ? centerY - radius : focusY = radius; } } } GradientStopCollection gradientStops = GetGradientStops(res.Stops); if (gradientStops == null || gradientStops.Count == 0) { return(null); } RadialGradientBrush brush = new RadialGradientBrush(gradientStops); brush.RadiusX = radius; brush.RadiusY = radius; brush.Center = new Point(centerX, centerY); brush.GradientOrigin = new Point(focusX, focusY); if (res.SpreadMethod != null) { SvgSpreadMethod spreadMethod = (SvgSpreadMethod)res.SpreadMethod.AnimVal; if (spreadMethod != SvgSpreadMethod.None) { brush.SpreadMethod = WpfConvert.ToSpreadMethod(spreadMethod); } } if (res.GradientUnits != null) { SvgUnitType mappingMode = (SvgUnitType)res.GradientUnits.AnimVal; if (mappingMode == SvgUnitType.ObjectBoundingBox) { brush.MappingMode = BrushMappingMode.RelativeToBoundingBox; } else if (mappingMode == SvgUnitType.UserSpaceOnUse) { brush.MappingMode = BrushMappingMode.Absolute; if (res.Fx.AnimVal.UnitType == SvgLengthType.Percentage) { brush.GradientOrigin = brush.Center; } _isUserSpace = true; } } MatrixTransform transform = GetTransformMatrix(res); if (transform != null && !transform.Matrix.IsIdentity) { brush.Transform = transform; } string colorInterpolation = res.GetPropertyValue("color-interpolation"); if (!string.IsNullOrWhiteSpace(colorInterpolation)) { if (string.Equals(colorInterpolation, "linearRGB", StringComparison.OrdinalIgnoreCase)) { brush.ColorInterpolationMode = ColorInterpolationMode.SRgbLinearInterpolation; } else { brush.ColorInterpolationMode = ColorInterpolationMode.ScRgbLinearInterpolation; } } return(brush); }
public static RadialGradientBrush ConstructBrush(SvgRadialGradientElement gradient, Rect bounds, Matrix transform) { if (gradient.Stops.Count == 0) { return(null); } double centerX = gradient.Cx.AnimVal.Value; double centerY = gradient.Cy.AnimVal.Value; double focusX = gradient.Fx.AnimVal.Value; double focusY = gradient.Fy.AnimVal.Value; double radius = gradient.R.AnimVal.Value; GradientStopCollection gradientStops = ToGradientStops(gradient.Stops); RadialGradientBrush brush = new RadialGradientBrush(gradientStops); brush.RadiusX = radius; brush.RadiusY = radius; brush.Center = new Point(centerX, centerY); brush.GradientOrigin = new Point(focusX, focusY); if (gradient.SpreadMethod != null) { SvgSpreadMethod spreadMethod = (SvgSpreadMethod)gradient.SpreadMethod.AnimVal; if (TryGetSpreadMethod(spreadMethod, out GradientSpreadMethod sm)) { brush.SpreadMethod = sm; } } SvgUnitType mappingMode = SvgUnitType.ObjectBoundingBox; if (gradient.GradientUnits != null) { mappingMode = (SvgUnitType)gradient.GradientUnits.AnimVal; if (mappingMode == SvgUnitType.ObjectBoundingBox) { brush.MappingMode = BrushMappingMode.RelativeToBoundingBox; } else if (mappingMode == SvgUnitType.UserSpaceOnUse) { brush.MappingMode = BrushMappingMode.Absolute; brush.Center.Offset(bounds.X, bounds.Y); brush.GradientOrigin.Offset(bounds.X, bounds.Y); } } Matrix brushTransform = ToWpfMatrix(((SvgTransformList)gradient.GradientTransform.AnimVal).TotalMatrix); if (mappingMode == SvgUnitType.UserSpaceOnUse) { brushTransform *= transform; } if (!brushTransform.IsIdentity) { brush.Transform = new MatrixTransform(brushTransform); } string colorInterpolation = gradient.GetPropertyValue("color-interpolation"); if (!string.IsNullOrWhiteSpace(colorInterpolation)) { if (colorInterpolation == "linearRGB") { brush.ColorInterpolationMode = ColorInterpolationMode.SRgbLinearInterpolation; } else { brush.ColorInterpolationMode = ColorInterpolationMode.ScRgbLinearInterpolation; } } return(brush); }
/// <summary> /// Initializes a new instance of the <see cref="SvgUnit"/> struct. /// </summary> /// <param name="type">The type.</param> /// <param name="value">The value.</param> public SvgUnit(SvgUnitType type, float value) { this._type = type; this._value = value; this._isEmpty = (this._value == 0.0f); this._deviceValue = null; }
public override void Render(WpfDrawingRenderer renderer) { WpfDrawingContext context = renderer.Context; SvgImageElement imageElement = (SvgImageElement)_svgElement; double x = imageElement.X.AnimVal.Value; double y = imageElement.Y.AnimVal.Value; double width = imageElement.Width.AnimVal.Value; double height = imageElement.Height.AnimVal.Value; Rect destRect = new Rect(x, y, width, height); Rect clipRect = new Rect(x, y, width, height); ImageSource imageSource = null; if (imageElement.IsSvgImage) { if (imageElement.IsRootReferenced(imageElement.OwnerDocument.BaseURI)) { return; } SvgWindow wnd = GetSvgWindow(); if (wnd == null) { return; } //_embeddedRenderer.BackColor = Color.Empty; _embeddedRenderer.Render(wnd.Document); DrawingGroup imageGroup = _embeddedRenderer.Drawing as DrawingGroup; if (imageGroup != null && (imageGroup.Children != null && imageGroup.Children.Count == 1)) { DrawingGroup imageDrawing = imageGroup.Children[0] as DrawingGroup; if (imageDrawing != null) { imageDrawing.ClipGeometry = null; imageSource = new DrawingImage(imageDrawing); } else { imageGroup.ClipGeometry = null; imageSource = new DrawingImage(imageGroup); } } else { imageSource = new DrawingImage(_embeddedRenderer.Drawing); } if (_embeddedRenderer != null) { _embeddedRenderer.Dispose(); _embeddedRenderer = null; } } else { imageSource = GetBitmapSource(imageElement, context); } if (imageSource == null) { return; } //TODO--PAUL: Set the DecodePixelWidth/DecodePixelHeight? // Freeze the DrawingImage for performance benefits. //imageSource.Freeze(); DrawingGroup drawGroup = null; ISvgAnimatedPreserveAspectRatio animatedAspectRatio = imageElement.PreserveAspectRatio; if (animatedAspectRatio != null && animatedAspectRatio.AnimVal != null) { SvgPreserveAspectRatio aspectRatio = animatedAspectRatio.AnimVal as SvgPreserveAspectRatio; SvgPreserveAspectRatioType aspectRatioType = (aspectRatio != null) ? aspectRatio.Align : SvgPreserveAspectRatioType.Unknown; if (aspectRatio != null && aspectRatioType != SvgPreserveAspectRatioType.None && aspectRatioType != SvgPreserveAspectRatioType.Unknown) { double imageWidth = imageSource.Width; double imageHeight = imageSource.Height; double viewWidth = destRect.Width; double viewHeight = destRect.Height; SvgMeetOrSlice meetOrSlice = aspectRatio.MeetOrSlice; if (meetOrSlice == SvgMeetOrSlice.Meet) { if (imageWidth <= viewWidth && imageHeight <= viewHeight) { if (this.Transform == null) { if (!aspectRatio.IsDefaultAlign) // Cacxa { destRect = this.GetBounds(destRect, new Size(imageWidth, imageHeight), aspectRatioType); } else { Transform viewTransform = this.GetAspectRatioTransform(aspectRatio, new SvgRect(0, 0, imageWidth, imageHeight), new SvgRect(destRect.X, destRect.Y, destRect.Width, destRect.Height)); if (viewTransform != null) { drawGroup = new DrawingGroup(); drawGroup.Transform = viewTransform; DrawingGroup lastGroup = context.Peek(); Debug.Assert(lastGroup != null); if (lastGroup != null) { lastGroup.Children.Add(drawGroup); } destRect = this.GetBounds(destRect, new Size(imageWidth, imageHeight), aspectRatioType); // The origin is already handled by the view transform... destRect.X = 0; destRect.Y = 0; } } } else { destRect = new Rect(0, 0, viewWidth, viewHeight); } } else { if (this.Transform == null) { Transform viewTransform = this.GetAspectRatioTransform(aspectRatio, new SvgRect(0, 0, imageWidth, imageHeight), new SvgRect(destRect.X, destRect.Y, destRect.Width, destRect.Height)); if (viewTransform != null) { drawGroup = new DrawingGroup(); drawGroup.Transform = viewTransform; DrawingGroup lastGroup = context.Peek(); Debug.Assert(lastGroup != null); if (lastGroup != null) { lastGroup.Children.Add(drawGroup); } destRect = this.GetBounds(destRect, new Size(imageWidth, imageHeight), aspectRatioType); // The origin is already handled by the view transform... destRect.X = 0; destRect.Y = 0; } } } } else if (meetOrSlice == SvgMeetOrSlice.Slice) { var fScaleX = viewWidth / imageWidth; var fScaleY = viewHeight / imageHeight; Transform viewTransform = this.GetAspectRatioTransform(aspectRatio, new SvgRect(0, 0, imageWidth, imageHeight), new SvgRect(destRect.X, destRect.Y, destRect.Width, destRect.Height)); DrawingGroup sliceGroup = new DrawingGroup(); sliceGroup.ClipGeometry = new RectangleGeometry(clipRect); DrawingGroup lastGroup = context.Peek(); Debug.Assert(lastGroup != null); if (lastGroup != null) { lastGroup.Children.Add(sliceGroup); } if (viewTransform != null) { drawGroup = new DrawingGroup(); drawGroup.Transform = viewTransform; sliceGroup.Children.Add(drawGroup); destRect = this.GetBounds(destRect, new Size(imageWidth, imageHeight), aspectRatioType); // The origin is already handled by the view transform... destRect.X = 0; destRect.Y = 0; } else { drawGroup = sliceGroup; } } } } ImageDrawing drawing = new ImageDrawing(imageSource, destRect); float opacityValue = -1; string opacity = imageElement.GetAttribute("opacity"); if (string.IsNullOrWhiteSpace(opacity)) { opacity = imageElement.GetPropertyValue("opacity"); } if (!string.IsNullOrWhiteSpace(opacity)) { opacityValue = (float)SvgNumber.ParseNumber(opacity); opacityValue = Math.Min(opacityValue, 1); opacityValue = Math.Max(opacityValue, 0); } Geometry clipGeom = this.ClipGeometry; Transform transform = this.Transform; bool ownedGroup = true; if (drawGroup == null) { drawGroup = context.Peek(); ownedGroup = false; } Debug.Assert(drawGroup != null); if (drawGroup != null) { if ((opacityValue >= 0 && opacityValue < 1) || (clipGeom != null && !clipGeom.IsEmpty()) || (transform != null && !transform.Value.IsIdentity)) { DrawingGroup clipGroup = ownedGroup ? drawGroup : new DrawingGroup(); if (opacityValue >= 0 && opacityValue < 1) { clipGroup.Opacity = opacityValue; } if (clipGeom != null) { SvgUnitType clipUnits = this.ClipUnits; if (clipUnits == SvgUnitType.ObjectBoundingBox) { Rect drawingBounds = drawing.Bounds; 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; } clipGroup.ClipGeometry = clipGeom; } if (transform != null) { Transform curTransform = clipGroup.Transform; if (curTransform != null && curTransform.Value.IsIdentity == false) { TransformGroup transformGroup = new TransformGroup(); transformGroup.Children.Add(curTransform); transformGroup.Children.Add(transform); clipGroup.Transform = transformGroup; } else { clipGroup.Transform = transform; } } clipGroup.Children.Add(drawing); if (!ownedGroup) { drawGroup.Children.Add(clipGroup); } } else { drawGroup.Children.Add(drawing); } string elementId = this.GetElementName(); if (ownedGroup) { string sVisibility = imageElement.GetPropertyValue("visibility"); string sDisplay = imageElement.GetPropertyValue("display"); if (string.Equals(sVisibility, "hidden") || string.Equals(sDisplay, "none")) { drawGroup.Opacity = 0; } if (!_idAssigned && !string.IsNullOrWhiteSpace(elementId) && !context.IsRegisteredId(elementId)) { SvgObject.SetName(drawGroup, elementId); context.RegisterId(elementId); if (context.IncludeRuntime) { SvgObject.SetId(drawGroup, elementId); } } } else if (!_idAssigned) { if (!_idAssigned && !string.IsNullOrWhiteSpace(elementId) && !context.IsRegisteredId(elementId)) { SvgObject.SetName(imageSource, elementId); context.RegisterId(elementId); if (context.IncludeRuntime) { SvgObject.SetId(imageSource, elementId); } } } } }
public SvgCoordinateContext MapPoint(Point point, SvgUnitType unitType) { return MapPoint(point, 0, unitType); }
private LinearGradientBrush GetLinearGradientBrush(Rect elementBounds, SvgLinearGradientElement res) { double x1 = res.X1.AnimVal.Value; double x2 = res.X2.AnimVal.Value; double y1 = res.Y1.AnimVal.Value; double y2 = res.Y2.AnimVal.Value; GradientStopCollection gradientStops = GetGradientStops(res.Stops); //LinearGradientBrush brush = new LinearGradientBrush(gradientStops); LinearGradientBrush brush = new LinearGradientBrush(gradientStops, new Point(x1, y1), new Point(x2, y2)); SvgSpreadMethod spreadMethod = SvgSpreadMethod.Pad; if (res.SpreadMethod != null) { spreadMethod = (SvgSpreadMethod)res.SpreadMethod.AnimVal; if (spreadMethod != SvgSpreadMethod.None) { brush.SpreadMethod = WpfConvert.ToSpreadMethod(spreadMethod); } } Transform viewBoxTransform = null; SvgUnitType mappingMode = SvgUnitType.ObjectBoundingBox; if (res.GradientUnits != null) { mappingMode = (SvgUnitType)res.GradientUnits.AnimVal; if (mappingMode == SvgUnitType.ObjectBoundingBox) { brush.MappingMode = BrushMappingMode.RelativeToBoundingBox; } else if (mappingMode == SvgUnitType.UserSpaceOnUse) { brush.MappingMode = BrushMappingMode.Absolute; viewBoxTransform = FitToViewbox(new SvgRect(x1, y1, Math.Abs(x2 - x1), Math.Abs(y2 - y1)), elementBounds); } } MatrixTransform transform = GetTransformMatrix(res); if (transform != null && !transform.Matrix.IsIdentity) { if (viewBoxTransform != null) { TransformGroup group = new TransformGroup(); group.Children.Add(viewBoxTransform); group.Children.Add(transform); brush.Transform = group; } else { brush.Transform = transform; //brush.StartPoint = new Point(0, 0.5); //brush.EndPoint = new Point(1, 0.5); } //brush.StartPoint = new Point(0, 0); //brush.EndPoint = new Point(1, 1); } else { float fLeft = (float)res.X1.AnimVal.Value; float fRight = (float)res.X2.AnimVal.Value; float fTop = (float)res.Y1.AnimVal.Value; float fBottom = (float)res.Y2.AnimVal.Value; if (fTop == fBottom) { //mode = LinearGradientMode.Horizontal; //brush.StartPoint = new Point(0, 0.5); //brush.EndPoint = new Point(1, 0.5); } else { if (fLeft == fRight) { //mode = LinearGradientMode.Vertical; //brush.StartPoint = new Point(0.5, 0); //brush.EndPoint = new Point(0.5, 1); } else { if (fLeft < fRight) { if (viewBoxTransform != null) { TransformGroup group = new TransformGroup(); group.Children.Add(viewBoxTransform); group.Children.Add(new RotateTransform(45, 0.5, 0.5)); brush.Transform = group; } else { brush.RelativeTransform = new RotateTransform(45, 0.5, 0.5); } //mode = LinearGradientMode.ForwardDiagonal; //brush.EndPoint = new Point(x1, y1 + 1); //brush.StartPoint = new Point(0, 0); //brush.EndPoint = new Point(1, 1); } else { //mode = LinearGradientMode.BackwardDiagonal; if (viewBoxTransform != null) { TransformGroup group = new TransformGroup(); group.Children.Add(viewBoxTransform); group.Children.Add(new RotateTransform(-45, 0.5, 0.5)); brush.Transform = group; } else { brush.RelativeTransform = new RotateTransform(-45, 0.5, 0.5); } //brush.StartPoint = new Point(0, 0); //brush.EndPoint = new Point(1, 1); } } } } string colorInterpolation = res.GetPropertyValue("color-interpolation"); if (!String.IsNullOrEmpty(colorInterpolation)) { if (colorInterpolation == "linearRGB") { brush.ColorInterpolationMode = ColorInterpolationMode.ScRgbLinearInterpolation; } else { brush.ColorInterpolationMode = ColorInterpolationMode.SRgbLinearInterpolation; } } return(brush); }
public override void Render(WpfDrawingRenderer renderer) { WpfDrawingContext context = renderer.Context; SvgImageElement imageElement = (SvgImageElement)_svgElement; double width = imageElement.Width.AnimVal.Value; double height = imageElement.Height.AnimVal.Value; Rect destRect = new Rect(imageElement.X.AnimVal.Value, imageElement.Y.AnimVal.Value, width, height); ImageSource imageSource = null; if (imageElement.IsSvgImage) { SvgWindow wnd = GetSvgWindow(); //_embeddedRenderer.BackColor = Color.Empty; _embeddedRenderer.Render(wnd.Document); DrawingGroup imageGroup = _embeddedRenderer.Drawing as DrawingGroup; if (imageGroup != null && (imageGroup.Children != null && imageGroup.Children.Count == 1)) { DrawingGroup drawImage = imageGroup.Children[0] as DrawingGroup; if (drawImage != null) { if (drawImage.ClipGeometry != null) { drawImage.ClipGeometry = null; } imageSource = new DrawingImage(drawImage); } else { if (imageGroup.ClipGeometry != null) { imageGroup.ClipGeometry = null; } imageSource = new DrawingImage(imageGroup); } } else { imageSource = new DrawingImage(_embeddedRenderer.Drawing); } if (_embeddedRenderer != null) { _embeddedRenderer.Dispose(); _embeddedRenderer = null; } } else { imageSource = GetBitmapSource(imageElement, context); } if (imageSource == null) { return; } //TODO--PAUL: Set the DecodePixelWidth/DecodePixelHeight? // Freeze the DrawingImage for performance benefits. imageSource.Freeze(); DrawingGroup drawGroup = null; ISvgAnimatedPreserveAspectRatio animatedAspectRatio = imageElement.PreserveAspectRatio; if (animatedAspectRatio != null && animatedAspectRatio.AnimVal != null) { SvgPreserveAspectRatio aspectRatio = animatedAspectRatio.AnimVal as SvgPreserveAspectRatio; SvgPreserveAspectRatioType aspectRatioType = (aspectRatio != null) ? aspectRatio.Align : SvgPreserveAspectRatioType.Unknown; if (aspectRatio != null && aspectRatioType != SvgPreserveAspectRatioType.None && aspectRatioType != SvgPreserveAspectRatioType.Unknown) { double imageWidth = imageSource.Width; double imageHeight = imageSource.Height; double viewWidth = destRect.Width; double viewHeight = destRect.Height; SvgMeetOrSlice meetOrSlice = aspectRatio.MeetOrSlice; if (meetOrSlice == SvgMeetOrSlice.Meet) { if (imageWidth <= viewWidth && imageHeight <= viewHeight) { destRect = this.GetBounds(destRect, new Size(imageWidth, imageHeight), aspectRatioType); } else { Transform viewTransform = this.GetAspectRatioTransform(aspectRatio, new SvgRect(0, 0, imageWidth, imageHeight), new SvgRect(destRect.X, destRect.Y, destRect.Width, destRect.Height)); //Transform scaleTransform = this.FitToViewbox(aspectRatio, // new SvgRect(destRect.X, destRect.Y, imageWidth, imageHeight), // new SvgRect(destRect.X, destRect.Y, destRect.Width, destRect.Height)); if (viewTransform != null) { drawGroup = new DrawingGroup(); drawGroup.Transform = viewTransform; DrawingGroup lastGroup = context.Peek(); Debug.Assert(lastGroup != null); if (lastGroup != null) { lastGroup.Children.Add(drawGroup); } destRect = this.GetBounds(destRect, new Size(imageWidth, imageHeight), aspectRatioType); // The origin is already handled by the view transform... destRect.X = 0; destRect.Y = 0; } } } else if (meetOrSlice == SvgMeetOrSlice.Slice) { } } } ImageDrawing drawing = new ImageDrawing(imageSource, destRect); float opacityValue = -1; string opacity = imageElement.GetAttribute("opacity"); if (opacity != null && opacity.Length > 0) { opacityValue = (float)SvgNumber.ParseNumber(opacity); opacityValue = Math.Min(opacityValue, 1); opacityValue = Math.Max(opacityValue, 0); } Geometry clipGeom = this.ClipGeometry; Transform transform = this.Transform; if (drawGroup == null) { drawGroup = context.Peek(); } Debug.Assert(drawGroup != null); if (drawGroup != null) { if (opacityValue >= 0 || (clipGeom != null && !clipGeom.IsEmpty()) || (transform != null && !transform.Value.IsIdentity)) { DrawingGroup clipGroup = new DrawingGroup(); if (opacityValue >= 0) { clipGroup.Opacity = opacityValue; } if (clipGeom != null) { SvgUnitType clipUnits = this.ClipUnits; if (clipUnits == SvgUnitType.ObjectBoundingBox) { Rect drawingBounds = drawing.Bounds; 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; } clipGroup.ClipGeometry = clipGeom; } if (transform != null) { clipGroup.Transform = transform; } clipGroup.Children.Add(drawing); drawGroup.Children.Add(clipGroup); } else { drawGroup.Children.Add(drawing); } } }
private LinearGradientBrush GetLinearGradientBrush(SvgLinearGradientElement res) { double x1 = res.X1.AnimVal.Value; double x2 = res.X2.AnimVal.Value; double y1 = res.Y1.AnimVal.Value; double y2 = res.Y2.AnimVal.Value; GradientStopCollection gradientStops = GetGradientStops(res.Stops); LinearGradientBrush brush = new LinearGradientBrush(gradientStops, new Point(x1, y1), new Point(x2, y2)); SvgSpreadMethod spreadMethod = SvgSpreadMethod.None; if (res.SpreadMethod != null) { spreadMethod = (SvgSpreadMethod)res.SpreadMethod.AnimVal; if (spreadMethod != SvgSpreadMethod.None) { brush.SpreadMethod = WpfConvert.ToSpreadMethod(spreadMethod); } } if (res.GradientUnits != null) { SvgUnitType mappingMode = (SvgUnitType)res.GradientUnits.AnimVal; if (mappingMode == SvgUnitType.ObjectBoundingBox) { brush.MappingMode = BrushMappingMode.RelativeToBoundingBox; } else if (mappingMode == SvgUnitType.UserSpaceOnUse) { brush.MappingMode = BrushMappingMode.Absolute; } } MatrixTransform transform = GetTransformMatrix(res); if (transform != null && !transform.Matrix.IsIdentity) { brush.Transform = transform; } //else //{ // float fLeft = (float)res.X1.AnimVal.Value; // float fRight = (float)res.X2.AnimVal.Value; // float fTop = (float)res.Y1.AnimVal.Value; // float fBottom = (float)res.Y2.AnimVal.Value; // if (fTop == fBottom) // { // //mode = LinearGradientMode.Horizontal; // } // else // { // if (fLeft == fRight) // { // //mode = LinearGradientMode.Vertical; // } // else // { // if (fLeft < fRight) // { // //mode = LinearGradientMode.ForwardDiagonal; // brush.Transform = new RotateTransform(45, 0, 0); // //brush.EndPoint = new Point(x1, y1 + 1); // } // else // { // //mode = LinearGradientMode.BackwardDiagonal; // brush.Transform = new RotateTransform(-45); // } // } // } //} string colorInterpolation = res.GetPropertyValue("color-interpolation"); if (!String.IsNullOrEmpty(colorInterpolation)) { if (colorInterpolation == "linearRGB") { brush.ColorInterpolationMode = ColorInterpolationMode.ScRgbLinearInterpolation; } else { brush.ColorInterpolationMode = ColorInterpolationMode.SRgbLinearInterpolation; } } return(brush); }