Skip to content

Commit

Permalink
feat(svg): [Wasm] Add support for ms-appdata
Browse files Browse the repository at this point in the history
  • Loading branch information
jeromelaban committed May 9, 2023
1 parent 69095eb commit 8dd1e30
Show file tree
Hide file tree
Showing 5 changed files with 250 additions and 3 deletions.
7 changes: 6 additions & 1 deletion src/SamplesApp/UITests.Shared/UITests.Shared.projitems
Original file line number Diff line number Diff line change
Expand Up @@ -1594,6 +1594,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\ImageTests\SvgImageSource_FromMsAppData.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\ListView\ListView_Snap_Rubberband.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
Expand Down Expand Up @@ -5663,6 +5667,7 @@
<DependentUpon>Image_Source_Nullify.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\ListView\ListView_BringIntoView.xaml.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\ImageTests\SvgImageSource_FromMsAppData.xaml.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\ListView\ListView_Snap_Rubberband.xaml.cs">
<DependentUpon>ListView_Snap_Rubberband.xaml</DependentUpon>
</Compile>
Expand Down Expand Up @@ -9034,4 +9039,4 @@
<Content Include="$(MSBuildThisFileDirectory)Assets\libre-camera-panorama.svg" />
</ItemGroup>
<Import Project="ItemExclusions.props" />
</Project>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<Page x:Class="UITests.Windows_UI_Xaml_Controls.ImageTests.SvgImageSource_FromMsAppData"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UITests.Windows_UI_Xaml_Controls.ImageTests"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>

<StackPanel Spacing="4">
<ComboBox ItemsSource="{x:Bind Sources}" SelectedItem="{x:Bind SelectedSource, Mode=TwoWay}" Header="SVG image">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="local:SampleSvgSource">
<TextBlock Text="{x:Bind Name}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<ComboBox ItemsSource="{x:Bind Stretches}" SelectedItem="{x:Bind SelectedStretch, Mode=TwoWay}" Header="Stretch" />
<TextBox Text="{x:Bind ImageWidth, Mode=TwoWay}" Header="Image width" />
<TextBox Text="{x:Bind ImageHeight, Mode=TwoWay}" Header="Image height" />
<TextBox Text="{x:Bind RasterizedWidth, Mode=TwoWay}" Header="Rasterized width" />
<TextBox Text="{x:Bind RasterizedHeight, Mode=TwoWay}" Header="Rasterized height" />
</StackPanel>

<Grid Grid.Row="1">
<Border HorizontalAlignment="Center" VerticalAlignment="Center" BorderBrush="Black" BorderThickness="2">
<Image x:Name="ImageElement" />
</Border>
</Grid>
</Grid>
</Page>
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
#pragma warning disable CA1848 // Use LoggerMessage

using System;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.Extensions.Logging;
using Uno.Extensions;
using Uno.UI.Samples.Controls;
using Windows.Storage;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;

namespace UITests.Windows_UI_Xaml_Controls.ImageTests;

