public void TestFuncAttr() { XmlElement elm = getElm(); elm.SetAttribute("kalle", "", "roffe"); CssCollectedStyleDeclaration csd = new CssCollectedStyleDeclaration(elm); csd.CollectProperty("foo", 1, CssValue.GetCssValue("attr(kalle)", false), CssStyleSheetType.Author, ""); CssPrimitiveValue cssPrimValue = csd.GetPropertyCssValue("foo") as CssPrimitiveValue; Assert.IsNotNull(cssPrimValue); Assert.AreEqual("roffe", cssPrimValue.GetStringValue()); }
protected void SetClip(GdiGraphics graphics) { if (_svgElement == null) { return; } SvgRenderingHint hint = _svgElement.RenderingHint; // todo: should we correct the clipping to adjust to the off-one-pixel drawing? graphics.TranslateClip(1, 1); #region Clip with clip // see http://www.w3.org/TR/SVG/masking.html#OverflowAndClipProperties if (_svgElement is ISvgSvgElement || _svgElement is ISvgMarkerElement || _svgElement is ISvgSymbolElement || _svgElement is ISvgPatternElement) { // check overflow property CssValue overflow = _svgElement.GetComputedCssValue("overflow", string.Empty) as CssValue; // TODO: clip can have "rect(10 10 auto 10)" CssPrimitiveValue clip = _svgElement.GetComputedCssValue("clip", string.Empty) as CssPrimitiveValue; string sOverflow = null; if (overflow != null || overflow.CssText == "") { sOverflow = overflow.CssText; } else { if (this is ISvgSvgElement) { sOverflow = "hidden"; } } if (sOverflow != null) { // "If the 'overflow' property has a value other than hidden or scroll, the property has no effect (i.e., a clipping rectangle is not created)." if (sOverflow == "hidden" || sOverflow == "scroll") { RectangleF clipRect = RectangleF.Empty; if (clip != null && clip.PrimitiveType == CssPrimitiveType.Rect) { if (_svgElement is ISvgSvgElement) { ISvgSvgElement svgElement = (ISvgSvgElement)_svgElement; SvgRect viewPort = svgElement.Viewport as SvgRect; clipRect = GdiConverter.ToRectangle(viewPort); ICssRect clipShape = (CssRect)clip.GetRectValue(); if (clipShape.Top.PrimitiveType != CssPrimitiveType.Ident) { clipRect.Y += (float)clipShape.Top.GetFloatValue(CssPrimitiveType.Number); } if (clipShape.Left.PrimitiveType != CssPrimitiveType.Ident) { clipRect.X += (float)clipShape.Left.GetFloatValue(CssPrimitiveType.Number); } if (clipShape.Right.PrimitiveType != CssPrimitiveType.Ident) { clipRect.Width = (clipRect.Right - clipRect.X) - (float)clipShape.Right.GetFloatValue(CssPrimitiveType.Number); } if (clipShape.Bottom.PrimitiveType != CssPrimitiveType.Ident) { clipRect.Height = (clipRect.Bottom - clipRect.Y) - (float)clipShape.Bottom.GetFloatValue(CssPrimitiveType.Number); } } } else if (clip == null || (clip.PrimitiveType == CssPrimitiveType.Ident && clip.GetStringValue() == "auto")) { if (_svgElement is ISvgSvgElement) { ISvgSvgElement svgElement = (ISvgSvgElement)_svgElement; SvgRect viewPort = svgElement.Viewport as SvgRect; clipRect = GdiConverter.ToRectangle(viewPort); } else if (_svgElement is ISvgMarkerElement || _svgElement is ISvgSymbolElement || _svgElement is ISvgPatternElement) { // TODO: what to do here? } } if (clipRect != RectangleF.Empty) { graphics.SetClip(clipRect); } } } } #endregion #region Clip with clip-path // see: http://www.w3.org/TR/SVG/masking.html#EstablishingANewClippingPath if (hint == SvgRenderingHint.Shape || hint == SvgRenderingHint.Text || hint == SvgRenderingHint.Clipping || hint == SvgRenderingHint.Masking || hint == SvgRenderingHint.Containment || hint == SvgRenderingHint.Image) { CssPrimitiveValue clipPath = _svgElement.GetComputedCssValue("clip-path", string.Empty) as CssPrimitiveValue; if (clipPath != null && clipPath.PrimitiveType == CssPrimitiveType.Uri) { string absoluteUri = _svgElement.ResolveUri(clipPath.GetStringValue()); SvgClipPathElement eClipPath = _svgElement.OwnerDocument.GetNodeByUri(absoluteUri) as SvgClipPathElement; if (eClipPath != null) { GraphicsPath gpClip = CreateClippingRegion(graphics, eClipPath); RectangleF clipBounds = gpClip != null?gpClip.GetBounds() : RectangleF.Empty; if (clipBounds.Width.Equals(0) || clipBounds.Height.Equals(0)) { return; } SvgUnitType pathUnits = (SvgUnitType)eClipPath.ClipPathUnits.AnimVal; if (pathUnits == SvgUnitType.ObjectBoundingBox) { SvgTransformableElement transElement = _svgElement as SvgTransformableElement; if (transElement != null) { ISvgRect bbox = transElement.GetBBox(); // scale clipping path Matrix matrix = new Matrix(); matrix.Scale((float)bbox.Width, (float)bbox.Height); gpClip.Transform(matrix); graphics.SetClip(gpClip); // offset clip graphics.TranslateClip((float)bbox.X, (float)bbox.Y); } else { throw new NotImplementedException("clip-path with SvgUnitType.ObjectBoundingBox " + "not supported for this type of element: " + _svgElement.GetType()); } } else { graphics.SetClip(gpClip); } gpClip.Dispose(); gpClip = null; } } } #endregion }
protected void 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; } }
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 }