예제 #1
0
        public static SKPicture?ToPicture(SvgFragment svgFragment)
        {
            var skSize   = SvgExtensions.GetDimensions(svgFragment);
            var skBounds = SKRect.Create(skSize);

            using var drawable = DrawableFactory.Create(svgFragment, skBounds, null, null, Attributes.None);
            if (drawable == null)
            {
                return(null);
            }

            drawable.PostProcess();

            if (skBounds.IsEmpty)
            {
                skBounds = GetBounds(drawable);
            }

            using var skPictureRecorder = new SKPictureRecorder();
            using var skCanvas          = skPictureRecorder.BeginRecording(skBounds);
#if USE_EXPERIMENTAL_LINEAR_RGB
            // TODO:
            using var skPaint       = new SKPaint();
            using var skColorFilter = SKColorFilter.CreateTable(null, SvgPaintingExtensions.s_LinearRGBtoSRGB, SvgPaintingExtensions.s_LinearRGBtoSRGB, SvgPaintingExtensions.s_LinearRGBtoSRGB);
            using var skImageFilter = SKImageFilter.CreateColorFilter(skColorFilter);
            skPaint.ImageFilter     = skImageFilter;
            skCanvas.SaveLayer(skPaint);
#endif
            drawable?.Draw(skCanvas, 0f, 0f);
#if USE_EXPERIMENTAL_LINEAR_RGB
            // TODO:
            skCanvas.Restore();
#endif
            return(skPictureRecorder.EndRecording());
        }
