Beispiel #1
0
        /// <summary>
        /// Gets the attribute with the specified name and inherits from ancestors if there is no attribute set.
        /// </summary>
        /// <typeparam name="TAttributeType">The type of the attribute value.</typeparam>
        /// <param name="attributeName">A <see cref="string"/> containing the name of the attribute.</param>
        /// <param name="defaultValue">The value to return if a value hasn't already been specified.</param>
        /// <returns>The attribute value if available; otherwise the ancestors value for the same attribute; otherwise the default value of <typeparamref name="TAttributeType"/>.</returns>
        public TAttributeType GetInheritedAttribute <TAttributeType>(string attributeName, TAttributeType defaultValue = default(TAttributeType))
        {
            if (ContainsKey(attributeName) && !IsInheritValue(base[attributeName]))
            {
                var result = (TAttributeType) base[attributeName];

                var deferred = result as SvgDeferredPaintServer;
                if (deferred == null)
                {
                    return(result);
                }
                else
                {
                    var server = SvgDeferredPaintServer.TryGet <SvgPaintServer>(deferred, _owner);
                    if (server != SvgPaintServer.Inherit)
                    {
                        return(result);
                    }
                }
            }

            var parentAttribute = _owner.Parent?.Attributes[attributeName];

            return(parentAttribute != null ? (TAttributeType)parentAttribute : defaultValue);
        }
Beispiel #2
0
        protected void LoadStops(SvgVisualElement parent)
        {
            var core = SvgDeferredPaintServer.TryGet <SvgGradientServer>(InheritGradient, parent);

            if (Stops.Count == 0 && core != null)
            {
                Stops.AddRange(core.Stops);
            }
        }
Beispiel #3
0
        public Color GetColor(SvgElement parent)
        {
            var core = SvgDeferredPaintServer.TryGet <SvgColourServer>(this.StopColor, parent);

            if (core == null)
            {
                throw new InvalidOperationException("Invalid paint server for gradient stop detected.");
            }
            return(core.Colour);
        }
Beispiel #4
0
        private void LoadStops(SvgVisualElement parent)
        {
            var gradient = this;

            while (gradient?.Stops.Count == 0)
            {
                gradient = SvgDeferredPaintServer.TryGet <SvgGradientServer>(gradient.InheritGradient, parent);
            }

            if (gradient != null)
            {
                Stops.AddRange(gradient.Stops);
            }
        }
        /// <summary>
        /// Gets the attribute with the specified name and inherits from ancestors if there is no attribute set.
        /// </summary>
        /// <typeparam name="TAttributeType">The type of the attribute value.</typeparam>
        /// <param name="attributeName">A <see cref="string"/> containing the name of the attribute.</param>
        /// <param name="inherited">Used only if the attribute value is not available. If set to true, the inherited value is returned in this case, otherwise the default value.</param>
        /// <param name="defaultValue">The value to return if a value hasn't already been specified.</param>
        /// <returns>The attribute value if available and not set to "inherit"; the ancestors value for the same attribute if it exists and if either the attribute value is set to "inherit", or <paramref name="inherited"/> is true; the default value otherwise.</returns>
        public TAttributeType GetInheritedAttribute <TAttributeType>(string attributeName, bool inherited, TAttributeType defaultValue = default(TAttributeType))
        {
            var inherit = false;

            if (ContainsKey(attributeName))
            {
                var result = (TAttributeType) base[attributeName];

                if (IsInheritValue(result))
                {
                    inherit = true;
                }
                else
                {
                    var deferred = result as SvgDeferredPaintServer;
                    if (deferred == null)
                    {
                        return(result);
                    }
                    else
                    {
                        var server = SvgDeferredPaintServer.TryGet <SvgPaintServer>(deferred, _owner);
                        if (server == SvgPaintServer.Inherit)
                        {
                            inherit = true;
                        }
                        else
                        {
                            return(result);
                        }
                    }
                }
            }

            if (inherited || inherit)
            {
                var parentAttribute = _owner.Parent?.Attributes.GetInheritedAttribute <object>(attributeName, inherited);
                if (parentAttribute != null)
                {
                    return((TAttributeType)parentAttribute);
                }
            }

            return(defaultValue);
        }
