Skip to content

Commit 0779e4a

Browse files
committed
Fixes the pixel artifacts occurring on small size outputs (#16)
1 parent 653e3d1 commit 0779e4a

File tree

7 files changed

+22
-51
lines changed

7 files changed

+22
-51
lines changed

SvgFileType/Extensions/SurfaceExtensions.cs

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using System;
55
using System.Runtime.CompilerServices;
66
using PaintDotNet;
7-
using PaintDotNet.Rendering;
87

98
namespace SvgFileTypePlugin.Extensions;
109

@@ -29,22 +28,6 @@ public static Document CreateSingleLayerDocument(this Surface surface, bool take
2928
return document;
3029
}
3130

32-
public static void ConvertFromPrgba(this Surface surface)
33-
{
34-
ArgumentNullException.ThrowIfNull(surface);
35-
36-
for (int y = 0; y < surface.Height; y++)
37-
{
38-
ref ColorBgra pix = ref surface.GetRowReferenceUnchecked(y);
39-
for (int x = surface.Width; x > 0; x--)
40-
{
41-
(pix.R, pix.B) = (pix.B, pix.R);
42-
pix = ref Unsafe.Add(ref pix, 1);
43-
}
44-
}
45-
surface.ConvertFromPremultipliedAlpha();
46-
}
47-
4831
public static bool IsEmpty(this Surface surface)
4932
{
5033
ArgumentNullException.ThrowIfNull(surface);
@@ -71,9 +54,6 @@ public static bool IsEmpty(this Surface surface)
7154
int h = tmp.Height;
7255
int stride = tmp.Stride;
7356
surface.Fill(backgroundColor);
74-
unsafe
75-
{
76-
new T().UnsafeApply(w, h, (ColorBgra*)surface.Scan0.Pointer, stride, (ColorBgra*)tmp.Scan0.Pointer, stride);
77-
}
57+
new T().Apply(surface, tmp);
7858
}
7959
}

SvgFileType/FodyWeavers.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
3-
<ILMerge IncludeAssemblies="Svg|ExCss|resvg.net|BitmapVectorizer|SimplePaletteQuantizer|PaintDotNet.IndirectUI.Fluent" NamespacePrefix="" IncludeResources="\.(resources|dtd|zip)$" CompactMode="0" FullImport="0" />
3+
<ILMerge IncludeAssemblies="Svg|ExCss|resvg.net|BitmapVectorizer|SimplePaletteQuantizer|PaintDotNet.IndirectUI.Fluent" NamespacePrefix="" IncludeResources="\.(resources|dtd|zip)$" CompactMode="0" FullImport="1" />
44
</Weavers>

SvgFileType/Import/MyBaseForm.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ public static bool UseImmersiveDarkModeColors(IWin32Window window, bool enable)
302302
{
303303
Attribute = WindowCompositionAttribute.WCA_USEDARKMODECOLORS,
304304
Data = enable ? 1 : 0,
305-
SizeOfData = Marshal.SizeOf(typeof(int))
305+
SizeOfData = Marshal.SizeOf<int>()
306306
};
307307
bool success = SetWindowCompositionAttribute(window.Handle, data);
308308
return success;
@@ -341,7 +341,7 @@ private static bool IsWindows10OrGreater(int build = -1)
341341
}
342342

