Beispiel #1
0
        public override void BeforeRender(WpfDrawingRenderer renderer)
        {
            base.BeforeRender(renderer);

            WpfDrawingContext context = renderer.Context;

            if (context.Count == 0)
            {
                _drawGroup = new DrawingGroup();
                context.Push(_drawGroup);
                context.Root = _drawGroup;
            }
            else if (context.Count == 1)
            {
                DrawingGroup currentGroup = context.Peek();

                if (currentGroup == null)
                {
                    throw new InvalidOperationException("An existing group is expected.");
                }

                if (currentGroup == context.Root)
                {
                    if (context.IsFragment)
                    {
                        // Do not add extra layer to fragments...
                        _drawGroup = currentGroup;
                    }
                    else
                    {
                        _drawGroup = new DrawingGroup();
                        SvgObject.SetName(_drawGroup, SvgObject.DrawLayer);
                        if (context.IncludeRuntime)
                        {
                            SvgLink.SetKey(_drawGroup, SvgObject.DrawLayer);
                        }

                        currentGroup.Children.Add(_drawGroup);
                        context.Push(_drawGroup);
                    }
                }
                else
                {
                    _drawGroup = new DrawingGroup();
                    currentGroup.Children.Add(_drawGroup);
                    context.Push(_drawGroup);
                }
            }
            else
            {
                _drawGroup = new DrawingGroup();
                DrawingGroup currentGroup = context.Peek();

                if (currentGroup == null)
                {
                    throw new InvalidOperationException("An existing group is expected.");
                }

                currentGroup.Children.Add(_drawGroup);
                context.Push(_drawGroup);
            }

            SvgSvgElement svgElm = (SvgSvgElement)_svgElement;

            double x      = Math.Round(svgElm.X.AnimVal.Value, 4);
            double y      = Math.Round(svgElm.Y.AnimVal.Value, 4);
            double width  = Math.Round(svgElm.Width.AnimVal.Value, 4);
            double height = Math.Round(svgElm.Height.AnimVal.Value, 4);

            if (width < 0 || height < 0)
            {
                // For invalid dimension, prevent the drawing of the children...
                _isRecursive = true;
                return;
            }

            Rect elmRect = new Rect(x, y, width, height);

            XmlNode parentNode = _svgElement.ParentNode;

            ISvgFitToViewBox fitToView = svgElm as ISvgFitToViewBox;
            ISvgAnimatedPreserveAspectRatio preserveAspectRatio = null;

            if (fitToView != null && fitToView.PreserveAspectRatio != null)
            {
                preserveAspectRatio = fitToView.PreserveAspectRatio;
                ISvgAnimatedRect animRect = fitToView.ViewBox;
                if (animRect != null)
                {
                    ISvgRect viewRect = animRect.AnimVal;
                    if (viewRect != null)
                    {
                        Rect wpfViewRect = WpfConvert.ToRect(viewRect);
                        if (!wpfViewRect.IsEmpty && wpfViewRect.Width > 0 && wpfViewRect.Height > 0)
                        {
                            elmRect = wpfViewRect;
                        }
                    }
                }
            }

            Transform transform   = null;
            var       aspectRatio = (preserveAspectRatio != null) ? preserveAspectRatio.AnimVal : null;

            if (parentNode.NodeType != XmlNodeType.Document ||
                (aspectRatio != null && aspectRatio.Align == SvgPreserveAspectRatioType.None))
            {
                FitToViewbox(context, elmRect);

                transform = this.Transform;
                if (transform != null)
                {
                    _drawGroup.Transform = transform;
                }
            }

            if (!elmRect.IsEmpty && !elmRect.Width.Equals(0) && !elmRect.Height.Equals(0))
            {
                // Elements such as "pattern" are also rendered by this renderer, so we make sure we are
                // dealing with the root SVG element...
                if (parentNode != null && parentNode.NodeType == XmlNodeType.Document)
                {
                    _drawGroup.ClipGeometry = new RectangleGeometry(elmRect);
                }
                else
                {
                    if (transform != null)
                    {
                        // We have already applied the transform, which will translate to the start point...
                        if (transform is TranslateTransform)
                        {
                            //_drawGroup.ClipGeometry = new RectangleGeometry(
                            //    new Rect(0, 0, elmRect.Width, elmRect.Height));
                        }
                        else
                        {
                            _drawGroup.ClipGeometry = new RectangleGeometry(elmRect);
                        }
                    }
                    else
                    {
                        _drawGroup.ClipGeometry = new RectangleGeometry(elmRect);
                    }
                }
            }
        }
