Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
0ad2d89
Make FilterQuality configurable for Resizetizer
jfversluis Mar 19, 2026
92052cb
Map FilterQuality to SamplingOptions and add functional tests
jfversluis Mar 19, 2026
83e0abb
Replace SKFilterQuality with custom ResizeQuality enum
jfversluis Mar 19, 2026
41deb7d
Address review: case-insensitive parsing + Best quality test
jfversluis Mar 19, 2026
b2975d5
Fix test gaps: SamplingOptions correctness, SVG pixel diffs, Best smo…
jfversluis Mar 19, 2026
9f96a53
Address review: add pixel array length guard, fix Fastest XML doc
jfversluis Mar 19, 2026
29a4d92
Potential fix for pull request finding
jfversluis Mar 19, 2026
a0d315f
Fix missing </summary> XML doc tag and add ResizeQuality to build inv…
jfversluis Apr 7, 2026
aae8194
Fix ResizeQuality propagation for monochrome adaptive icons
jfversluis Jun 8, 2026
04ad952
Address ResizeQuality incremental review feedback
jfversluis Jul 1, 2026
24bf0a2
Fix ResizeQuality splash input test for Helix
jfversluis Jul 1, 2026
1400dcd
Address ResizeQuality review comments
jfversluis Jul 2, 2026
10271d0
Address ResizeQuality incremental review follow-up
jfversluis Jul 8, 2026
3d3c59c
Require source inputs for ResizeQuality freshness checks
jfversluis Jul 9, 2026
f80c83f
Allow optional empty ResizeQuality freshness inputs
jfversluis Jul 10, 2026
3848dca
Address ResizeQuality SVG review feedback
jfversluis Jul 15, 2026
b80fcff
Guard in-tree imports on Core buildtasks
jfversluis Jul 15, 2026
65d879e
Handle fractional SVG dimensions for ResizeQuality
jfversluis Jul 15, 2026
e29b54f
Address final ResizeQuality review comments
jfversluis Jul 15, 2026
0a80a67
Fix adaptive icon foreground comment typo
jfversluis Jul 15, 2026
99f27ee
Remove unused Resizer using
jfversluis Jul 15, 2026
8c1d05e
Merge net11.0 into ResizeQuality branch
jfversluis Aug 3, 2026
2cecde0
Fix net11 device test compile errors
jfversluis Aug 3, 2026
bc8afed
Skip Avalonia template builds until packages are available
jfversluis Aug 3, 2026
b0d2352
Serialize dispatcher provider unit tests
jfversluis Aug 3, 2026
3b29bba
Check in-tree build task imports before importing
jfversluis Aug 3, 2026
f9d67f6
Merge net11.0 into ResizeQuality branch
jfversluis Aug 6, 2026
484a562
Add empirical SVG resize quality test
jfversluis Aug 6, 2026
943428a
Retry CI after infrastructure failure
jfversluis Aug 6, 2026
a6f7f81
Preserve resize quality for themed splash assets
jfversluis Aug 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions src/Maui.InTree.props
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
<Project>

<ImportGroup Condition="Exists('$(_MauiBuildTasksLocation)Microsoft.Maui.Controls.Build.Tasks.dll') and Exists('$(_MauiBuildTasksLocation)Microsoft.Maui.Resizetizer.dll')">
<PropertyGroup>
<_MauiCoreBuildTasksProps>$(_MauiBuildTasksLocation)Microsoft.Maui.Core.props</_MauiCoreBuildTasksProps>
<_MauiCoreBuildTasksProps Condition="'$(_MauiTargetPlatformIsWindows)' == 'true'">$(_MauiBuildTasksLocation)net$(_MauiMinimumSupportedDotNetTfm)-windows$(MinimumWindowsTargetFrameworkVersion)\Microsoft.Maui.Core.props</_MauiCoreBuildTasksProps>
<_MauiControlsBuildTasksProps>$(_MauiBuildTasksLocation)Microsoft.Maui.Controls.Build.Tasks.props</_MauiControlsBuildTasksProps>
<_MauiControlsBuildTasksProps Condition="'$(_MauiTargetPlatformIsiOS)' == 'true'">$(_MauiBuildTasksLocation)net6.0-ios10.0\Microsoft.Maui.Controls.Build.Tasks.props</_MauiControlsBuildTasksProps>
<_MauiControlsBuildTasksProps Condition="'$(_MauiTargetPlatformIsMacCatalyst)' == 'true'">$(_MauiBuildTasksLocation)net6.0-maccatalyst13.1\Microsoft.Maui.Controls.Build.Tasks.props</_MauiControlsBuildTasksProps>
<_MauiControlsBuildTasksProps Condition="'$(_MauiTargetPlatformIsWindows)' == 'true'">$(_MauiBuildTasksLocation)net6.0-windows10.0.17763.0\Microsoft.Maui.Controls.Build.Tasks.props</_MauiControlsBuildTasksProps>
<_MauiResizetizerBuildTasksProps>$(_MauiBuildTasksLocation)Microsoft.Maui.Resizetizer.props</_MauiResizetizerBuildTasksProps>
<_MauiBuildTasksPropsReady Condition="Exists('$(_MauiCoreBuildTasksProps)') and Exists('$(_MauiControlsBuildTasksProps)') and Exists('$(_MauiResizetizerBuildTasksProps)') and Exists('$(_MauiBuildTasksLocation)Microsoft.Maui.Controls.Build.Tasks.dll') and Exists('$(_MauiBuildTasksLocation)Microsoft.Maui.Resizetizer.dll')">true</_MauiBuildTasksPropsReady>
</PropertyGroup>

<ImportGroup Condition="'$(_MauiBuildTasksPropsReady)' == 'true'">

<!-- Microsoft.Maui.Core.props -->
<Import Project="$(_MauiBuildTasksLocation)net$(_MauiMinimumSupportedDotNetTfm)-windows$(MinimumWindowsTargetFrameworkVersion)\Microsoft.Maui.Core.props" Condition="'$(_MauiTargetPlatformIsWindows)' == 'true'" />
<Import Project="$(_MauiBuildTasksLocation)Microsoft.Maui.Core.props" Condition="'$(_MauiTargetPlatformIsWindows)' != 'true'" />
<Import Project="$(_MauiCoreBuildTasksProps)" />

<!-- Microsoft.Maui.Controls.Build.Tasks.props -->
<Import Project="$(_MauiBuildTasksLocation)net6.0-ios10.0\Microsoft.Maui.Controls.Build.Tasks.props" Condition="'$(_MauiTargetPlatformIsiOS)' == 'true'" />
<Import Project="$(_MauiBuildTasksLocation)net6.0-maccatalyst13.1\Microsoft.Maui.Controls.Build.Tasks.props" Condition="'$(_MauiTargetPlatformIsMacCatalyst)' == 'true'" />
<Import Project="$(_MauiBuildTasksLocation)net6.0-windows10.0.17763.0\Microsoft.Maui.Controls.Build.Tasks.props" Condition="'$(_MauiTargetPlatformIsWindows)' == 'true'" />
<Import Project="$(_MauiBuildTasksLocation)Microsoft.Maui.Controls.Build.Tasks.props" Condition="'$(_MauiTargetPlatformIsiOS)' != 'true' and '$(_MauiTargetPlatformIsMacCatalyst)' != 'true' and '$(_MauiTargetPlatformIsWindows)' != 'true'" />
<Import Project="$(_MauiControlsBuildTasksProps)" />

<!-- Microsoft.Maui.Resizetizer.props -->
<Import Project="$(_MauiBuildTasksLocation)Microsoft.Maui.Resizetizer.props" />
<Import Project="$(_MauiResizetizerBuildTasksProps)" />

</ImportGroup>

Expand Down
28 changes: 18 additions & 10 deletions src/Maui.InTree.targets
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,36 @@

<ItemGroup>
<ProjectCapability Include="MauiRepository" />
<ProjectCapability Include="MauiRepositorySampleProject" Contition="'$(SampleProject)' == 'true'" />
<ProjectCapability Include="MauiRepositorySampleProject" Condition="'$(SampleProject)' == 'true'" />
</ItemGroup>

<ImportGroup Condition="Exists('$(_MauiBuildTasksLocation)Microsoft.Maui.Controls.Build.Tasks.dll') and Exists('$(_MauiBuildTasksLocation)Microsoft.Maui.Resizetizer.dll')">
<PropertyGroup>
<_MauiCoreBuildTasksTargets>$(_MauiBuildTasksLocation)Microsoft.Maui.Core.targets</_MauiCoreBuildTasksTargets>
<_MauiCoreBuildTasksTargets Condition="'$(_MauiTargetPlatformIsWindows)' == 'true'">$(_MauiBuildTasksLocation)net$(_MauiMinimumSupportedDotNetTfm)-windows$(MinimumWindowsTargetFrameworkVersion)\Microsoft.Maui.Core.targets</_MauiCoreBuildTasksTargets>
<_MauiControlsBuildTasksTargets>$(_MauiBuildTasksLocation)Microsoft.Maui.Controls.Build.Tasks.targets</_MauiControlsBuildTasksTargets>
<_MauiControlsBuildTasksTargets Condition="'$(_MauiTargetPlatformIsiOS)' == 'true'">$(_MauiBuildTasksLocation)net6.0-ios10.0\Microsoft.Maui.Controls.Build.Tasks.targets</_MauiControlsBuildTasksTargets>
<_MauiControlsBuildTasksTargets Condition="'$(_MauiTargetPlatformIsMacCatalyst)' == 'true'">$(_MauiBuildTasksLocation)net6.0-maccatalyst13.1\Microsoft.Maui.Controls.Build.Tasks.targets</_MauiControlsBuildTasksTargets>
<_MauiControlsBuildTasksTargets Condition="'$(_MauiTargetPlatformIsWindows)' == 'true'">$(_MauiBuildTasksLocation)net6.0-windows10.0.17763.0\Microsoft.Maui.Controls.Build.Tasks.targets</_MauiControlsBuildTasksTargets>
<_MauiCoreAfterBuildTasksTargets>$(_MauiBuildTasksLocation)Microsoft.Maui.Core.After.targets</_MauiCoreAfterBuildTasksTargets>
<_MauiResizetizerBuildTasksTargets>$(_MauiBuildTasksLocation)Microsoft.Maui.Resizetizer.targets</_MauiResizetizerBuildTasksTargets>
<_MauiBuildTasksTargetsReady Condition="Exists('$(_MauiCoreBuildTasksTargets)') and Exists('$(_MauiControlsBuildTasksTargets)') and Exists('$(_MauiCoreAfterBuildTasksTargets)') and Exists('$(_MauiResizetizerBuildTasksTargets)') and Exists('$(_MauiBuildTasksLocation)Microsoft.Maui.Controls.Build.Tasks.dll') and Exists('$(_MauiBuildTasksLocation)Microsoft.Maui.Resizetizer.dll')">true</_MauiBuildTasksTargetsReady>
</PropertyGroup>

<ImportGroup Condition="'$(_MauiBuildTasksPropsReady)' == 'true' and '$(_MauiBuildTasksTargetsReady)' == 'true'">

Comment thread
jfversluis marked this conversation as resolved.
<!-- Microsoft.Maui.Core.targets -->
<Import Project="$(_MauiBuildTasksLocation)net$(_MauiMinimumSupportedDotNetTfm)-windows$(MinimumWindowsTargetFrameworkVersion)\Microsoft.Maui.Core.targets" Condition="'$(_MauiTargetPlatformIsWindows)' == 'true'" />
<Import Project="$(_MauiBuildTasksLocation)Microsoft.Maui.Core.targets" Condition="'$(_MauiTargetPlatformIsWindows)' != 'true'" />
<Import Project="$(_MauiCoreBuildTasksTargets)" />