Beispiel #6
0
        /// <summary>
        /// Gets a <see cref="Brush"/> representing the current paint server.
        /// </summary>
        /// <param name="renderingElement">The owner <see cref="SvgVisualElement"/>.</param>
        /// <param name="renderer">The renderer object.</param>
        /// <param name="opacity">The opacity of the brush.</param>
        /// <param name="forStroke">Not used.</param>
        public override Brush GetBrush(SvgVisualElement renderingElement, ISvgRenderer renderer, float opacity, bool forStroke = false)
        {
            var chain = new List <SvgPatternServer>();

            var curr = this;

            do
            {
                chain.Add(curr);
                curr = SvgDeferredPaintServer.TryGet <SvgPatternServer>(curr.InheritGradient, renderingElement);
            } while (curr != null);

            var firstChildren = chain.Where(p => p.Children.Count > 0).FirstOrDefault();

            if (firstChildren == null)
            {
                return(null);
            }
            var firstX      = chain.Where(p => p.X != null && p.X != SvgUnit.None).FirstOrDefault();
            var firstY      = chain.Where(p => p.Y != null && p.Y != SvgUnit.None).FirstOrDefault();
            var firstWidth  = chain.Where(p => p.Width != null && p.Width != SvgUnit.None).FirstOrDefault();
            var firstHeight = chain.Where(p => p.Height != null && p.Height != SvgUnit.None).FirstOrDefault();

            if (firstWidth == null || firstHeight == null)
            {
                return(null);
            }
            var firstPatternUnit        = chain.Where(p => p.PatternUnits != SvgCoordinateUnits.Inherit).FirstOrDefault();
            var firstPatternContentUnit = chain.Where(p => p.PatternContentUnits != SvgCoordinateUnits.Inherit).FirstOrDefault();
            var firstViewBox            = chain.Where(p => p.ViewBox != null && p.ViewBox != SvgViewBox.Empty).FirstOrDefault();

            var xUnit      = firstX == null ? new SvgUnit(0f) : firstX.X;
            var yUnit      = firstY == null ? new SvgUnit(0f) : firstY.Y;
            var widthUnit  = firstWidth.Width;
            var heightUnit = firstHeight.Height;

            var patternUnits        = firstPatternUnit == null ? SvgCoordinateUnits.ObjectBoundingBox : firstPatternUnit.PatternUnits;
            var patternContentUnits = firstPatternContentUnit == null ? SvgCoordinateUnits.UserSpaceOnUse : firstPatternContentUnit.PatternContentUnits;
            var viewBox             = firstViewBox == null ? SvgViewBox.Empty : firstViewBox.ViewBox;

            var isPatternObjectBoundingBox = patternUnits == SvgCoordinateUnits.ObjectBoundingBox;

            try
            {
                if (isPatternObjectBoundingBox)
                {
                    renderer.SetBoundable(renderingElement);
                }

                var x      = xUnit.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this);
                var y      = yUnit.ToDeviceValue(renderer, UnitRenderingType.Vertical, this);
                var width  = widthUnit.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this);
                var height = heightUnit.ToDeviceValue(renderer, UnitRenderingType.Vertical, this);

                if (isPatternObjectBoundingBox)
                {
                    var bounds = renderer.GetBoundable().Bounds;    // Boundary without stroke is expect...

                    if (xUnit.Type != SvgUnitType.Percentage)
                    {
                        x *= bounds.Width;
                    }
                    if (yUnit.Type != SvgUnitType.Percentage)
                    {
                        y *= bounds.Height;
                    }
                    if (widthUnit.Type != SvgUnitType.Percentage)
                    {
                        width *= bounds.Width;
                    }
                    if (heightUnit.Type != SvgUnitType.Percentage)
                    {
                        height *= bounds.Height;
                    }
                    x += bounds.X;
                    y += bounds.Y;
                }

                var tile = new Bitmap((int)Math.Ceiling(width), (int)Math.Ceiling(height));
                using (var tileRenderer = SvgRenderer.FromImage(tile))
                {
                    tileRenderer.SetBoundable(renderingElement);
                    if (viewBox != SvgViewBox.Empty)
                    {
                        var bounds = tileRenderer.GetBoundable().Bounds;
                        tileRenderer.ScaleTransform(width / viewBox.Width, height / viewBox.Height);
                    }
                    else if (patternContentUnits == SvgCoordinateUnits.ObjectBoundingBox)
                    {
                        var bounds = tileRenderer.GetBoundable().Bounds;
                        tileRenderer.ScaleTransform(bounds.Width, bounds.Height);
                    }

                    foreach (var child in firstChildren.Children)
                    {
                        child.RenderElement(tileRenderer);
                    }
                }

                using (var transform = EffectivePatternTransform)
                {
                    var textureBrush = new TextureBrush(tile, new RectangleF(0f, 0f, width, height))
                    {
                        Transform = transform
                    };
                    textureBrush.TranslateTransform(x, y);
                    return(textureBrush);
                }
            }
            finally
            {
                if (isPatternObjectBoundingBox)
                {
                    renderer.PopBoundable();
                }
            }
        }
Beispiel #7
0
        /// <summary>
        /// Gets a <see cref="Brush"/> representing the current paint server.
        /// </summary>
        /// <param name="renderingElement">The owner <see cref="SvgVisualElement"/>.</param>
        /// <param name="opacity">The opacity of the brush.</param>
        public override Brush GetBrush(SvgVisualElement renderingElement, ISvgRenderer renderer, float opacity, bool forStroke = false)
        {
            var chain = new List <SvgPatternServer>();
            var curr  = this;

            while (curr != null)
            {
                chain.Add(curr);
                curr = SvgDeferredPaintServer.TryGet <SvgPatternServer>(curr._inheritGradient, renderingElement);
            }

            var childElem = chain.Where((p) => p.Children != null && p.Children.Count > 0).FirstOrDefault();

            if (childElem == null)
            {
                return(null);
            }
            var widthElem  = chain.Where((p) => p.Width != null && p.Width != SvgUnit.None).FirstOrDefault();
            var heightElem = chain.Where((p) => p.Height != null && p.Height != SvgUnit.None).FirstOrDefault();

            if (widthElem == null && heightElem == null)
            {
                return(null);
            }

            var viewBoxElem = chain.Where((p) => p.ViewBox != null && p.ViewBox != SvgViewBox.Empty).FirstOrDefault();
            var viewBox     = viewBoxElem == null ? SvgViewBox.Empty : viewBoxElem.ViewBox;
            var xElem       = chain.Where((p) => p.X != null && p.X != SvgUnit.None).FirstOrDefault();
            var yElem       = chain.Where((p) => p.Y != null && p.Y != SvgUnit.None).FirstOrDefault();
            var xUnit       = xElem == null ? SvgUnit.Empty : xElem.X;
            var yUnit       = yElem == null ? SvgUnit.Empty : yElem.Y;

            var patternUnitElem        = chain.Where((p) => p.PatternUnits != SvgCoordinateUnits.Inherit).FirstOrDefault();
            var patternUnits           = (patternUnitElem == null ? SvgCoordinateUnits.ObjectBoundingBox : patternUnitElem.PatternUnits);
            var patternContentUnitElem = chain.Where((p) => p.PatternContentUnits != SvgCoordinateUnits.Inherit).FirstOrDefault();
            var patternContentUnits    = (patternContentUnitElem == null ? SvgCoordinateUnits.UserSpaceOnUse : patternContentUnitElem.PatternContentUnits);

            try
            {
                if (patternUnits == SvgCoordinateUnits.ObjectBoundingBox)
                {
                    renderer.SetBoundable(renderingElement);
                }

                using (var patternMatrix = new Matrix())
                {
                    var bounds = renderer.GetBoundable().Bounds;
                    var xScale = (patternUnits == SvgCoordinateUnits.ObjectBoundingBox ? bounds.Width : 1);
                    var yScale = (patternUnits == SvgCoordinateUnits.ObjectBoundingBox ? bounds.Height : 1);

                    float x = xScale * NormalizeUnit(xUnit).ToDeviceValue(renderer, UnitRenderingType.Horizontal, this);
                    float y = yScale * NormalizeUnit(yUnit).ToDeviceValue(renderer, UnitRenderingType.Vertical, this);

                    float width  = xScale * NormalizeUnit(widthElem.Width).ToDeviceValue(renderer, UnitRenderingType.Horizontal, this);
                    float height = yScale * NormalizeUnit(heightElem.Height).ToDeviceValue(renderer, UnitRenderingType.Vertical, this);

                    // Apply a scale if needed
                    patternMatrix.Scale((patternContentUnits == SvgCoordinateUnits.ObjectBoundingBox ? bounds.Width : 1) *
                                        (viewBox.Width > 0 ? width / viewBox.Width : 1),
                                        (patternContentUnits == SvgCoordinateUnits.ObjectBoundingBox ? bounds.Height : 1) *
                                        (viewBox.Height > 0 ? height / viewBox.Height : 1), MatrixOrder.Prepend);

                    Bitmap image = new Bitmap((int)width, (int)height);
                    using (var iRenderer = SvgRenderer.FromImage(image))
                    {
                        iRenderer.SetBoundable((_patternContentUnits == SvgCoordinateUnits.ObjectBoundingBox) ? new GenericBoundable(0, 0, width, height) : renderer.GetBoundable());
                        iRenderer.Transform     = patternMatrix;
                        iRenderer.SmoothingMode = SmoothingMode.AntiAlias;
                        iRenderer.SetClip(new Region(new RectangleF(0, 0,
                                                                    viewBox.Width > 0 ? viewBox.Width : width,
                                                                    viewBox.Height > 0 ? viewBox.Height : height)));

                        foreach (SvgElement child in childElem.Children)
                        {
                            child.RenderElement(iRenderer);
                        }
                    }

                    TextureBrush textureBrush   = new TextureBrush(image);
                    var          brushTransform = EffectivePatternTransform.Clone();
                    brushTransform.Translate(x, y, MatrixOrder.Append);
                    textureBrush.Transform = brushTransform;
                    return(textureBrush);
                }
            }
            finally
            {
                if (this.PatternUnits == SvgCoordinateUnits.ObjectBoundingBox)
                {
                    renderer.PopBoundable();
                }
            }
        }