Beispiel #2
0
        public override void BeforeRender(WpfDrawingRenderer renderer)
        {
            base.BeforeRender(renderer);

            _idElement = string.Empty;

            WpfDrawingContext context = renderer.Context;

            DrawingGroup currentGroup = context.Peek();

            if (currentGroup == null)
            {
                throw new InvalidOperationException("An existing group is expected.");
            }

            if (currentGroup == context.Root)
            {
                if (context.IsFragment)
                {
                    // Do not add extra layer to fragments...
                    _drawGroup = currentGroup;
                }
                else
                {
                    _drawGroup = new DrawingGroup();
                    SvgObject.SetName(_drawGroup, SvgObject.DrawLayer);
                    if (context.IncludeRuntime)
                    {
                        SvgLink.SetKey(_drawGroup, SvgObject.DrawLayer);
                    }

                    currentGroup.Children.Add(_drawGroup);
                    context.Push(_drawGroup);
                }
            }
            else
            {
                _drawGroup = new DrawingGroup();
                currentGroup.Children.Add(_drawGroup);
                context.Push(_drawGroup);
            }

            SvgPatternElement svgElm = (SvgPatternElement)_svgElement;

            _idElement = svgElm.Id;
            if (!string.IsNullOrWhiteSpace(_idElement))
            {
                context.AddUrl(_idElement);
            }

            double x      = Math.Round(svgElm.X.AnimVal.Value, 4);
            double y      = Math.Round(svgElm.Y.AnimVal.Value, 4);
            double width  = Math.Round(svgElm.Width.AnimVal.Value, 4);
            double height = Math.Round(svgElm.Height.AnimVal.Value, 4);

            if (width < 0 || height < 0)
            {
                // For invalid dimension, prevent the drawing of the children...
                _isRecursive = true;
                return;
            }

            Rect elmRect = new Rect(x, y, width, height);

//            XmlNode parentNode = _svgElement.ParentNode;

            ISvgFitToViewBox fitToView = svgElm as ISvgFitToViewBox;
            ISvgAnimatedPreserveAspectRatio preserveAspectRatio = null;

            if (fitToView != null && fitToView.PreserveAspectRatio != null)
            {
                preserveAspectRatio = fitToView.PreserveAspectRatio;
                ISvgAnimatedRect animRect = fitToView.ViewBox;
                if (animRect != null)
                {
                    ISvgRect viewRect = animRect.AnimVal;
                    if (viewRect != null)
                    {
                        Rect wpfViewRect = WpfConvert.ToRect(viewRect);
                        if (!wpfViewRect.IsEmpty && wpfViewRect.Width > 0 && wpfViewRect.Height > 0)
                        {
                            elmRect = wpfViewRect;
                        }
                    }
                }
            }

            Transform transform   = null;
            var       aspectRatio = (preserveAspectRatio != null) ? preserveAspectRatio.AnimVal : null;

            if (aspectRatio != null /* && aspectRatio.Align == SvgPreserveAspectRatioType.None*/)
            {
                FitToViewbox(context, elmRect);

                transform = this.Transform;
                if (transform != null)
                {
                    _drawGroup.Transform = transform;
                }
            }
        }
Beispiel #3
0
        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
        }
        public override void BeforeRender(WpfDrawingRenderer renderer)
        {
            base.BeforeRender(renderer);

            WpfDrawingContext context = renderer.Context;

            _drawGroup = new DrawingGroup();

            if (context.Count == 0)
            {
                context.Push(_drawGroup);
                context.Root = _drawGroup;
            }
            else if (context.Count == 1)
            {
                DrawingGroup currentGroup = context.Peek();

                if (currentGroup == null)
                {
                    throw new InvalidOperationException("An existing group is expected.");
                }
                if (currentGroup == context.Root && !context.IsFragment)
                {
                    _drawGroup.SetValue(FrameworkElement.NameProperty, SvgObject.DrawLayer);
                    if (context.IncludeRuntime)
                    {
                        SvgLink.SetKey(_drawGroup, SvgObject.DrawLayer);
                    }
                }

                currentGroup.Children.Add(_drawGroup);
                context.Push(_drawGroup);
            }
            else
            {
                DrawingGroup currentGroup = context.Peek();

                if (currentGroup == null)
                {
                    throw new InvalidOperationException("An existing group is expected.");
                }

                currentGroup.Children.Add(_drawGroup);
                context.Push(_drawGroup);
            }

            SvgSvgElement svgElm = (SvgSvgElement)_svgElement;

            double x      = Math.Round(svgElm.X.AnimVal.Value, 4);
            double y      = Math.Round(svgElm.Y.AnimVal.Value, 4);
            double width  = Math.Round(svgElm.Width.AnimVal.Value, 4);
            double height = Math.Round(svgElm.Height.AnimVal.Value, 4);

            Rect elmRect = new Rect(x, y, width, height);

            //if (element.ParentNode is SvgElement)
            //{
            //    // TODO: should it be moved with x and y?
            //}

            XmlNode parentNode = _svgElement.ParentNode;

            //if (parentNode.NodeType == XmlNodeType.Document)
            {
                ISvgFitToViewBox fitToView = svgElm as ISvgFitToViewBox;
                if (fitToView != null)
                {
                    ISvgAnimatedRect animRect = fitToView.ViewBox;
                    if (animRect != null)
                    {
                        ISvgRect viewRect = animRect.AnimVal;
                        if (viewRect != null)
                        {
                            Rect wpfViewRect = WpfConvert.ToRect(viewRect);
                            if (!wpfViewRect.IsEmpty && wpfViewRect.Width > 0 && wpfViewRect.Height > 0)
                            {
                                elmRect = wpfViewRect;
                            }
                        }
                    }
                }
            }

            Transform transform = null;

            if (parentNode.NodeType != XmlNodeType.Document)
            {
                FitToViewbox(context, elmRect);

                transform = this.Transform;
                if (transform != null)
                {
                    _drawGroup.Transform = transform;
                }
            }

            //if (height > 0 && width > 0)
            //{
            //    ClipGeometry = new RectangleGeometry(elmRect);
            //}
            //Geometry clipGeom = this.ClipGeometry;
            //if (clipGeom != null)
            //{
            //    _drawGroup.ClipGeometry = clipGeom;
            //}

            if (((float)elmRect.Width != 0 && (float)elmRect.Height != 0))
            {
                // Elements such as "pattern" are also rendered by this renderer, so we make sure we are
                // dealing with the root SVG element...
                if (parentNode != null && parentNode.NodeType == XmlNodeType.Document)
                {
                    _drawGroup.ClipGeometry = new RectangleGeometry(elmRect);
                }
                else
                {
                    if (transform != null)
                    {
                        // We have already applied the transform, which will translate to the start point...
                        if (transform is TranslateTransform)
                        {
                            _drawGroup.ClipGeometry = new RectangleGeometry(
                                new Rect(0, 0, elmRect.Width, elmRect.Height));
                        }
                        else
                        {
                            _drawGroup.ClipGeometry = new RectangleGeometry(elmRect);
                        }
                    }
                    else
                    {
                        _drawGroup.ClipGeometry = new RectangleGeometry(elmRect);
                    }
                }

                //DrawingGroup animationGroup = context.Links;
                //if (animationGroup != null)
                //{
                //    animationGroup.ClipGeometry = clipGeom;
                //}
            }
        }
