Can someone explain how GDI+ coordinates work?
I’m migrating a large MFC/C++ gdi-drawing program to use gdi+. The simplest way to get going was to create a Gdiplus::graphics object from a DC I’d already initialised, then move each element of drawing across in turn - taking care not to switch between DC & gdi++. Almost everything worked instantly.
So: mentally, I think in gdi. Migrating to gdi+ with minimal changes works, except for one thing...
In gdi+ line widths aren’t constant. Defining a pen, with a certain width results in a different number of pixels depending on where on the screen it’s drawn. With GDI, whatever units/scaling was declared, defining a pen always resulted in a constant pixel width. I’ve stripped out all mapping mode / DC initialisation code done prior to declaring the Gdiplus::graphics, but the basic issue is still there.
Clearly, I’m missing something.
Example code, stripping out all DC initialisation...
OnPaint >> DoDraw(CDC* pDC, CRect rPaint)
Graphics graphics(pDC->m_hDC);
Gdiplus::REAL sc = 1.0;
Gdiplus::REAL nPenWidth = sc * 5;
Gdiplus::Pen p(color, nPenWidth);
for (int r = 0; r < 20; r++)
{
Gdiplus::REAL y = 0.0 + (r *40);
g->DrawLine(&p, 20.0, y, 120.0, y);
}
This draws a column of 20 short horizontal lines, all using the same pen. On my 96dpi monitor some are 3 pixels wide, some are 4 pixels wide. Why aren’t these lines the same width?
What I have tried:
Replacing the initialization of “sc” prior to defining the pen improves the consistency, but doesn’t completely fix things (so maybe its a red herring).
// set Points as units -
graphics.SetPageUnit(Gdiplus::UnitPoint);
Gdiplus::REAL dpiX = graphics.GetDpiX();
Gdiplus::REAL sc = 72.0 / dpiX;
graphics.SetPageScale(sc);