343343
[DllImport("uxtheme", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
344-
private static extern int SetWindowTheme(IntPtr hWnd, string pszSubAppName, string pszSubIdList);
344+
private static extern int SetWindowTheme(IntPtr hWnd, string? pszSubAppName, string? pszSubIdList);
345345

346346
[DllImport("uxtheme", SetLastError = true, EntryPoint = "#133")]
347347
[return: MarshalAs(UnmanagedType.Bool)]

SvgFileType/Import/ResvgSvgRenderer.cs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,12 @@ protected override Document GetFlatDocument(string svgdata, SvgImportConfig conf
2525
using BenchmarkScope _ = new BenchmarkScope();
2626
using MemoryFailPoint mfp = GetMemoryFailPoint(width, height, 1);
2727
ResetProgress(1);
28-
Surface surface = new Surface(width, height, SurfaceCreationFlags.DoNotZeroFillHint);
28+
Surface surface = new Surface(width, height);
2929
try
3030
{
31-
using (Resvg resvg = Resvg.FromData(svgdata, loadSystemFonts: true))
32-
{
33-
ResvgTransform transform = CalculateTransform(resvg.Size, config);
34-
resvg.Render(surface.Scan0.Pointer, transform, width, height);
35-
}
36-
surface.ConvertFromPrgba();
31+
using Resvg resvg = Resvg.FromData(svgdata, loadSystemFonts: true);
32+
ResvgTransform transform = CalculateTransform(resvg.Size, config);
33+
resvg.Render(surface.Scan0.Pointer, transform, width, height, PixelOpFlags.RgbaToBgra | PixelOpFlags.UnPremultiplyAlpha);
3734
}
3835
catch (Exception)
3936
{
@@ -66,7 +63,7 @@ protected override Document GetLayeredDocument(string svgdata, SvgImportConfig c
6663
using ResvgOptions options = new ResvgOptions();
6764
options.LoadSystemFonts();
6865

69-
using Surface surface = new Surface(config.RasterWidth, config.RasterHeight);
66+
using Surface surface = new Surface(config.RasterWidth, config.RasterHeight, SurfaceCreationFlags.DoNotZeroFillHint);
7067
// Render all visual elements that are passed here.
7168
foreach (SvgVisualElement element in elements)
7269
{
@@ -141,9 +138,9 @@ private void RenderSvgDocument(SvgElement element, Surface surface, ResvgOptions
141138
else
142139
{
143140
SvgDocument clone = element.OwnerDocument.RemoveInvisibleAndNonTextElements();
144-
using (Resvg resvg = Resvg.FromData(clone.GetXML_QuotedFuncIRIHack(), options))
145-
resvg.Render(surface.Scan0.Pointer, surface.Width, surface.Height);
146-
surface.ConvertFromPrgba();
141+
(int width, int height) = (surface.Width, surface.Height);
142+
using Resvg resvg = Resvg.FromData(clone.GetXML_QuotedFuncIRIHack(), options);
143+
resvg.Render(surface.Scan0.Pointer, width, height, PixelOpFlags.RgbaToBgra | PixelOpFlags.UnPremultiplyAlpha);
147144
}
148145
}
149146

@@ -156,8 +153,8 @@ private static ResvgTransform CalculateTransform(SizeF svgsize, SvgImportConfig
156153
: config.RasterHeight / svgsize.Height * tolerance;
157154
return new ResvgTransform()
158155
{
159-
a = ratioX,
160-
d = ratioY
156+
M11 = ratioX,
157+
M22 = ratioY
161158
};
162159
}
163160
}

SvgFileType/SvgFileType.cs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -155,17 +155,12 @@ protected override bool ShouldSerializeTokenProperty(Property property)
155155

156156
private static bool IsSerializable(Property property)
157157
{
158-
switch (property.Name)
159-
{
160-
case nameof(PropertyNames.GitHubLink):
161-
case nameof(PropertyNames.DiscussionLink):
162-
case nameof(PropertyNames.PdnShape):
163-
case nameof(PropertyNames.PdnShapeName):
164-
case nameof(PropertyNames.PreviewMode):
165-
return false;
166-
default:
167-
return Enum.IsDefined(typeof(PropertyNames), property.Name);
168-
}
158+
return Enum.TryParse(property.Name, out PropertyNames prop)
159+
&& prop is not PropertyNames.GitHubLink
160+
and not PropertyNames.DiscussionLink
161+
and not PropertyNames.PdnShape
162+
and not PropertyNames.PdnShapeName
163+
and not PropertyNames.PreviewMode;
169164
}
170165

171166
#endregion

SvgFileType/SvgFileTypePlugin.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
<ProduceReferenceAssembly>false</ProduceReferenceAssembly>
1111
<RootNamespace>SvgFileTypePlugin</RootNamespace>
1212
<UseWindowsForms>true</UseWindowsForms>
13-
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
1413
</PropertyGroup>
1514

1615
<PropertyGroup Label="AssemblyInfo" Condition="'$(GenerateAssemblyInfo)'=='true' Or '$(GenerateAssemblyInfo)'==''">
@@ -19,7 +18,7 @@
1918
<Copyright>Copyright © 2025 Osman Tunçelli</Copyright>
2019
<Company>$(Copyright)</Company>
2120
<Product>$(AssemblyTitle)</Product>
22-
<Version>1.0.7.0</Version>
21+
<Version>1.0.7.1</Version>
2322
</PropertyGroup>
2423

2524
<PropertyGroup Label="Base Variables">

0 commit comments

Comments
 (0)