Beispiel #5
0
        public override Brush GetBrush(Rect elementBounds, WpfDrawingContext context, Transform viewTransform)
        {
            Rect bounds = elementBounds;

            DrawingGroup image = this.GetImage(context, bounds);

            if (image == null || image.Bounds.Width.Equals(0) || image.Bounds.Height.Equals(0))
            {
                return(null);
            }

            bool isUserSpace = true;

            if (_renderedElement.PatternContentUnits.AnimVal.Equals((ushort)SvgUnitType.ObjectBoundingBox))
            {
                bounds      = new Rect(0, 0, 1, 1);
                isUserSpace = false;
            }
            Rect destRect = GetDestRect(bounds);

            // Check for validity of the brush...
            if (destRect.Width.Equals(0) || destRect.Height.Equals(0) || destRect.IsEmpty)
            {
                return(null);
            }

            // Apply a scale if needed
            if (isUserSpace && image.Transform != null)
            {
                ISvgFitToViewBox fitToView = _renderedElement as ISvgFitToViewBox;
                if (fitToView != null && fitToView.ViewBox != null)
                {
                    ISvgAnimatedRect animRect = fitToView.ViewBox;
                    ISvgRect         viewRect = animRect.AnimVal;
                    if (viewRect != null)
                    {
                        Rect wpfViewRect = WpfConvert.ToRect(viewRect);
                        if (!wpfViewRect.IsEmpty && wpfViewRect.Width > 0 && wpfViewRect.Height > 0)
                        {
                            var scaleX = elementBounds.Width > 0 ? destRect.Width / wpfViewRect.Width : 1;
                            var scaleY = elementBounds.Height > 0 ? destRect.Height / wpfViewRect.Height : 1;

                            if (!scaleX.Equals(1) || !scaleY.Equals(1))
                            {
                                var currentTransform = image.Transform as ScaleTransform;
                                if (currentTransform != null)
                                {
                                    image.Transform = new ScaleTransform(scaleX, scaleY);
                                }
                            }
                        }
                    }
                }
            }

            DrawingBrush tb = new DrawingBrush(image);

            tb.Viewbox  = destRect;
            tb.Viewport = destRect;
            //tb.Viewbox = new Rect(0, 0, destRect.Width, destRect.Height);
            //tb.Viewport = new Rect(0, 0, bounds.Width, bounds.Height);
            tb.ViewboxUnits  = BrushMappingMode.Absolute;
            tb.ViewportUnits = isUserSpace ? BrushMappingMode.Absolute : BrushMappingMode.RelativeToBoundingBox;
            tb.TileMode      = TileMode.Tile;
//            tb.Stretch       = isUserSpace ? Stretch.Fill : Stretch.Uniform;

            if (isUserSpace)
            {
                MatrixTransform transform = GetTransformMatrix(image.Bounds, isUserSpace);
                if (transform != null && !transform.Matrix.IsIdentity)
                {
                    tb.Transform = transform;
                }
            }
            else
            {
                MatrixTransform transform = GetTransformMatrix(bounds, isUserSpace);
                if (transform != null && !transform.Matrix.IsIdentity)
                {
                    tb.RelativeTransform = transform;
                }
            }

            return(tb);
        }