When using the Direct2D renderer for wxDCs (under a HiPDI environment), font drawing is half the size it should be if using a non-window based wxDC. In other words, Direct2D with wxPaint looks OK, but if you use Direct2D with a wxMemoryDC then the font is tiny. Interestingly, it seems to only be a font issue--shape drawing is fine.
To Reproduce
On a HiDPI Windows system:
Note how the bitmap saved when Direct2D was in use has its text half the size as the GDI+ image. If you try this with other screens the problem doesn't happen with shapes and whatnot; it appears to be a font size issue.
Digging into the code, I think it has do with the wxGraphicsContext created from m_renderer->CreateContext(). If the wxDC passed into this has a window related to it (e.g., a wxPaintDC), then the wxGraphicsContext will be aware of the DPI. However, if a wxMemoryDC is passed, then it doesn't know what the DPI is and falls back to the default 96. I can see that the context created from a wxMemoryDC reports 96 when I call GetDPI(). However, I get 192 when I call GetDPI() with the context created from a wxPaintDC. I'm guessing this is the root cause.
Platform and version information
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you are subscribed to this thread.![]()
creataion of wxGraphicsFont for d2d
// src/msw/graphicsd2d.cpp:5112 wxGraphicsFont wxD2DRenderer::CreateFont( double sizeInPixels, const wxString& facename, int flags, const wxColour& col) { // Use the same DPI as wxFont will use in SetPixelSize, so these cancel // each other out and we are left with the actual pixel size. ScreenHDC hdc; wxRealPoint dpi(::GetDeviceCaps(hdc, LOGPIXELSX), ::GetDeviceCaps(hdc, LOGPIXELSY)); return CreateFontAtDPI( wxFontInfo(wxSize(sizeInPixels, sizeInPixels)).AllFlags(flags).FaceName(facename), dpi, col); }
so... when dpi is not specific by user, dpi is set using screendc.
in same process on GDI+
// src/msw/graphics.cpp:2858 wxGraphicsFont wxGDIPlusRenderer::CreateFont( const wxFont &font, const wxColour &col ) { return CreateFontAtDPI(font, wxRealPoint(), col); }
so I suggest
wxGraphicsFont wxD2DRenderer::CreateFont( double sizeInPixels, const wxString& facename, int flags, const wxColour& col) { return CreateFontAtDPI( wxFontInfo(wxSize(sizeInPixels, sizeInPixels)).AllFlags(flags).FaceName(facename), wxRealPoint(), col); }
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you are subscribed to this thread.![]()
No, didn't seem to help. wxGraphicsContext::CreateFont (graphicscmn.cpp, line 952) still relies on GetDPI, which incorrectly reports 96 (not 192). The lack of a window in the graphics context causes GetDPI to be problem.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you are subscribed to this thread.![]()
As a workaround/fix, you can associate the window with the wxMemoryDC. In the drawing sample: mdc.GetImpl()->SetWindow(this);
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you are subscribed to this thread.![]()
mdc.GetImpl()->SetWindow(this);
That totally works! Thank you!
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you are subscribed to this thread.![]()
I don't see any differences in the text size between the 3 bitmaps saved while running with 200% DPI scaling, see:
I do see that the text is smaller than the much larger (and overlapping because of it...) text shown on screen. But normally I would say that this ought to be fixed with
diff --git a/samples/drawing/drawing.cpp b/samples/drawing/drawing.cpp index 55e8e62c52..717f880560 100644 --- a/samples/drawing/drawing.cpp +++ b/samples/drawing/drawing.cpp @@ -2535,7 +2535,8 @@ void MyFrame::OnSave(wxCommandEvent& WXUNUSED(event)) else #endif // wxUSE_POSTSCRIPT { - wxBitmap bmp(width, height); + wxBitmap bmp; + bmp.CreateWithDIPSize(wxSize(width, height), GetDPIScaleFactor()); wxMemoryDC mdc(bmp); mdc.SetBackground(*wxWHITE_BRUSH); mdc.Clear();
(the use of DIP size is due to the fact that nothing is being scaled by DPI in this sample right now, so all pixels are actually DPI-independent in it under MSW) but this doesn't work neither right now because the bitmap scale factor is ignored by wxMemoryDC under MSW. I've tried fixing this in #22234 and with it the saved bitmap looks roughly like this in all 3 cases:
which is ugly but corresponds to the picture actually shown on the screen.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
I don't see any differences in the text size between the 3 bitmaps saved while running with 200% DPI scaling
Correction: as discussed in #22234, I do see the problem when actually running in 200% DPI and not just moving the window to a monitor using 200% DPI (while the main display still uses 100%).
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Verified in my personal project as well. Thanks for the fix!
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
> + wxBitmap bmp; > + bmp.CreateWithDIPSize(wxSize(width, height), GetDPIScaleFactor());
Sorry to drop on this one, but if this is the solution, why not call it in the c-tor? (wxBitmap(width, height))
This single change (wrong font size using wxMemoryDC) caused me hours of work...
My only solution at the time was to drop wxMemoryDC and use wxClientDC.
Had I known this workaround, I would have used it...
--
You received this message because you are subscribed to the Google Groups "wx-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wx-dev+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/wx-dev/wxWidgets/wxWidgets/issues/22130/1100171515%40github.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/wx-dev/CAOpAFwWXjvWOW5hPSNWAVfgVfMx%3DyUXz-SKf3HchamO4HjWH_Q%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/wx-dev/11b5235f-fcef-c4c8-2438-ea77b7fc947b%40gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/wx-dev/CAOpAFwVq6sTW_LA5pzgeLNxzr4ryiJTbQCYKXLd1HLF68VxzKw%40mail.gmail.com.