Exemple #1
0
        internal SKPicture Load(SvgFragment svgFragment)
        {
            var skSize   = SkiaUtil.GetDimensions(svgFragment);
            var cullRect = SKRect.Create(skSize);

            using (var skPictureRecorder = new SKPictureRecorder())
                using (var skCanvas = skPictureRecorder.BeginRecording(cullRect))
                    using (var renderer = new SKSvgRenderer(skCanvas, skSize))
                    {
                        renderer.DrawFragment(svgFragment, false);
                        return(skPictureRecorder.EndRecording());
                    }
        }
Exemple #2
0
        // TODO:
        //public void DrawAnchor(SvgAnchor svgAnchor, bool ignoreDisplay)
        //{
        //    _skCanvas.Save();
        //
        //    var skMatrix = SkiaUtil.GetSKMatrix(svgAnchor.Transforms);
        //    SetTransform(skMatrix);
        //
        //    var skPaintOpacity = SetOpacity(svgAnchor, _disposable);
        //
        //    foreach (var svgElement in svgAnchor.Children)
        //    {
        //        Draw(svgElement, ignoreDisplay);
        //    }
        //
        //    if (skPaintOpacity != null)
        //    {
        //        _skCanvas.Restore();
        //    }
        //
        //    _skCanvas.Restore();
        //}

        public void DrawFragment(SvgFragment svgFragment, bool ignoreDisplay)
        {
            float x      = svgFragment.X.ToDeviceValue(null, UnitRenderingType.Horizontal, svgFragment);
            float y      = svgFragment.Y.ToDeviceValue(null, UnitRenderingType.Vertical, svgFragment);
            var   skSize = SkiaUtil.GetDimensions(svgFragment);

            _skCanvas.Save();

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

            default:
                var skClipRect = SKRect.Create(x, y, skSize.Width, skSize.Height);
                _skCanvas.ClipRect(skClipRect, SKClipOperation.Intersect);
                break;
            }

            var skMatrixViewBox = SkiaUtil.GetSvgViewBoxTransform(svgFragment.ViewBox, svgFragment.AspectRatio, x, y, skSize.Width, skSize.Height);
            var skMatrix        = SkiaUtil.GetSKMatrix(svgFragment.Transforms);

            SKMatrix.PreConcat(ref skMatrix, ref skMatrixViewBox);
            SetTransform(skMatrix);

            var skPaintOpacity = SetOpacity(svgFragment, _disposable);

            foreach (var svgElement in svgFragment.Children)
            {
                Draw(svgElement, ignoreDisplay);
            }

            if (skPaintOpacity != null)
            {
                _skCanvas.Restore();
            }

            _skCanvas.Restore();
        }