예제 #2
0
        public static void Draw(SKCanvas skCanvas, SvgFragment svgFragment)
        {
            var size     = SvgModelExtensions.GetDimensions(svgFragment);
            var bounds   = Rect.Create(size);
            var drawable = DrawableFactory.Create(svgFragment, bounds, null, _assetLoader);

            if (drawable is { })
예제 #3
0
        public static Drawable?ToDrawable(SvgElement svgElement, SKRect skBounds, Attributes ignoreAttributes = Attributes.None)
        {
            var drawable = DrawableFactory.Create(svgElement, skBounds, null, null, ignoreAttributes);

            drawable?.PostProcess();
            return(drawable);
        }
예제 #4
0
        public SwitchDrawable(SvgSwitch svgSwitch, SKRect skOwnerBounds, Drawable?root, Drawable?parent, Attributes ignoreAttributes = Attributes.None)
            : base(svgSwitch, root, parent)
        {
            IgnoreAttributes = ignoreAttributes;
            IsDrawable       = CanDraw(svgSwitch, IgnoreAttributes) && HasFeatures(svgSwitch, IgnoreAttributes);

            if (!IsDrawable)
            {
                return;
            }

            foreach (var child in svgSwitch.Children)
            {
                if (!IsKnownElement(child))
                {
                    continue;
                }

                bool hasRequiredFeatures   = HasRequiredFeatures(child);
                bool hasRequiredExtensions = HasRequiredExtensions(child);
                bool hasSystemLanguage     = HasSystemLanguage(child);

                if (hasRequiredFeatures && hasRequiredExtensions && hasSystemLanguage)
                {
                    //var ignoreAttributesSwitch = ignoreAttributes
                    //    | Attributes.Visibility
                    //    | Attributes.Display
                    //    | Attributes.RequiredFeatures
                    //    | Attributes.RequiredExtensions
                    //    | Attributes.SystemLanguage;

                    var drawable = DrawableFactory.Create(child, skOwnerBounds, root, parent, ignoreAttributes);
                    if (drawable != null)
                    {
                        FirstChild = drawable;
                        _disposable.Add(FirstChild);
                    }
                    break;
                }
            }

            if (FirstChild == null)
            {
                IsDrawable = false;
                return;
            }

            IsAntialias = SvgPaintingExtensions.IsAntialias(svgSwitch);

            TransformedBounds = FirstChild.TransformedBounds;

            Transform = SvgTransformsExtensions.ToSKMatrix(svgSwitch.Transforms);

            Fill   = null;
            Stroke = null;

            // TODO: Transform _skBounds using _skMatrix.
            TransformedBounds = Transform.MapRect(TransformedBounds);
        }
예제 #5
0
        public static void Draw(SKCanvas skCanvas, SvgFragment svgFragment)
        {
            var skSize   = SvgExtensions.GetDimensions(svgFragment);
            var skBounds = SKRect.Create(skSize);

            using var drawable = DrawableFactory.Create(svgFragment, skBounds, null, null, Attributes.None);
            drawable?.PostProcess();
            drawable?.Draw(skCanvas, 0f, 0f);
        }
예제 #6
0
        public static Drawable?ToDrawable(SvgFragment svgFragment)
        {
            var skSize   = SvgExtensions.GetDimensions(svgFragment);
            var skBounds = SKRect.Create(skSize);
            var drawable = DrawableFactory.Create(svgFragment, skBounds, null, null, Attributes.None);

            drawable?.PostProcess();
            return(drawable);
        }
예제 #7
0
        public static void Draw(SkiaSharp.SKCanvas skCanvas, SvgFragment svgFragment)
        {
            var references = new HashSet <Uri> {
                svgFragment.OwnerDocument.BaseUri
            };
            var size     = SvgExtensions.GetDimensions(svgFragment);
            var bounds   = SKRect.Create(size);
            var drawable = DrawableFactory.Create(svgFragment, bounds, null, s_assetLoader, references);

            if (drawable is { })
예제 #8
0
 protected virtual void CreateChildren(SvgElement svgElement, SKRect skOwnerBounds, Drawable?root, Drawable?parent, Attributes ignoreAttributes)
 {
     foreach (var child in svgElement.Children)
     {
         var drawable = DrawableFactory.Create(child, skOwnerBounds, root, parent, ignoreAttributes);
         if (drawable != null)
         {
             ChildrenDrawables.Add(drawable);
             _disposable.Add(drawable);
         }
     }
 }
예제 #9
0
        public static SKPicture?ToPicture(SvgFragment svgFragment, out Drawable?drawable)
        {
            var skSize   = SvgExtensions.GetDimensions(svgFragment);
            var skBounds = SKRect.Create(skSize);

            drawable = DrawableFactory.Create(svgFragment, skBounds, null, null, Attributes.None);
            if (drawable == null)
            {
                return(null);
            }

            drawable.PostProcess();

            if (skBounds.IsEmpty)
            {
                skBounds = GetBounds(drawable);
            }

            using var skPictureRecorder = new SKPictureRecorder();
            using var skCanvas          = skPictureRecorder.BeginRecording(skBounds);
            drawable?.Draw(skCanvas, 0f, 0f);
            return(skPictureRecorder.EndRecording());
        }
예제 #10
0
        public MarkerDrawable(SvgMarker svgMarker, SvgVisualElement pOwner, SKPoint pMarkerPoint, float fAngle, SKRect skOwnerBounds, Drawable?root, Drawable?parent, Attributes ignoreAttributes = Attributes.None)
            : base(svgMarker, root, parent)
        {
            IgnoreAttributes = Attributes.Display | ignoreAttributes;
            IsDrawable       = true;

            if (!IsDrawable)
            {
                return;
            }

            var markerElement = GetMarkerElement(svgMarker);

            if (markerElement == null)
            {
                IsDrawable = false;
                return;
            }

            var skMarkerMatrix = SKMatrix.MakeIdentity();

            var skMatrixMarkerPoint = SKMatrix.MakeTranslation(pMarkerPoint.X, pMarkerPoint.Y);

            skMarkerMatrix = skMarkerMatrix.PreConcat(skMatrixMarkerPoint);

            var skMatrixAngle = SKMatrix.MakeRotationDegrees(svgMarker.Orient.IsAuto ? fAngle : svgMarker.Orient.Angle);

            skMarkerMatrix = skMarkerMatrix.PreConcat(skMatrixAngle);

            var strokeWidth = pOwner.StrokeWidth.ToDeviceValue(UnitRenderingType.Other, svgMarker, skOwnerBounds);

            var   refX         = svgMarker.RefX.ToDeviceValue(UnitRenderingType.Horizontal, svgMarker, skOwnerBounds);
            var   refY         = svgMarker.RefY.ToDeviceValue(UnitRenderingType.Vertical, svgMarker, skOwnerBounds);
            float markerWidth  = svgMarker.MarkerWidth.ToDeviceValue(UnitRenderingType.Other, svgMarker, skOwnerBounds);
            float markerHeight = svgMarker.MarkerHeight.ToDeviceValue(UnitRenderingType.Other, svgMarker, skOwnerBounds);
            float viewBoxToMarkerUnitsScaleX = 1f;
            float viewBoxToMarkerUnitsScaleY = 1f;

            switch (svgMarker.MarkerUnits)
            {
            case SvgMarkerUnits.StrokeWidth:
            {
                var skMatrixStrokeWidth = SKMatrix.MakeScale(strokeWidth, strokeWidth);
                skMarkerMatrix = skMarkerMatrix.PreConcat(skMatrixStrokeWidth);

                var viewBoxWidth  = svgMarker.ViewBox.Width;
                var viewBoxHeight = svgMarker.ViewBox.Height;

                var scaleFactorWidth  = (viewBoxWidth <= 0) ? 1 : (markerWidth / viewBoxWidth);
                var scaleFactorHeight = (viewBoxHeight <= 0) ? 1 : (markerHeight / viewBoxHeight);

                viewBoxToMarkerUnitsScaleX = Math.Min(scaleFactorWidth, scaleFactorHeight);
                viewBoxToMarkerUnitsScaleY = Math.Min(scaleFactorWidth, scaleFactorHeight);

                var skMatrixTranslateRefXY = SKMatrix.MakeTranslation(-refX * viewBoxToMarkerUnitsScaleX, -refY * viewBoxToMarkerUnitsScaleY);
                skMarkerMatrix = skMarkerMatrix.PreConcat(skMatrixTranslateRefXY);

                var skMatrixScaleXY = SKMatrix.MakeScale(viewBoxToMarkerUnitsScaleX, viewBoxToMarkerUnitsScaleY);
                skMarkerMatrix = skMarkerMatrix.PreConcat(skMatrixScaleXY);
            }
            break;

            case SvgMarkerUnits.UserSpaceOnUse:
            {
                var skMatrixTranslateRefXY = SKMatrix.MakeTranslation(-refX, -refY);
                skMarkerMatrix = skMarkerMatrix.PreConcat(skMatrixTranslateRefXY);
            }
            break;
            }

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

            default:
                MarkerClipRect = SKRect.Create(
                    svgMarker.ViewBox.MinX,
                    svgMarker.ViewBox.MinY,
                    markerWidth / viewBoxToMarkerUnitsScaleX,
                    markerHeight / viewBoxToMarkerUnitsScaleY);
                break;
            }

            var drawable = DrawableFactory.Create(markerElement, skOwnerBounds, root, this, Attributes.Display);

            if (drawable != null)
            {
                MarkerElementDrawable = drawable;
                _disposable.Add(MarkerElementDrawable);
            }
            else
            {
                IsDrawable = false;
                return;
            }

            IsAntialias = SvgPaintingExtensions.IsAntialias(svgMarker);

            TransformedBounds = MarkerElementDrawable.TransformedBounds;

            Transform = SvgTransformsExtensions.ToSKMatrix(svgMarker.Transforms);
            Transform = Transform.PreConcat(skMarkerMatrix);

            Fill   = null;
            Stroke = null;

            // TODO: Transform _skBounds using _skMatrix.
            TransformedBounds = Transform.MapRect(TransformedBounds);
        }
예제 #11
0
        public UseDrawable(SvgUse svgUse, SKRect skOwnerBounds, Drawable?root, Drawable?parent, Attributes ignoreAttributes = Attributes.None)
            : base(svgUse, root, parent)
        {
            IgnoreAttributes = ignoreAttributes;
            IsDrawable       = CanDraw(svgUse, IgnoreAttributes) && HasFeatures(svgUse, IgnoreAttributes);

            if (!IsDrawable)
            {
                return;
            }

            if (SvgExtensions.HasRecursiveReference(svgUse, (e) => e.ReferencedElement, new HashSet <Uri>()))
            {
                IsDrawable = false;
                return;
            }

            var svgReferencedElement = SvgExtensions.GetReference <SvgElement>(svgUse, svgUse.ReferencedElement);

            if (svgReferencedElement == null)
            {
                IsDrawable = false;
                return;
            }

            float x      = svgUse.X.ToDeviceValue(UnitRenderingType.Horizontal, svgUse, skOwnerBounds);
            float y      = svgUse.Y.ToDeviceValue(UnitRenderingType.Vertical, svgUse, skOwnerBounds);
            float width  = svgUse.Width.ToDeviceValue(UnitRenderingType.Horizontal, svgUse, skOwnerBounds);
            float height = svgUse.Height.ToDeviceValue(UnitRenderingType.Vertical, svgUse, skOwnerBounds);

            if (width <= 0f)
            {
                width = new SvgUnit(SvgUnitType.Percentage, 100f).ToDeviceValue(UnitRenderingType.Horizontal, svgUse, skOwnerBounds);
            }

            if (height <= 0f)
            {
                height = new SvgUnit(SvgUnitType.Percentage, 100f).ToDeviceValue(UnitRenderingType.Vertical, svgUse, skOwnerBounds);
            }

            var originalReferencedElementParent = svgReferencedElement.Parent;
            var referencedElementParent         = default(FieldInfo);

            try
            {
                referencedElementParent = svgReferencedElement.GetType().GetField("_parent", BindingFlags.NonPublic | BindingFlags.Instance);
                if (referencedElementParent != null)
                {
                    referencedElementParent.SetValue(svgReferencedElement, svgUse);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
                Debug.WriteLine(ex.StackTrace);
            }

            svgReferencedElement.InvalidateChildPaths();

            if (svgReferencedElement is SvgSymbol svgSymbol)
            {
                ReferencedDrawable = new SymbolDrawable(svgSymbol, x, y, width, height, skOwnerBounds, root, this, ignoreAttributes);
                _disposable.Add(ReferencedDrawable);
            }
            else
            {
                var drawable = DrawableFactory.Create(svgReferencedElement, skOwnerBounds, root, this, ignoreAttributes);
                if (drawable != null)
                {
                    ReferencedDrawable = drawable;
                    _disposable.Add(ReferencedDrawable);
                }
                else
                {
                    IsDrawable = false;
                    return;
                }
            }

            IsAntialias = SvgPaintingExtensions.IsAntialias(svgUse);

            TransformedBounds = ReferencedDrawable.TransformedBounds;

            Transform = SvgTransformsExtensions.ToSKMatrix(svgUse.Transforms);
            if (!(svgReferencedElement is SvgSymbol))
            {
                var skMatrixTranslateXY = SKMatrix.MakeTranslation(x, y);
                Transform = Transform.PreConcat(skMatrixTranslateXY);
            }

            Fill   = null;
            Stroke = null;

            // TODO: Transform _skBounds using _skMatrix.
            TransformedBounds = Transform.MapRect(TransformedBounds);

            try
            {
                if (referencedElementParent != null)
                {
                    referencedElementParent.SetValue(svgReferencedElement, originalReferencedElementParent);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
                Debug.WriteLine(ex.StackTrace);
            }
        }