mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-07 03:36:44 +02:00
Add SVG Thumbnail Provider for Windows Explorer (#5048)
* Add SVG Thumbnail Provider * Some cleanup * Small settings changes * Update PowerToys.sln Remove Any CPU entries * Fix project configuration issues * Fix bad merge * Update output path for SVG thumbnail provider * Sync with latest
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.InteropServices.ComTypes;
|
||||
using System.Text;
|
||||
using Moq;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Common.ComInterlop;
|
||||
using SvgThumbnailProvider;
|
||||
|
||||
namespace SvgThumbnailProviderUnitTests
|
||||
{
|
||||
[TestClass]
|
||||
public class SvgThumbnailProviderTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void LoadSimpleSVG_ShouldReturnNonNullBitmap()
|
||||
{
|
||||
var svgBuilder = new StringBuilder();
|
||||
svgBuilder.AppendLine("<svg viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\">");
|
||||
svgBuilder.AppendLine("\t<circle cx=\"50\" cy=\"50\" r=\"50\">");
|
||||
svgBuilder.AppendLine("\t</circle>");
|
||||
svgBuilder.AppendLine("</svg>");
|
||||
|
||||
Bitmap thumbnail = SvgThumbnailProvider.SvgThumbnailProvider.GetThumbnail(svgBuilder.ToString(), 256);
|
||||
Assert.IsTrue(thumbnail != null);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CheckBlockedElements_ShouldReturnNullBitmap_IfBlockedElementsIsPresentInNestedLevel()
|
||||
{
|
||||
var svgBuilder = new StringBuilder();
|
||||
svgBuilder.AppendLine("<svg viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\">");
|
||||
svgBuilder.AppendLine("\t<circle cx=\"50\" cy=\"50\" r=\"50\">");
|
||||
svgBuilder.AppendLine("\t\t<script>alert(\"valid-message\")</script>");
|
||||
svgBuilder.AppendLine("\t</circle>");
|
||||
svgBuilder.AppendLine("</svg>");
|
||||
|
||||
Bitmap thumbnail = SvgThumbnailProvider.SvgThumbnailProvider.GetThumbnail(svgBuilder.ToString(), 256);
|
||||
Assert.IsTrue(thumbnail == null);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CheckNoSvg_ShouldReturnNullBitmap()
|
||||
{
|
||||
var svgBuilder = new StringBuilder();
|
||||
svgBuilder.AppendLine("<p>foo</p>");
|
||||
|
||||
Bitmap thumbnail = SvgThumbnailProvider.SvgThumbnailProvider.GetThumbnail(svgBuilder.ToString(), 256);
|
||||
Assert.IsTrue(thumbnail == null);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CheckNoSvgEmptyString_ShouldReturnNullBitmap()
|
||||
{
|
||||
Bitmap thumbnail = SvgThumbnailProvider.SvgThumbnailProvider.GetThumbnail("", 256);
|
||||
Assert.IsTrue(thumbnail == null);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CheckNoSvgNullString_ShouldReturnNullBitmap()
|
||||
{
|
||||
Bitmap thumbnail = SvgThumbnailProvider.SvgThumbnailProvider.GetThumbnail(null, 256);
|
||||
Assert.IsTrue(thumbnail == null);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CheckZeroSizedThumbnail_ShouldReturnNullBitmap()
|
||||
{
|
||||
string content = "<svg></svg>";
|
||||
Bitmap thumbnail = SvgThumbnailProvider.SvgThumbnailProvider.GetThumbnail(content, 0);
|
||||
Assert.IsTrue(thumbnail == null);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CheckBlockedElements_ShouldReturnBitmap_HTMLWrapped()
|
||||
{
|
||||
var svgBuilder = new StringBuilder();
|
||||
svgBuilder.AppendLine("<html>");
|
||||
svgBuilder.AppendLine("<head>");
|
||||
svgBuilder.AppendLine("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=Edge\">");
|
||||
svgBuilder.AppendLine("<meta http-equiv=\"Content-Type\" content=\"text/html\" charset=\"utf-8\">");
|
||||
svgBuilder.AppendLine("</head>");
|
||||
svgBuilder.AppendLine("<body>");
|
||||
svgBuilder.AppendLine("<svg viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\">");
|
||||
svgBuilder.AppendLine("<circle cx=\"50\" cy=\"50\" r=\"50\">");
|
||||
svgBuilder.AppendLine("</circle>");
|
||||
svgBuilder.AppendLine("</svg>");
|
||||
svgBuilder.AppendLine("</body>");
|
||||
svgBuilder.AppendLine("</html>");
|
||||
|
||||
Bitmap thumbnail = SvgThumbnailProvider.SvgThumbnailProvider.GetThumbnail(svgBuilder.ToString(), 256);
|
||||
Assert.IsTrue(thumbnail != null);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetThumbnail_ValidStreamSVG()
|
||||
{
|
||||
var svgBuilder = new StringBuilder();
|
||||
svgBuilder.AppendLine("<svg viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\">");
|
||||
svgBuilder.AppendLine("<circle cx=\"50\" cy=\"50\" r=\"50\">");
|
||||
svgBuilder.AppendLine("</circle>");
|
||||
svgBuilder.AppendLine("</svg>");
|
||||
|
||||
SvgThumbnailProvider.SvgThumbnailProvider provider = new SvgThumbnailProvider.SvgThumbnailProvider();
|
||||
|
||||
provider.Initialize(GetMockStream(svgBuilder.ToString()), 0);
|
||||
|
||||
IntPtr bitmap;
|
||||
WTS_ALPHATYPE alphaType;
|
||||
provider.GetThumbnail(256, out bitmap, out alphaType);
|
||||
|
||||
Assert.IsTrue(bitmap != IntPtr.Zero);
|
||||
Assert.IsTrue(alphaType == WTS_ALPHATYPE.WTSAT_RGB);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetThumbnail_ValidStreamHTML()
|
||||
{
|
||||
var svgBuilder = new StringBuilder();
|
||||
svgBuilder.AppendLine("<html>");
|
||||
svgBuilder.AppendLine("<head>");
|
||||
svgBuilder.AppendLine("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=Edge\">");
|
||||
svgBuilder.AppendLine("<meta http-equiv=\"Content-Type\" content=\"text/html\" charset=\"utf-8\">");
|
||||
svgBuilder.AppendLine("</head>");
|
||||
svgBuilder.AppendLine("<body>");
|
||||
svgBuilder.AppendLine("<svg viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\">");
|
||||
svgBuilder.AppendLine("<circle cx=\"50\" cy=\"50\" r=\"50\">");
|
||||
svgBuilder.AppendLine("</circle>");
|
||||
svgBuilder.AppendLine("</svg>");
|
||||
svgBuilder.AppendLine("</body>");
|
||||
svgBuilder.AppendLine("</html>");
|
||||
|
||||
SvgThumbnailProvider.SvgThumbnailProvider provider = new SvgThumbnailProvider.SvgThumbnailProvider();
|
||||
|
||||
provider.Initialize(GetMockStream(svgBuilder.ToString()), 0);
|
||||
|
||||
IntPtr bitmap;
|
||||
WTS_ALPHATYPE alphaType;
|
||||
provider.GetThumbnail(256, out bitmap, out alphaType);
|
||||
|
||||
Assert.IsTrue(bitmap != IntPtr.Zero);
|
||||
Assert.IsTrue(alphaType == WTS_ALPHATYPE.WTSAT_RGB);
|
||||
}
|
||||
|
||||
private IStream GetMockStream(string streamData)
|
||||
{
|
||||
var mockStream = new Mock<IStream>();
|
||||
var streamBytes = Encoding.UTF8.GetBytes(streamData);
|
||||
|
||||
var streamMock = new Mock<IStream>();
|
||||
var firstCall = true;
|
||||
streamMock
|
||||
.Setup(x => x.Read(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<IntPtr>()))
|
||||
.Callback<byte[], int, IntPtr>((buffer, countToRead, bytesReadPtr) =>
|
||||
{
|
||||
if (firstCall)
|
||||
{
|
||||
Array.Copy(streamBytes, 0, buffer, 0, streamBytes.Length);
|
||||
Marshal.WriteInt32(bytesReadPtr, streamBytes.Length);
|
||||
firstCall = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Marshal.WriteInt32(bytesReadPtr, 0);
|
||||
}
|
||||
});
|
||||
|
||||
return streamMock.Object;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\..\..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.props" Condition="Exists('..\..\..\..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{1EF1EEF0-10F0-4F2E-8550-39B6D8044D3E}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>UnitTests_SvgThumbnailProvider</RootNamespace>
|
||||
<AssemblyName>UnitTests-SvgThumbnailProvider</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
|
||||
<IsCodedUITest>False</IsCodedUITest>
|
||||
<TestProjectType>UnitTest</TestProjectType>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Castle.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\..\packages\Castle.Core.4.4.0\lib\net45\Castle.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\..\packages\MSTest.TestFramework.2.1.1\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\..\packages\MSTest.TestFramework.2.1.1\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Moq, Version=4.14.0.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\..\packages\Moq.4.14.5\lib\net45\Moq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\..\packages\System.Threading.Tasks.Extensions.4.5.1\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="SvgThumbnailProviderTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Common\PreviewHandlerCommon.csproj">
|
||||
<Project>{af2349b8-e5b6-4004-9502-687c1c7730b1}</Project>
|
||||
<Name>PreviewHandlerCommon</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SvgThumbnailProvider\SvgThumbnailProvider.csproj">
|
||||
<Project>{8ffe09da-fa4f-4ee1-b3a2-ad5497fbd1ad}</Project>
|
||||
<Name>SvgThumbnailProvider</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Properties\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\..\..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\..\..\..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.targets" Condition="Exists('..\..\..\..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.targets')" />
|
||||
</Project>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Castle.Core" version="4.4.0" targetFramework="net472" />
|
||||
<package id="Moq" version="4.14.5" targetFramework="net472" />
|
||||
<package id="MSTest.TestAdapter" version="2.1.1" targetFramework="net472" />
|
||||
<package id="MSTest.TestFramework" version="2.1.1" targetFramework="net472" />
|
||||
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.0" targetFramework="net472" />
|
||||
<package id="System.Threading.Tasks.Extensions" version="4.5.1" targetFramework="net472" />
|
||||
</packages>
|
||||
Reference in New Issue
Block a user