Skip to content

Commit 421cf73

Browse files
committed
Fix DrawImage not working when scaling
1 parent 617eac0 commit 421cf73

File tree

6 files changed

+112
-41
lines changed

6 files changed

+112
-41
lines changed

.editorconfig

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,36 @@ dotnet_style_predefined_type_for_member_access= true:error
66
dotnet_diagnostic.CA1021.severity=silent
77
dotnet_diagnostic.CA1310.severity=suggestion
88
dotnet_style_allow_multiple_blank_lines_experimental= false:suggestion
9+
dotnet_style_coalesce_expression = true:suggestion
10+
dotnet_style_null_propagation = true:suggestion
11+
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
12+
dotnet_style_prefer_auto_properties = true:suggestion
13+
dotnet_style_object_initializer = true:suggestion
14+
dotnet_style_collection_initializer = true:suggestion
15+
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
16+
dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
17+
dotnet_style_prefer_conditional_expression_over_return = true:suggestion
18+
dotnet_style_operator_placement_when_wrapping = beginning_of_line
19+
tab_width = 4
20+
indent_size = 4
21+
dotnet_style_explicit_tuple_names = true:suggestion
22+
dotnet_style_prefer_inferred_tuple_names = true:suggestion
23+
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
24+
dotnet_style_prefer_compound_assignment = true:suggestion
25+
dotnet_style_prefer_simplified_interpolation = true:suggestion
26+
dotnet_style_namespace_match_folder = true:suggestion
27+
dotnet_style_readonly_field = true:suggestion
28+
dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
29+
dotnet_style_allow_statement_immediately_after_block_experimental = true:suggestion
30+
dotnet_code_quality_unused_parameters = non_public:suggestion
31+
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
32+
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
33+
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
34+
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
35+
dotnet_style_qualification_for_field = false:silent
36+
dotnet_style_qualification_for_property = false:silent
37+
dotnet_style_qualification_for_method = false:silent
38+
dotnet_style_qualification_for_event = false:silent
939

