diff --git a/CADability.Forms/GdiPrinting.cs b/CADability.Forms/GdiPrinting.cs
new file mode 100644
index 00000000..1b979e37
--- /dev/null
+++ b/CADability.Forms/GdiPrinting.cs
@@ -0,0 +1,69 @@
+using CADability.Attribute;
+using System.Drawing;
+using System.Drawing.Printing;
+
+namespace CADability.Forms
+{
+ ///
+ /// Printing with GDI+ (System.Drawing.Printing): prints a or a to a
+ /// and renders a model into a . These methods replace
+ /// , and the public
+ /// members of , which are obsolete because GDI+ leaves the kernel in CADability 2.0 (issue #412).
+ /// In CADability 1.x they still use the implementation in the kernel; in 2.0 it moves here.
+ ///
+ public static class GdiPrinting
+ {
+#pragma warning disable CS0618 // the implementation is still in the kernel in CADability 1.x
+ ///
+ /// Prints the layout of on a single page. Depending on the global setting
+ /// "Printing.PrintingMode" the patches are either output as vector graphics (mode 1, with hidden line removal and shading)
+ /// or each patch is rendered into a bitmap at the printer resolution which is placed on the page. The paper size of the
+ /// layout is assumed to be in mm. Exceptions of the printing system are swallowed.
+ ///
+ /// The print document to print to, with the printer and page settings already set
+ /// The layout to print
+ public static void Print(this PrintDocument printDocument, LayoutView layoutView)
+ {
+ layoutView.Print(printDocument);
+ }
+ ///
+ /// Prints the contents of on a single page. The paper of the view
+ /// ( by ) is fitted onto the page, so the paper size
+ /// should be set. Exceptions of the printing system are swallowed.
+ ///
+ /// The print document to print to, with the printer and page settings already set
+ /// The view to print
+ public static void PrintSinglePage(this PrintDocument printDocument, GDI2DView gdiView)
+ {
+ gdiView.PrintSinglePage(printDocument);
+ }
+ ///
+ /// Prints the named of on a single page.
+ /// Nothing is printed if the project has no such view.
+ ///
+ /// The print document to print to, null for the print document of the project
+ /// The project containing the view
+ /// The name of the view
+ /// True to print only the curves, false to print the faces too
+ public static void PrintSinglePage(this PrintDocument printDocument, Project project, string nameOfView, bool print2D)
+ {
+ PrintToGDI.PrintSinglePage(project, nameOfView, print2D, printDocument);
+ }
+ ///
+ /// Renders with the into , which is
+ /// filled white first.
+ ///
+ /// The bitmap to render into
+ /// The model to render
+ /// The projection to use
+ /// The layers to render
+ /// True to shade the faces
+ /// Not used: whether only the curves are rendered follows of
+ /// , as in
+ public static void DrawModel(this Bitmap bitmap, Model model, Projection projection, Layer[] visibleLayers, bool shading, bool curvesOnly)
+ {
+ new PrintToGDI(bitmap).PrintToBitmap(model, projection, visibleLayers, shading, curvesOnly);
+ }
+#pragma warning restore CS0618
+ }
+}
diff --git a/CADability/GDI2DView.cs b/CADability/GDI2DView.cs
index e2f7f6b9..71b89eab 100644
--- a/CADability/GDI2DView.cs
+++ b/CADability/GDI2DView.cs
@@ -348,7 +348,7 @@ public bool ThinLinesOnly
/// is fitted onto the page, so the paper size should be set. Exceptions of the printing system are swallowed.
///
/// The print document to print to, with the printer and page settings already set
- [Obsolete("Printing with GDI+ moves into CADability.Forms in CADability 2.0 (issue #412).")]
+ [Obsolete("Use the PrintDocument extension PrintSinglePage(GDI2DView) of CADability.Forms.GdiPrinting instead. Printing with GDI+ moves into CADability.Forms in CADability 2.0 (issue #412).")]
public void PrintSinglePage(PrintDocument pd)
{
PrintToGDI pdg = new PrintToGDI(this);
diff --git a/CADability/LayoutView.cs b/CADability/LayoutView.cs
index 632cfcfd..d8e9d7e9 100644
--- a/CADability/LayoutView.cs
+++ b/CADability/LayoutView.cs
@@ -148,7 +148,7 @@ public void ZoomTotal(double factor)
/// the printing system are swallowed.
///
/// The print document to print to, with the printer and page settings already set
- [Obsolete("Printing with GDI+ moves into CADability.Forms in CADability 2.0 (issue #412).")]
+ [Obsolete("Use the PrintDocument extension Print(LayoutView) of CADability.Forms.GdiPrinting instead. Printing with GDI+ moves into CADability.Forms in CADability 2.0 (issue #412).")]
public void Print(PrintDocument pd)
{
bool printToGDI = Settings.GlobalSettings.GetIntValue("Printing.PrintingMode", 0) == 1;
diff --git a/CADability/PrintToGDI.cs b/CADability/PrintToGDI.cs
index 98943026..b4b93a3e 100644
--- a/CADability/PrintToGDI.cs
+++ b/CADability/PrintToGDI.cs
@@ -1453,7 +1453,7 @@ public override IGeoObject Debug
/// ), to render a model into a () and for the display of
/// the . Not available in the WebAssembly build.
///
- [Obsolete("Printing with GDI+ moves into CADability.Forms in CADability 2.0 (issue #412).")]
+ [Obsolete("Use the extensions of CADability.Forms.GdiPrinting instead: PrintDocument.Print(LayoutView), PrintDocument.PrintSinglePage(GDI2DView) or PrintSinglePage(Project, string, bool), and Bitmap.DrawModel(...). Printing with GDI+ moves into CADability.Forms in CADability 2.0 (issue #412).")]
public class PrintToGDI : IPaintTo3D, QuadTree.IIterateQuadTreeLists
{
diff --git a/tests/CADability.Tests/GdiPrintingTests.cs b/tests/CADability.Tests/GdiPrintingTests.cs
new file mode 100644
index 00000000..0a2ee6a9
--- /dev/null
+++ b/tests/CADability.Tests/GdiPrintingTests.cs
@@ -0,0 +1,54 @@
+#if WINDOWS
+using CADability.Attribute;
+using CADability.Forms;
+using CADability.GeoObject;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System.Drawing;
+
+namespace CADability.Tests
+{
+ ///
+ /// The printing extensions of in CADability.Forms replace the obsolete printing members of the
+ /// kernel (issue #412). In CADability 1.x they forward to the kernel, so they must produce the same output.
+ ///
+ [TestClass]
+ public class GdiPrintingTests
+ {
+ [TestMethod]
+ public void DrawModelRendersLikePrintToGdi()
+ {
+ Project project = Project.CreateSimpleProject();
+ Model model = project.GetActiveModel();
+ Line line = Line.Construct();
+ line.SetTwoPoints(new GeoPoint(10, 10, 0), new GeoPoint(90, 90, 0));
+ model.Add(line);
+ Layer[] layers = project.LayerList.ToArray();
+
+ Bitmap viaExtension = Render((bitmap, projection) => bitmap.DrawModel(model, projection, layers, false, true));
+#pragma warning disable CS0618 // the obsolete kernel implementation as the reference
+ Bitmap viaKernel = Render((bitmap, projection) => new PrintToGDI(bitmap).PrintToBitmap(model, projection, layers, false, true));
+#pragma warning restore CS0618
+
+ int drawn = 0;
+ for (int x = 0; x < viaKernel.Width; x++)
+ for (int y = 0; y < viaKernel.Height; y++)
+ {
+ Color expected = viaKernel.GetPixel(x, y);
+ Assert.AreEqual(expected.ToArgb(), viaExtension.GetPixel(x, y).ToArgb(), $"pixel {x}, {y}");
+ if (expected.ToArgb() != Color.White.ToArgb()) ++drawn;
+ }
+ Assert.IsTrue(drawn > 0, "the line is drawn");
+ }
+
+ private static Bitmap Render(System.Action draw)
+ {
+ Bitmap bitmap = new Bitmap(100, 100);
+ Projection projection = new Projection(Projection.StandardProjection.FromTop);
+ projection.ShowFaces = false;
+ projection.SetPlacement(new Rectangle(0, 0, 100, 100), new BoundingRect(0, 0, 100, 100));
+ draw(bitmap, projection);
+ return bitmap;
+ }
+ }
+}
+#endif