Beispiel #1
0
        public FragmentDrawable(SvgFragment svgFragment, SKRect skOwnerBounds, Drawable?root, Drawable?parent, Attributes ignoreAttributes = Attributes.None)
            : base(svgFragment, root, parent)
        {
            IgnoreAttributes = ignoreAttributes;
            IsDrawable       = HasFeatures(svgFragment, IgnoreAttributes);

            if (!IsDrawable)
            {
                return;
            }

            var svgFragmentParent = svgFragment.Parent;

            float x = svgFragmentParent == null ? 0f : svgFragment.X.ToDeviceValue(UnitRenderingType.Horizontal, svgFragment, skOwnerBounds);
            float y = svgFragmentParent == null ? 0f : svgFragment.Y.ToDeviceValue(UnitRenderingType.Vertical, svgFragment, skOwnerBounds);

            var skSize = SvgExtensions.GetDimensions(svgFragment);

            if (skOwnerBounds.IsEmpty)
            {
                skOwnerBounds = SKRect.Create(x, y, skSize.Width, skSize.Height);
            }

            CreateChildren(svgFragment, skOwnerBounds, this, this, ignoreAttributes);

            IsAntialias = SvgPaintingExtensions.IsAntialias(svgFragment);

            TransformedBounds = skOwnerBounds;

            CreateTransformedBounds();

            Transform = SvgTransformsExtensions.ToSKMatrix(svgFragment.Transforms);
            var skMatrixViewBox = SvgTransformsExtensions.ToSKMatrix(svgFragment.ViewBox, svgFragment.AspectRatio, x, y, skSize.Width, skSize.Height);

            SKMatrix.PreConcat(ref Transform, ref skMatrixViewBox);

            switch (svgFragment.Overflow)
            {
            case SvgOverflow.Auto:
            case SvgOverflow.Visible:
            case SvgOverflow.Inherit:
                break;

            default:
                if (skSize.IsEmpty)
                {
                    Overflow = SKRect.Create(
                        x,
                        y,
                        Math.Abs(TransformedBounds.Left) + TransformedBounds.Width,
                        Math.Abs(TransformedBounds.Top) + TransformedBounds.Height);
                }
                else
                {
                    Overflow = SKRect.Create(x, y, skSize.Width, skSize.Height);
                }
                break;
            }

            var clipPathUris = new HashSet <Uri>();
            var svgClipPath  = svgFragment.GetUriElementReference <SvgClipPath>("clip-path", clipPathUris);

            if (svgClipPath != null && svgClipPath.Children != null)
            {
                ClipPath = IgnoreAttributes.HasFlag(Attributes.ClipPath) ? null : SvgClippingExtensions.GetClipPath(svgClipPath, TransformedBounds, clipPathUris, _disposable);
            }
            else
            {
                ClipPath = null;
            }

            Fill   = null;
            Stroke = null;

            // TODO: Transform _skBounds using _skMatrix.
            SKMatrix.MapRect(ref Transform, out TransformedBounds, ref TransformedBounds);
        }
        public static FragmentDrawable Create(SvgFragment svgFragment, Rect skOwnerBounds, DrawableBase?parent, IAssetLoader assetLoader, Attributes ignoreAttributes = Attributes.None)
        {
            var drawable = new FragmentDrawable(assetLoader)
            {
                Element          = svgFragment,
                Parent           = parent,
                IgnoreAttributes = ignoreAttributes
            };

            drawable.IsDrawable = drawable.HasFeatures(svgFragment, drawable.IgnoreAttributes);

            if (!drawable.IsDrawable)
            {
                return(drawable);
            }

            var svgFragmentParent = svgFragment.Parent;

            var x = svgFragmentParent is null ? 0f : svgFragment.X.ToDeviceValue(UnitRenderingType.Horizontal, svgFragment, skOwnerBounds);
            var y = svgFragmentParent is null ? 0f : svgFragment.Y.ToDeviceValue(UnitRenderingType.Vertical, svgFragment, skOwnerBounds);

            var skSize = SvgModelExtensions.GetDimensions(svgFragment);

            if (skOwnerBounds.IsEmpty)
            {
                skOwnerBounds = Rect.Create(x, y, skSize.Width, skSize.Height);
            }

            drawable.CreateChildren(svgFragment, skOwnerBounds, drawable, assetLoader, ignoreAttributes);

            drawable.IsAntialias = SvgModelExtensions.IsAntialias(svgFragment);

            drawable.TransformedBounds = skOwnerBounds;

            drawable.CreateTransformedBounds();

            drawable.Transform = SvgModelExtensions.ToMatrix(svgFragment.Transforms);
            var skMatrixViewBox = SvgModelExtensions.ToMatrix(svgFragment.ViewBox, svgFragment.AspectRatio, x, y, skSize.Width, skSize.Height);

            drawable.Transform = drawable.Transform.PreConcat(skMatrixViewBox);

            switch (svgFragment.Overflow)
            {
            case SvgOverflow.Auto:
            case SvgOverflow.Visible:
            case SvgOverflow.Inherit:
                break;

            default:
                if (skSize.IsEmpty)
                {
                    drawable.Overflow = Rect.Create(
                        x,
                        y,
                        Math.Abs(drawable.TransformedBounds.Left) + drawable.TransformedBounds.Width,
                        Math.Abs(drawable.TransformedBounds.Top) + drawable.TransformedBounds.Height);
                }
                else
                {
                    drawable.Overflow = Rect.Create(x, y, skSize.Width, skSize.Height);
                }
                break;
            }

            var clipPathUris = new HashSet <Uri>();
            var svgClipPath  = svgFragment.GetUriElementReference <SvgClipPath>("clip-path", clipPathUris);

            if (svgClipPath?.Children is { })