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()); } }
// 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(); }
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(); }