Skip to content

Instantly share code, notes, and snippets.

@robmikh
Created November 24, 2018 20:45
Show Gist options
  • Save robmikh/06c6813aefd80ac26443061be6b6590b to your computer and use it in GitHub Desktop.
Save robmikh/06c6813aefd80ac26443061be6b6590b to your computer and use it in GitHub Desktop.
CompositionSurfaceFactory SVG "plug-in" Concept
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;
}
}
@robmikh
Copy link
Author

robmikh commented Nov 24, 2018

I haven't tested this extensively. This is just a proof of concept I wrote while waiting for my flight.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment