Created
November 24, 2018 20:45
-
-
Save robmikh/06c6813aefd80ac26443061be6b6590b to your computer and use it in GitHub Desktop.
CompositionSurfaceFactory SVG "plug-in" Concept
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.Graphics.Canvas; | |
using Microsoft.Graphics.Canvas.Svg; | |
using Microsoft.Graphics.Canvas.UI.Composition; | |
using Robmikh.CompositionSurfaceFactory; | |
using System; | |
using System.Threading.Tasks; | |
using Windows.Foundation; | |
using Windows.Graphics.DirectX; | |
using Windows.Storage; | |
using Windows.UI; | |
using Windows.UI.Composition; | |
namespace CSFSVGTest | |
{ | |
static class SurfaceFactoryExtensions | |
{ | |
public static async Task<SVGSurface> CreateSVGSurfaceFromLocalUriAsync(this SurfaceFactory surfaceFactory, Uri uri, Size size) | |
{ | |
var svgSurface = await SVGSurface.CreateFromLocalUriAsync(surfaceFactory, uri, size); | |
return svgSurface; | |
} | |
} | |
class SVGSurface | |
{ | |
public static async Task<SVGSurface> CreateFromLocalUriAsync(SurfaceFactory surfaceFactory, Uri uri, Size size) | |
{ | |
var svgSurface = new SVGSurface(surfaceFactory, uri, size); | |
await svgSurface.RedrawAsync(); | |
return svgSurface; | |
} | |
private static async Task<CanvasSvgDocument> LoadSvgDocumentAsync(CanvasDevice device, Uri uri) | |
{ | |
CanvasSvgDocument result = null; | |
var file = await StorageFile.GetFileFromApplicationUriAsync(uri); | |
using (var stream = await file.OpenReadAsync()) | |
{ | |
result = await CanvasSvgDocument.LoadAsync(device, stream); | |
} | |
return result; | |
} | |
public SurfaceFactory SurfaceFactory { get; } | |
public ICompositionSurface Surface => _surface; | |
private SVGSurface(SurfaceFactory surfaceFactory, Uri uri, Size size) | |
{ | |
SurfaceFactory = surfaceFactory; | |
_uri = uri; | |
_size = size; | |
_surface = SurfaceFactory.GraphicsDevice.CreateDrawingSurface( | |
new Size(1, 1), | |
DirectXPixelFormat.B8G8R8A8UIntNormalized, | |
DirectXAlphaMode.Premultiplied); | |
SurfaceFactory.DeviceReplaced += OnDeviceReplaced; | |
} | |
private void OnDeviceReplaced(object sender, RenderingDeviceReplacedEventArgs e) | |
{ | |
var ignored = RedrawAsync(); | |
} | |
private async Task RedrawAsync() | |
{ | |
var device = CanvasComposition.GetCanvasDevice(SurfaceFactory.GraphicsDevice); | |
var document = await LoadSvgDocumentAsync(device, _uri); | |
if (_surface.Size != _size) | |
{ | |
SurfaceFactory.ResizeSurface(_surface, _size); | |
} | |
using (var lockSession = SurfaceFactory.DrawingLock.GetLockSession()) | |
using (var drawingSession = CanvasComposition.CreateDrawingSession(_surface)) | |
{ | |
drawingSession.Clear(Colors.Transparent); | |
drawingSession.DrawSvg(document, _size); | |
} | |
} | |
public void Resize(Size size) | |
{ | |
_size = size; | |
var ignored = RedrawAsync(); | |
} | |
private Uri _uri; | |
private CompositionDrawingSurface _surface; | |
private Size _size; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I haven't tested this extensively. This is just a proof of concept I wrote while waiting for my flight.