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?
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With