Comment thread
jfversluis marked this conversation as resolved.
<!-- Microsoft.Maui.Controls.Build.Tasks.targets -->
<Import Project="$(_MauiBuildTasksLocation)net6.0-ios10.0\Microsoft.Maui.Controls.Build.Tasks.targets" Condition="'$(_MauiTargetPlatformIsiOS)' == 'true'" />
<Import Project="$(_MauiBuildTasksLocation)net6.0-maccatalyst13.1\Microsoft.Maui.Controls.Build.Tasks.targets" Condition="'$(_MauiTargetPlatformIsMacCatalyst)' == 'true'" />
<Import Project="$(_MauiBuildTasksLocation)net6.0-windows10.0.17763.0\Microsoft.Maui.Controls.Build.Tasks.targets" Condition="'$(_MauiTargetPlatformIsWindows)' == 'true'" />
<Import Project="$(_MauiBuildTasksLocation)Microsoft.Maui.Controls.Build.Tasks.targets" Condition="'$(_MauiTargetPlatformIsiOS)' != 'true' and '$(_MauiTargetPlatformIsMacCatalyst)' != 'true' and '$(_MauiTargetPlatformIsWindows)' != 'true'" />
<Import Project="$(_MauiControlsBuildTasksTargets)" />

<!-- Microsoft.Maui.Resizetizer.targets -->
<Import Project="$(_MauiBuildTasksLocation)Microsoft.Maui.Resizetizer.targets" />
<Import Project="$(_MauiResizetizerBuildTasksTargets)" />

</ImportGroup>