[Sample("Image")]
public sealed partial class SvgImageSource_FromMsAppData : Page
{
private SampleSvgSource _selectedSource;
private string _imageWidth = "100";
private string _rasterizedWidth = "";
private string _imageHeight = "100";
private string _rasterizedHeight = "";
private string _selectedStretch = "None";

public SvgImageSource_FromMsAppData()
{
this.InitializeComponent();

_selectedSource = Sources[0];
OnPropertyChanged();
}

public SampleSvgSource[] Sources { get; } = new SampleSvgSource[]
{
new("Temp", new Uri("ms-appx:///Assets/Formats/couch.svg")),
new("Local", new Uri("ms-appx:///Assets/Formats/czcalendar.svg")),
new("Roaming", new Uri("ms-appx:///Assets/Formats/heliocentric.svg"))
};

public string[] Stretches { get; } = Enum.GetNames(typeof(Stretch)).ToArray();

public SampleSvgSource SelectedSource
{
get => _selectedSource;
set
{
_selectedSource = value;
OnPropertyChanged();
}
}

public string SelectedStretch
{
get => _selectedStretch;
set
{
_selectedStretch = value;
OnPropertyChanged();
}
}

public string ImageWidth
{
get => _imageWidth;
set
{
_imageWidth = value;
OnPropertyChanged();
}
}

public string ImageHeight
{
get => _imageHeight;
set
{
_imageHeight = value;
OnPropertyChanged();
}
}

public string RasterizedWidth
{
get => _rasterizedWidth;
set
{
_rasterizedWidth = value;
OnPropertyChanged();
}
}

public string RasterizedHeight
{
get => _rasterizedHeight;
set
{
_rasterizedHeight = value;
OnPropertyChanged();
}
}

private async void OnPropertyChanged()
{
try
{
if (ImageElement.Source is not SvgImageSource svgImageSource)
{
svgImageSource = new SvgImageSource();
ImageElement.Source = svgImageSource;
}

if (SelectedSource != null)
{
var file = await StorageFile.GetFileFromApplicationUriAsync(SelectedSource.Uri);

var targetFolder = SelectedSource.Name switch {
"Local" => ApplicationData.Current.LocalFolder,
"Temp" => ApplicationData.Current.TemporaryFolder,
"Roaming" => ApplicationData.Current.RoamingFolder,
_ => throw new NotSupportedException("Unsupported ms-appx target")
};

await file.CopyAsync(targetFolder, file.Name, NameCollisionOption.ReplaceExisting);

svgImageSource.UriSource = new Uri($"ms-appdata:///local/{file.Name}");

var text = await FileIO.ReadTextAsync(file);
using MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(text));
await svgImageSource.SetSourceAsync(stream.AsRandomAccessStream());
}

if (Enum.TryParse(SelectedStretch, out Stretch stretch))
{
ImageElement.Stretch = stretch;
}

if (double.TryParse(ImageWidth, out var width))
{
ImageElement.Width = width;
}
else
{
ImageElement.Width = double.NaN;
}

if (double.TryParse(ImageHeight, out var height))
{
ImageElement.Height = height;
}
else
{
ImageElement.Height = double.NaN;
}

if (double.TryParse(RasterizedWidth, out var rasterizedWidth))
{
svgImageSource.RasterizePixelWidth = rasterizedWidth;
}
else
{
//svgImageSource.RasterizePixelWidth = double.PositiveInfinity;
}

if (double.TryParse(RasterizedHeight, out var rasterizedHeight))
{
svgImageSource.RasterizePixelHeight = rasterizedHeight;
}
else
{
//svgImageSource.RasterizePixelHeight = double.PositiveInfinity;
}
}
catch (Exception ex)
{
this.Log().LogError(ex, "Error while changing SVG properties");
}
}
}
23 changes: 21 additions & 2 deletions src/Uno.UI/UI/Xaml/Media/Imaging/SvgImageSource.wasm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Foundation;
using Windows.Graphics.Display;
using Windows.Storage.Streams;
Expand All @@ -10,6 +11,7 @@
using static Windows.UI.Xaml.Media.Imaging.BitmapImage;
using Windows.Storage.Helpers;
using Uno.UI.Xaml.Media;
using Uno.Helpers;

namespace Windows.UI.Xaml.Media.Imaging
{
Expand Down Expand Up @@ -43,8 +45,6 @@ private protected override bool TryOpenSourceSync(int? targetWidth, int? targetH
{
image = ImageData.FromUrl(uri.AbsoluteUri, this);
}

// TODO: Implement ms-appdata
}
else
{
Expand Down Expand Up @@ -74,9 +74,28 @@ private protected override bool TryOpenSourceAsync(
return true;
}

if (AbsoluteUri is { } absoluteUri)
{
if (AppDataUriEvaluator.IsAppDataUri(absoluteUri))
{
asyncImage = OpenMsAppData(absoluteUri, ct);

return true;
}
}

asyncImage = default;
return false;
}

private protected async Task<ImageData> OpenMsAppData(Uri uri, CancellationToken ct)
{
var file = await StorageFile.GetFileFromPathAsync(AppDataUriEvaluator.ToPath(uri));
var stream = await file.OpenAsync(FileAccessMode.Read);

var streamWithContentType = stream.TrySetContentType(ContentType);

return await OpenFromStream(streamWithContentType, null, ct);
}

internal override void ReportImageLoaded() => RaiseImageOpened();
Expand Down
6 changes: 6 additions & 0 deletions src/Uno.UWP/Helpers/AppDataUriEvaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ internal static class AppDataUriEvaluator
private const string RoamingFolderRoute = "roaming";
private const string TemporaryFolderRoute = "temp";

/// <summary>
/// Determines if an URI is using ms-appdata
/// </summary>
public static bool IsAppDataUri(Uri uri)
=> uri.Scheme.Equals("ms-appdata", StringComparison.OrdinalIgnoreCase);

/// <summary>
/// Converts given ms-appdata: URI to filesystem path.
/// </summary>
Expand Down

0 comments on commit 8dd1e30

Please sign in to comment.