Non-scaling Pen in GDI+

.net, c#, gdi+, pen

Solution

The Pen itself has a Transform attribute. Use that one with the inverse of your global scale-Transform on the graphics object. Set the pen width to a constant of whatever you want.

Also there is a bug in gdi+ making pens of width<1.5 not being able to scale.

Good link: https://web.archive.org/web/20131221083258/http://bobpowell.net/scalepens.aspx

(Also there is a PageUnit attribute on the graphics object with ability to change between pixels, millimeters, etc. Dunno if that could help)

Problem

I need to create a pen which draws with a width of 0.5 mm regardless of the scale of the graphics transformation matrix. Here is what I am doing: Note: The sample code is C++/CLI but answers using C# are welcome. ``` // assume that g is a Graphics object int dpi = g->DpiX; float dotsPerHalfInch = dpi * 0.5; // to extract scale factor from the transformation matrix... // create two points distant one unit apart... array<PointF> ^points = gcnew array<PointF>{ PointF(0.0f, 0.0f), PointF(1.0f, 0.0f) }; // transform them... g->Transform->TransformPoints(points); // get distance after transformation... float dX = points[1].X - points[0].X; float dY = points[1].Y - points[0].Y; float distance = Math::Sqrt(dX * dX + dY * dY); // reverse the effects of any scale factor in graphics transform float penWidth = dotsPerHalfInch / distance; Pen ^halfInchPen = gcnew Pen(Color::Black, penWidth); ``` Doesn't seem to work on screen (96 dpi) ...gives me a pixel wide pen. On the PDF printer (600 dpi) it gives me a pen far more thicker than half an inch. What am I doing wrong? What is the correct way to create a non-scaling pen in GDI?

Original source