<Target Name="VerifyMauiBuildTasksBuilt" BeforeTargets="_CheckForInvalidConfigurationAndPlatform">
<Error Condition="!Exists('$(_MauiBuildTasksLocation)Microsoft.Maui.Controls.Build.Tasks.dll') or !Exists('$(_MauiBuildTasksLocation)Microsoft.Maui.Resizetizer.dll')"
<Error Condition="'$(_MauiBuildTasksPropsReady)' != 'true' or '$(_MauiBuildTasksTargetsReady)' != 'true'"
Text="We have detected that the required MSBuild tasks are not yet built or they are out of date. (Expand to see more info)
You will need to exit Visual Studio and wait for it to completely close.
After the process has ended, run the build command on the CLI with the .NET MAUI repository as the working directory:
Expand Down
31 changes: 14 additions & 17 deletions src/SingleProject/Resizetizer/src/AndroidAdaptiveIconGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,21 @@ namespace Microsoft.Maui.Resizetizer
{
internal class AndroidAdaptiveIconGenerator
{
public AndroidAdaptiveIconGenerator(ResizeImageInfo info, string appIconName, string intermediateOutputPath, ILogger logger)
public AndroidAdaptiveIconGenerator(ResizeImageInfo info, string appIconName, string intermediateOutputPath, string inputsFile, ILogger logger)
{
Info = info;
Logger = logger;
IntermediateOutputPath = intermediateOutputPath;
AppIconName = appIconName;
InputsFile = inputsFile;
}

public ResizeImageInfo Info { get; }

public string IntermediateOutputPath { get; }

public string InputsFile { get; }

public ILogger Logger { get; private set; }

public string AppIconName { get; }
Expand Down Expand Up @@ -65,7 +68,7 @@ public IEnumerable<ResizedImageInfo> Generate()
void ProcessBackground(List<ResizedImageInfo> results, DirectoryInfo fullIntermediateOutputPath)
{
var backgroundFile = Info.Filename;
var (backgroundExists, backgroundModified) = Utils.FileExists(backgroundFile);
var (backgroundExists, _) = Utils.FileExists(backgroundFile);
var backgroundDestFilename = AppIconName + "_background.png";

if (backgroundExists)
Expand All @@ -77,12 +80,10 @@ void ProcessBackground(List<ResizedImageInfo> results, DirectoryInfo fullInterme
{
var dir = Path.Combine(fullIntermediateOutputPath.FullName, dpi.Path);
var destination = Path.Combine(dir, backgroundDestFilename);
var (destinationExists, destinationModified) = Utils.FileExists(destination);
Directory.CreateDirectory(dir);

if (destinationModified > backgroundModified)
if (Resizer.IsUpToDate(new[] { backgroundFile }, destination, InputsFile, Logger, backgroundFile))
{
Logger.Log($"Skipping `{backgroundFile}` => `{destination}` file is up to date.");
results.Add(new ResizedImageInfo { Dpi = dpi, Filename = destination });
continue;
}
Expand All @@ -92,7 +93,7 @@ void ProcessBackground(List<ResizedImageInfo> results, DirectoryInfo fullInterme
if (backgroundExists)
{
// resize the background
var tools = SkiaSharpTools.Create(Info.IsVector, Info.Filename, dpi.Size, Info.Color, null, Logger);
var tools = SkiaSharpTools.Create(Info.IsVector, Info.Filename, dpi.Size, Info.Color, null, Info.Quality, Logger);
Comment thread
jfversluis marked this conversation as resolved.
Comment thread
jfversluis marked this conversation as resolved.
Comment thread
jfversluis marked this conversation as resolved.
tools.Resize(dpi, destination, dpiSizeIsAbsolute: true);
}
else
Expand All @@ -109,7 +110,7 @@ void ProcessBackground(List<ResizedImageInfo> results, DirectoryInfo fullInterme
void ProcessForeground(List<ResizedImageInfo> results, DirectoryInfo fullIntermediateOutputPath)
{
var foregroundFile = Info.ForegroundFilename;
var (foregroundExists, foregroundModified) = Utils.FileExists(foregroundFile);
var (foregroundExists, _) = Utils.FileExists(foregroundFile);
var foregroundDestFilename = AppIconName + "_foreground.png";

if (foregroundExists)
Expand All @@ -121,12 +122,10 @@ void ProcessForeground(List<ResizedImageInfo> results, DirectoryInfo fullInterme
{
var dir = Path.Combine(fullIntermediateOutputPath.FullName, dpi.Path);
var destination = Path.Combine(dir, foregroundDestFilename);
var (destinationExists, destinationModified) = Utils.FileExists(destination);
Directory.CreateDirectory(dir);

if (destinationModified > foregroundModified)
if (Resizer.IsUpToDate(new[] { foregroundFile }, destination, InputsFile, Logger, foregroundFile))
{
Logger.Log($"Skipping `{foregroundFile}` => `{destination}` file is up to date.");
results.Add(new ResizedImageInfo { Dpi = dpi, Filename = destination });
continue;
}
Expand All @@ -135,8 +134,8 @@ void ProcessForeground(List<ResizedImageInfo> results, DirectoryInfo fullInterme

if (foregroundExists)
{
// resize the forground
var tools = SkiaSharpTools.Create(Info.ForegroundIsVector, Info.ForegroundFilename, dpi.Size, null, Info.TintColor, Logger);
// resize the foreground
var tools = SkiaSharpTools.Create(Info.ForegroundIsVector, Info.ForegroundFilename, dpi.Size, null, Info.TintColor, Info.Quality, Logger);
tools.Resize(dpi, destination, Info.ForegroundScale, dpiSizeIsAbsolute: true);
Comment thread
jfversluis marked this conversation as resolved.
}
else
Expand All @@ -153,7 +152,7 @@ void ProcessForeground(List<ResizedImageInfo> results, DirectoryInfo fullInterme
void ProcessMonochrome(List<ResizedImageInfo> results, DirectoryInfo fullIntermediateOutputPath)
{
var monochromeFile = Info.MonochromeFilename;
var (monochromeExists, monochromeModified) = Utils.FileExists(monochromeFile);
var (monochromeExists, _) = Utils.FileExists(monochromeFile);
var monochromeDestFilename = AppIconName + "_monochrome.png";

if (monochromeExists)
Expand All @@ -165,12 +164,10 @@ void ProcessMonochrome(List<ResizedImageInfo> results, DirectoryInfo fullInterme
{
var dir = Path.Combine(fullIntermediateOutputPath.FullName, dpi.Path);
var destination = Path.Combine(dir, monochromeDestFilename);
var (destinationExists, destinationModified) = Utils.FileExists(destination);
Directory.CreateDirectory(dir);

if (destinationModified > monochromeModified)
if (Resizer.IsUpToDate(new[] { monochromeFile }, destination, InputsFile, Logger, monochromeFile))
{
Logger.Log($"Skipping `{monochromeFile}` => `{destination}` file is up to date.");
results.Add(new ResizedImageInfo { Dpi = dpi, Filename = destination });
continue;
}
Expand All @@ -179,7 +176,7 @@ void ProcessMonochrome(List<ResizedImageInfo> results, DirectoryInfo fullInterme

if (monochromeExists)
{
var tools = SkiaSharpTools.Create(Info.MonochromeIsVector, Info.MonochromeFilename, dpi.Size, null, null, Logger);
var tools = SkiaSharpTools.Create(Info.MonochromeIsVector, Info.MonochromeFilename, dpi.Size, null, null, Info.Quality, Logger);
tools.Resize(dpi, destination, dpiSizeIsAbsolute: true);
}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ private static ResizeImageInfo CloneForAsset(ResizeImageInfo info, string alias)
Resize = info.Resize,
TintColor = info.TintColor,
Color = info.Color,
Quality = info.Quality,
};

private static string GetAssetExtension(ResizeImageInfo info) =>
Expand Down
9 changes: 9 additions & 0 deletions src/SingleProject/Resizetizer/src/ResizeImageInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ namespace Microsoft.Maui.Resizetizer
{
internal class ResizeImageInfo
{
public const ResizeQuality DefaultResizeQuality = ResizeQuality.Auto;

public string? ItemSpec { get; set; }

public string? Alias { get; set; }
Expand Down Expand Up @@ -67,6 +69,8 @@ DarkTintColor is not null ||

public bool MonochromeIsVector => IsVectorFilename(MonochromeFilename);

public ResizeQuality Quality { get; set; } = DefaultResizeQuality;

private static bool IsVectorFilename(string? filename)
=> IsVectorExtension(Path.GetExtension(filename));

Expand Down Expand Up @@ -141,6 +145,10 @@ public static ResizeImageInfo Parse(ITaskItem image)
if (float.TryParse(image.GetMetadata("ForegroundScale"), NumberStyles.Number, CultureInfo.InvariantCulture, out var fsc))
info.ForegroundScale = fsc;

if (Enum.TryParse<ResizeQuality>(image.GetMetadata("ResizeQuality"), ignoreCase: true, out var quality) &&
Enum.IsDefined(typeof(ResizeQuality), quality))
info.Quality = quality;

var fgFile = image.GetMetadata("ForegroundFile");
if (!string.IsNullOrEmpty(fgFile))
{
Expand Down Expand Up @@ -201,6 +209,7 @@ public ResizeImageInfo CreateDarkVariant(string? alias = null)
ForegroundFilename = ForegroundFilename,
ForegroundScale = ForegroundScale,
MonochromeFilename = MonochromeFilename,
Quality = Quality,
};
}
}
Expand Down
28 changes: 28 additions & 0 deletions src/SingleProject/Resizetizer/src/ResizeQuality.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace Microsoft.Maui.Resizetizer
{
/// <summary>
/// Controls the quality of image resampling during resize operations.
/// </summary>
internal enum ResizeQuality
{
/// <summary>
/// Default behavior, preserving existing image output.
/// Uses bilinear interpolation with mipmaps.
/// </summary>
Auto = 0,

/// <summary>
/// Highest quality output using Mitchell cubic resampler.
/// Provides high-fidelity scaling when preserving smooth detail is critical.
/// Uses cubic resampling for smoother results than the default bilinear output.
/// </summary>
Best = 1,

/// <summary>
/// Fastest processing with nearest-neighbor interpolation.
/// May appear pixelated when scaling, but is ideal for pixel art.
/// Use it when build speed matters more than visual fidelity.
/// </summary>
Fastest = 2,
}
}
44 changes: 33 additions & 11 deletions src/SingleProject/Resizetizer/src/Resizer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.IO;
using System.Collections.Generic;
using System.IO;
using SkiaSharp;

namespace Microsoft.Maui.Resizetizer
Expand All @@ -25,7 +26,7 @@ public Resizer(ResizeImageInfo info, string intermediateOutputPath, ILogger logg
public SKSize? BaseSize => Info.BaseSize;

protected SkiaSharpTools Tools =>
tools ??= SkiaSharpTools.Create(Info.IsVector, Info.Filename, Info.BaseSize, Info.Color, Info.TintColor, Logger);
tools ??= SkiaSharpTools.Create(Info.IsVector, Info.Filename, Info.BaseSize, Info.Color, Info.TintColor, Info.Quality, Logger);

public string GetRasterFileDestination(DpiPath dpi, bool includeIntermediate = true, bool includeScale = true)
=> GetRasterFileDestination(Info, dpi, includeIntermediate ? IntermediateOutputPath : null, includeScale);
Expand Down Expand Up @@ -75,21 +76,42 @@ public ResizedImageInfo CopyFile(DpiPath dpi, string inputsFile)
return new ResizedImageInfo { Filename = destination, Dpi = dpi };
}

static bool IsUpToDate(string inputFile, string outputFile, string inputsFile, ILogger logger)
internal static bool IsUpToDate(string inputFile, string outputFile, string inputsFile, ILogger logger)
{
var fileIn = new FileInfo(inputFile);
return IsUpToDate(new[] { inputFile }, outputFile, inputsFile, logger, inputFile);
}

internal static bool IsUpToDate(IEnumerable<string> inputFiles, string outputFile, string inputsFile, ILogger logger, string inputDescription = null)
{
var fileInputs = string.IsNullOrEmpty(inputsFile) ? null : new FileInfo(inputsFile);
if (fileInputs?.Exists != true)
return false;

var fileOut = new FileInfo(outputFile);
var fileInputs = inputsFile is null ? null : new FileInfo(inputsFile);
if (!fileOut.Exists)
return false;

if (fileIn.Exists && fileOut.Exists && fileInputs?.Exists == true
&& fileIn.LastWriteTimeUtc <= fileOut.LastWriteTimeUtc
&& fileInputs.LastWriteTimeUtc <= fileOut.LastWriteTimeUtc)
var newestInput = fileInputs.LastWriteTimeUtc;

foreach (var inputFile in inputFiles)
{
logger.Log($"Skipping '{inputFile}' as output '{outputFile}' is already up to date.");
return true;
if (string.IsNullOrEmpty(inputFile))
continue;

var fileIn = new FileInfo(inputFile);
if (!fileIn.Exists)
return false;

if (fileIn.LastWriteTimeUtc > newestInput)
newestInput = fileIn.LastWriteTimeUtc;
}

return false;
if (newestInput > fileOut.LastWriteTimeUtc)
return false;

var description = string.IsNullOrEmpty(inputDescription) ? "inputs" : inputDescription;
logger.Log($"Skipping '{description}' as output '{outputFile}' is already up to date.");
return true;
}

public ResizedImageInfo Resize(DpiPath dpi, string inputsFile)
Expand Down
Loading
Loading