mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-15 03:07:56 +01:00
[Peek] Use WebView2 for SVG preview to improve compatibility (#44209)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Improves SVG preview compatibility in Peek by using WebView2 instead of `SvgImageSource`. ## Problem `SvgImageSource` has limited SVG feature support and fails to render SVGs with advanced features like `clipPath`, complex gradients, or certain namespace configurations. This results in black previews or icon-only display for many SVG files. ## Solution Render SVG files using WebView2 which provides full SVG specification support through the browser engine. <img width="1973" height="1314" alt="image" src="https://github.com/user-attachments/assets/a4eb2ff5-d76f-4f7f-87e3-6404e18b2b09" /> <img width="1997" height="1358" alt="image" src="https://github.com/user-attachments/assets/7ce4dd69-7fba-447e-8499-d37af3f02c4d" /> <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] Closes: #44193 <!-- - [ ] Closes: #yyy (add separate lines for additional resolved issues) --> - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed
This commit is contained in:
@@ -54,8 +54,6 @@ namespace Peek.FilePreviewer.Previewers
|
||||
|
||||
private bool IsPng() => Item.Extension == ".png";
|
||||
|
||||
private bool IsSvg() => Item.Extension == ".svg";
|
||||
|
||||
private bool IsQoi() => Item.Extension == ".qoi";
|
||||
|
||||
private DispatcherQueue Dispatcher { get; }
|
||||
@@ -63,7 +61,7 @@ namespace Peek.FilePreviewer.Previewers
|
||||
private static readonly HashSet<string> _supportedFileTypes =
|
||||
BitmapDecoder.GetDecoderInformationEnumerator()
|
||||
.SelectMany(di => di.FileExtensions)
|
||||
.Union([".svg", ".qoi"])
|
||||
.Union([".qoi"])
|
||||
.ToHashSet(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
public static bool IsItemSupported(IFileSystemItem item)
|
||||
@@ -75,15 +73,7 @@ namespace Peek.FilePreviewer.Previewers
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
if (IsSvg())
|
||||
{
|
||||
var size = await Task.Run(Item.GetSvgSize);
|
||||
if (size != null)
|
||||
{
|
||||
ImageSize = size.Value;
|
||||
}
|
||||
}
|
||||
else if (IsQoi())
|
||||
if (IsQoi())
|
||||
{
|
||||
var size = await Task.Run(Item.GetQoiSize);
|
||||
if (size != null)
|
||||
@@ -176,31 +166,16 @@ namespace Peek.FilePreviewer.Previewers
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
using FileStream stream = ReadHelper.OpenReadOnly(Item.Path);
|
||||
|
||||
if (IsSvg())
|
||||
{
|
||||
var source = new SvgImageSource();
|
||||
source.RasterizePixelHeight = ImageSize?.Height ?? 0;
|
||||
source.RasterizePixelWidth = ImageSize?.Width ?? 0;
|
||||
|
||||
var loadStatus = await source.SetSourceAsync(stream.AsRandomAccessStream());
|
||||
if (loadStatus != SvgImageSourceLoadStatus.Success)
|
||||
{
|
||||
Logger.LogError("Error loading SVG: " + loadStatus.ToString());
|
||||
throw new ImageLoadingException(nameof(source));
|
||||
}
|
||||
|
||||
Preview = source;
|
||||
}
|
||||
else if (IsQoi())
|
||||
if (IsQoi())
|
||||
{
|
||||
using FileStream stream = ReadHelper.OpenReadOnly(Item.Path);
|
||||
using var bitmap = QoiImage.FromStream(stream);
|
||||
|
||||
Preview = await BitmapHelper.BitmapToImageSource(bitmap, true, cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
using FileStream stream = ReadHelper.OpenReadOnly(Item.Path);
|
||||
Preview = new BitmapImage();
|
||||
await ((BitmapImage)Preview).SetSourceAsync(stream.AsRandomAccessStream());
|
||||
}
|
||||
|
||||
@@ -33,6 +33,10 @@ namespace Peek.FilePreviewer.Previewers
|
||||
|
||||
// Markdown
|
||||
".md",
|
||||
|
||||
// SVG - using WebView2 for better compatibility with complex SVGs
|
||||
// (e.g., from Adobe Illustrator, Inkscape)
|
||||
".svg",
|
||||
};
|
||||
|
||||
[ObservableProperty]
|
||||
@@ -111,9 +115,10 @@ namespace Peek.FilePreviewer.Previewers
|
||||
{
|
||||
bool isHtml = File.Extension == ".html" || File.Extension == ".htm";
|
||||
bool isMarkdown = File.Extension == ".md";
|
||||
bool isSvg = File.Extension == ".svg";
|
||||
|
||||
bool supportedByMonaco = MonacoHelper.SupportedMonacoFileTypes.Contains(File.Extension);
|
||||
bool useMonaco = supportedByMonaco && !isHtml && !isMarkdown;
|
||||
bool useMonaco = supportedByMonaco && !isHtml && !isMarkdown && !isSvg;
|
||||
|
||||
IsDevFilePreview = supportedByMonaco;
|
||||
CustomContextMenu = useMonaco;
|
||||
@@ -128,6 +133,13 @@ namespace Peek.FilePreviewer.Previewers
|
||||
var raw = await ReadHelper.Read(File.Path.ToString());
|
||||
Preview = new Uri(MarkdownHelper.PreviewTempFile(raw, File.Path, TempFolderPath.Path));
|
||||
}
|
||||
else if (isSvg)
|
||||
{
|
||||
// SVG files are rendered directly by WebView2 for better compatibility
|
||||
// with complex SVGs from Adobe Illustrator, Inkscape, etc.
|
||||
IsDevFilePreview = false;
|
||||
Preview = new Uri(File.Path);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Simple html file to preview. Shouldn't do things like enabling scripts or using a virtual mapped directory.
|
||||
|
||||
Reference in New Issue
Block a user