1040
[*.xml]
1141
indent_style = space
@@ -38,7 +68,7 @@ csharp_indent_labels = one_less_than_current
3868
csharp_using_directive_placement = outside_namespace:silent
3969
csharp_prefer_simple_using_statement = true:suggestion
4070
csharp_style_prefer_method_group_conversion = true:suggestion
41-
csharp_style_prefer_top_level_statements = true:silent
71+
csharp_style_prefer_top_level_statements = true:suggestion
4272
csharp_style_expression_bodied_lambdas = true:suggestion
4373
csharp_style_expression_bodied_local_functions = when_on_single_line:suggestion
4474
csharp_space_around_binary_operators = before_and_after

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ A fork of the SvgNet & SvgGdi bridge (http://www.codeproject.com/KB/cs/svgnet.as
44

55
__SvgNet is now available as a Nuget:__ [SvgNet](https://www.nuget.org/packages/SvgNet/).
66

7-
__Latest version 2.2.2 is .NET Standard 2.0 and 2.1 and also .NET 5.0/6.0 (base and Windows) compatible and works with .NET Core 2.x and 3.x and .NET 5.0/6.0, but now requires .NET Framework 4.6.1 or higher__
7+
__Latest version 3.0.0 is .NET Standard 2.0 and 2.1 and also .NET 6.0 (base and Windows) compatible and works with .NET Core 2.x and 3.x and .NET 5.0/6.0, but now requires .NET Framework 4.6.1 or higher__
88

9-
To build this version properly you need .NET 6.0.100+ SDK installed
9+
To build this version properly you need .NET 6.0.400+ SDK installed
1010

1111
## License: BSD
1212

SvgGdiTest/SvgGdiTestForm.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,12 @@ private void Render(IGraphics ig) {
6767
private void RenderImages(IGraphics ig) {
6868
var ike = new Icon(GetType(), "App.ico");
6969
ig.DrawIcon(ike, 10, 10);
70-
//ig.DrawIcon(ike, new Rectangle(270, 400, 30, 40));
70+
ig.DrawIcon(ike, new Rectangle(50, 10, ike.Width * 2, ike.Height * 3));
7171

7272
var bmp = new Bitmap(GetType(), "test.bmp");
7373
ig.DrawImage(bmp, 100f, 150f);
7474
GraphicsContainer cnt = ig.BeginContainer();
75-
ig.RotateTransform(5);
75+
ig.RotateTransform(7.5f);
7676
ig.DrawImage(bmp, 160f, 50f, 120f, 70f);
7777
ig.EndContainer(cnt);
7878
//ig.DrawImageUnscaled(bmp, 270, 450, 20, 20);
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
Copyright © 2003 RiskCare Ltd. All rights reserved.
3+
Copyright © 2010 SvgNet & SvgGdi Bridge Project. All rights reserved.
4+
Copyright © 2015-2022 Rafael Teixeira, Mojmír Němeček, Benjamin Peterson and Other Contributors
5+
6+
Original source code licensed with BSD-2-Clause spirit, treat it thus, see accompanied LICENSE for more
7+
*/
8+
9+
using SvgNet.Elements;
10+
11+
namespace SvgNet;
12+
13+
public sealed partial class SvgGraphics {
14+
private class BitmapDrawer {
15+
public BitmapDrawer(SvgGroupElement g, float x, float y, (float X, float Y) scaling) {
16+
_groupElement = g;
17+
_x = x;
18+
_y = y;
19+
(_scaleX, _scaleY) = scaling;
20+
}
21+
22+
private readonly SvgGroupElement _groupElement;
23+
private readonly float _x;
24+
private readonly float _y;
25+
private readonly float _scaleX;
26+
private readonly float _scaleY;
27+
28+
public SvgGroupElement DrawBitmapData(Bitmap b) {
29+
for (int line = 0; line < b.Height; ++line) {
30+
float scaledLine = _y + (line * _scaleY);
31+
// Only draws the last 'set' of pixels when a new color is encountered or it's the last pixel in the line.
32+
Color currentColor = GetPixelColor(b, line, 0);
33+
int consecutive = 1;
34+
for (int col = 0; col < b.Width; ++col) {
35+
try {
36+
if (col == b.Width - 1)
37+
DrawPixel(scaledLine, col, consecutive, currentColor);
38+
else {
39+
// This is SO slow, but better than making the whole library 'unsafe'
40+
Color nextColor = GetPixelColor(b, line, col + 1);
41+
if (nextColor != currentColor) {
42+
DrawPixel(scaledLine, col, consecutive, currentColor);
43+
currentColor = nextColor;
44+
consecutive = 1;
45+
} else consecutive++;
46+
}
47+
} catch { }
48+
}
49+
}
50+
return _groupElement;
51+
}
52+
53+
// This could be optimized in an unsafe version of the lib
54+
private static Color GetPixelColor(Bitmap b, int y, int x) => b.GetPixel(x, y);
55+
56+
private void DrawPixel(float scaledLine, int col, int consecutive, Color color) =>
57+
DrawImagePixel(_groupElement,
58+
color,
59+
_x + ((col - consecutive - 1) * _scaleX),
60+
scaledLine,
61+
consecutive * _scaleX,
62+
_scaleY);
63+
}
64+
}
65+

SvgNet/ImplementedGraphics/SVGGraphics.cs

Lines changed: 11 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
Original source code licensed with BSD-2-Clause spirit, treat it thus, see accompanied LICENSE for more
77
*/
88

9-
using SvgNet.Elements;
9+
using SvgNet.Elements;
1010
using SvgNet.Types;
1111

1212
namespace SvgNet;
@@ -31,7 +31,7 @@ namespace SvgNet;
3131
/// Some aspects of GDI that can be implemented in SVG are not. The most important omission is that only solid brushes are supported.
3232
/// </para>
3333
/// </summary>
34-
public sealed class SvgGraphics : IGraphics {
34+
public sealed partial class SvgGraphics : IGraphics {
3535
public SvgGraphics() : this(Color.FromName("Control")) {
3636
}
3737

@@ -1849,40 +1849,15 @@ private static PointF[] Spline2Bez(PointF[] points, int start, int num, bool clo
18491849
}
18501850

18511851
private void DrawBitmapData(Bitmap b, float x, float y, float w, float h, bool scale) {
1852-
var g = new SvgGroupElement("bitmap_at_" + x.ToString("F", CultureInfo.InvariantCulture) + "_" + y.ToString("F", CultureInfo.InvariantCulture));
1853-
1854-
float scalex = 1, scaley = 1;
1855-
1856-
if (scale) {
1857-
scalex = w / b.Width;
1858-
scaley = h / b.Height;
1859-
}
1860-
1861-
for (int line = 0; line < b.Height; ++line) {
1862-
// Only draws the last 'set' of pixels when a new color is encountered or it's the last pixel in the line.
1863-
Color currentColor = b.GetPixel(0, line);
1864-
int consecutive = 1;
1865-
for (int col = 0; col < b.Width; ++col) {
1866-
Color? nextColor = null;
1867-
// This is SO slow, but better than making the whole library 'unsafe'
1868-
if (col != b.Width - 1) nextColor = b.GetPixel(col + 1, line);
1869-
1870-
if (nextColor == currentColor) consecutive++;
1871-
else {
1872-
// New Color encountered or Last pixel in the line; Draw.
1873-
if (!scale) if (col <= w && line <= h)
1874-
DrawImagePixel(g, currentColor, x + col - (consecutive - 1), y + line, consecutive, 1);
1875-
else DrawImagePixel(g, currentColor, x + ((col - (consecutive - 1)) * scalex), y + (line * scaley), consecutive * scalex, scaley);
1876-
1877-
currentColor = nextColor ?? Color.Transparent; // Only null on last column so assigned color is never used.
1878-
consecutive = 1;
1879-
}
1880-
}
1881-
}
1882-
1852+
SvgGroupElement groupElement = new BitmapDrawer(
1853+
new SvgGroupElement("bitmap_at_" + x.ToString("F", CultureInfo.InvariantCulture) + "_" + y.ToString("F", CultureInfo.InvariantCulture)),
1854+
x,
1855+
y,
1856+
scale ? (w / b.Width, h / b.Height) : (1, 1))
1857+
.DrawBitmapData(b);
18831858
if (!_transforms.Result.IsIdentity)
1884-
g.Transform = _transforms.Result.Clone();
1885-
_cur.AddChild(g);
1859+
groupElement.Transform = _transforms.Result.Clone();
1860+
_cur.AddChild(groupElement);
18861861
}
18871862

18881863
private void DrawBitmapImage(Image image, float x, float y, float width, float height) {
@@ -2282,3 +2257,4 @@ public void Pop() {
22822257
private Matrix _result;
22832258
}
22842259
}
2260+

SvgNet/SvgNet.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFrameworks>netstandard2.0;netstandard2.1;net6.0</TargetFrameworks>
5-
<TargetFrameworks Condition="'$(OS)' == 'Windows_NT'">$(TargetFrameworks);net461;net5.0-windows;net6.0-windows</TargetFrameworks>
5+
<TargetFrameworks Condition="'$(OS)' == 'Windows_NT'">$(TargetFrameworks);net461;net6.0-windows</TargetFrameworks>
66
<UseWindowsForms Condition="'$(TargetFramework)' == 'net5.0-windows' or '$(TargetFramework)' == 'net6.0-windows'">true</UseWindowsForms>
77
<LangVersion>10.0</LangVersion>
88
<AssemblyName>SVG</AssemblyName>

0 commit comments

Comments
 (0)