Exemple #3
0
        public void DrawImage(SvgImage svgImage, bool ignoreDisplay)
        {
            if (!CanDraw(svgImage, ignoreDisplay))
            {
                return;
            }

            float width    = svgImage.Width.ToDeviceValue(null, UnitRenderingType.Horizontal, svgImage);
            float height   = svgImage.Height.ToDeviceValue(null, UnitRenderingType.Vertical, svgImage);
            var   location = svgImage.Location.ToDeviceValue(null, svgImage);

            if (width <= 0f || height <= 0f || svgImage.Href == null)
            {
                return;
            }

            var image       = SkiaUtil.GetImage(svgImage, svgImage.Href);
            var skImage     = image as SKImage;
            var svgFragment = image as SvgFragment;

            if (skImage == null && svgFragment == null)
            {
                return;
            }

            if (skImage != null)
            {
                _disposable.Add(skImage);
            }

            SKRect srcRect = default;

            if (skImage != null)
            {
                srcRect = SKRect.Create(0f, 0f, skImage.Width, skImage.Height);
            }

            if (svgFragment != null)
            {
                var skSize = SkiaUtil.GetDimensions(svgFragment);
                srcRect = SKRect.Create(0f, 0f, skSize.Width, skSize.Height);
            }

            var destClip = SKRect.Create(location.X, location.Y, width, height);
            var destRect = destClip;

            var aspectRatio = svgImage.AspectRatio;

            if (aspectRatio.Align != SvgPreserveAspectRatio.none)
            {
                var fScaleX = destClip.Width / srcRect.Width;
                var fScaleY = destClip.Height / srcRect.Height;
                var xOffset = 0f;
                var yOffset = 0f;

                if (aspectRatio.Slice)
                {
                    fScaleX = Math.Max(fScaleX, fScaleY);
                    fScaleY = Math.Max(fScaleX, fScaleY);
                }
                else
                {
                    fScaleX = Math.Min(fScaleX, fScaleY);
                    fScaleY = Math.Min(fScaleX, fScaleY);
                }

                switch (aspectRatio.Align)
                {
                case SvgPreserveAspectRatio.xMinYMin:
                    break;

                case SvgPreserveAspectRatio.xMidYMin:
                    xOffset = (destClip.Width - srcRect.Width * fScaleX) / 2;
                    break;

                case SvgPreserveAspectRatio.xMaxYMin:
                    xOffset = (destClip.Width - srcRect.Width * fScaleX);
                    break;

                case SvgPreserveAspectRatio.xMinYMid:
                    yOffset = (destClip.Height - srcRect.Height * fScaleY) / 2;
                    break;

                case SvgPreserveAspectRatio.xMidYMid:
                    xOffset = (destClip.Width - srcRect.Width * fScaleX) / 2;
                    yOffset = (destClip.Height - srcRect.Height * fScaleY) / 2;
                    break;

                case SvgPreserveAspectRatio.xMaxYMid:
                    xOffset = (destClip.Width - srcRect.Width * fScaleX);
                    yOffset = (destClip.Height - srcRect.Height * fScaleY) / 2;
                    break;

                case SvgPreserveAspectRatio.xMinYMax:
                    yOffset = (destClip.Height - srcRect.Height * fScaleY);
                    break;

                case SvgPreserveAspectRatio.xMidYMax:
                    xOffset = (destClip.Width - srcRect.Width * fScaleX) / 2;
                    yOffset = (destClip.Height - srcRect.Height * fScaleY);
                    break;

                case SvgPreserveAspectRatio.xMaxYMax:
                    xOffset = (destClip.Width - srcRect.Width * fScaleX);
                    yOffset = (destClip.Height - srcRect.Height * fScaleY);
                    break;
                }

                destRect = SKRect.Create(
                    destClip.Left + xOffset, destClip.Top + yOffset,
                    srcRect.Width * fScaleX, srcRect.Height * fScaleY);
            }

            _skCanvas.Save();

            var skMatrix = SkiaUtil.GetSKMatrix(svgImage.Transforms);

            SetTransform(skMatrix);
            SetClipPath(svgImage, _disposable);

            var skPaintOpacity = SetOpacity(svgImage, _disposable);

            var skPaintFilter = SetFilter(svgImage, _disposable);

            _skCanvas.ClipRect(destClip, SKClipOperation.Intersect);

            SetClip(svgImage, destClip);

            if (skImage != null)
            {
                _skCanvas.DrawImage(skImage, srcRect, destRect);
            }

            if (svgFragment != null)
            {
                _skCanvas.Save();

                float dx = destRect.Left;
                float dy = destRect.Top;
                float sx = destRect.Width / srcRect.Width;
                float sy = destRect.Height / srcRect.Height;
                var   skTranslationMatrix = SKMatrix.MakeTranslation(dx, dy);
                var   skScaleMatrix       = SKMatrix.MakeScale(sx, sy);
                SKMatrix.PreConcat(ref skTranslationMatrix, ref skScaleMatrix);
                SetTransform(skTranslationMatrix);

                DrawFragment(svgFragment, ignoreDisplay);

                _skCanvas.Restore();
            }

            if (skPaintFilter != null)
            {
                _skCanvas.Restore();
            }

            if (skPaintOpacity != null)
            {
                _skCanvas.Restore();
            }

            _skCanvas.Restore();
        }