[bugs:#2505] Blurry text in autocompletion lists with DirectWrite in a GDI scaled application
Status: open
Group: Bug
Labels: Scintilla Windows
Created: Tue Mar 31, 2026 03:16 PM UTC by Markus Nißl
Last Updated: Tue Mar 31, 2026 03:16 PM UTC
Owner: nobody
Since version 5.5.6, autocompletion lists are drawn using DirectWrite if the document is drawn with DirectWrite.
In a GDI scaled application using Scintilla with DirectWrite, text in autocompletion lists appears blurry. The following patch to ListBox.cxx fixes this.
The taken approach is similar to the one in #2344 DirectWrite rendering looks blurry with DPI unaware apps
--- scintilla5.6.1\win32\ListBox.cxx 2026-03-27 13:02:26.002174200 +0100
+++ myScintilla\win32\ListBox.cxx 2026-03-31 17:09:38.505640600 +0200
@@ -175,6 +175,10 @@ class ListBoxX : public ListBox {
MouseWheelDelta wheelDelta;
ListOptions options;
DWORD frameStyle = WS_THICKFRAME;
+ float deviceScaleFactor = 1.f;
+ [[nodiscard]] int GetFirstIntegralMultipleDeviceScaleFactor() const noexcept {
+ return static_cast<int>(std::ceil(deviceScaleFactor));
+ }
LBGraphics graphics;
@@ -265,6 +269,9 @@ void ListBoxX::Create(Window &parent_, i
this);
dpi = DpiForWindow(hwndParent);
+ if (technology != Technology::Default) {
+ deviceScaleFactor = Internal::GetDeviceScaleFactorWhenGdiScalingActive(hwndParent);
+ }
POINT locationw = POINTFromPoint(location);
::MapWindowPoints(hwndParent, {}, &locationw, 1);
location = PointFromPOINT(locationw);
@@ -423,7 +430,8 @@ void ListBoxX::Draw(DRAWITEMSTRUCT *pDra
#endif
const PRectangle rcItemBase = PRectangleFromRECT(pDrawItem->rcItem);
- const PRectangle rcItem(0, 0, rcItemBase.Width(), rcItemBase.Height());
+ const int integralDeviceScaleFactor = GetFirstIntegralMultipleDeviceScaleFactor();
+ const PRectangle rcItem(0, 0, rcItemBase.Width() * integralDeviceScaleFactor, rcItemBase.Height() * integralDeviceScaleFactor);
PRectangle rcBox = rcItem;
rcBox.left += TextOffset();
ColourRGBA colourFore;
@@ -458,6 +466,7 @@ void ListBoxX::Draw(DRAWITEMSTRUCT *pDra
PRectangle rcImage = rcItem;
rcImage.left = left;
rcImage.right = rcImage.left + images.GetWidth();
+ rcImage.bottom = rcImage.top + rcItemBase.Height();
graphics.pixmapLine->DrawRGBAImage(rcImage,
pimage->GetWidth(), pimage->GetHeight(), pimage->Pixels());
}
@@ -473,7 +482,11 @@ void ListBoxX::Draw(DRAWITEMSTRUCT *pDra
// Blit from hMemDC to hDC
const SIZE extent = SizeOfRect(pDrawItem->rcItem);
- ::BitBlt(pDrawItem->hDC, pDrawItem->rcItem.left, pDrawItem->rcItem.top, extent.cx, extent.cy, graphics.bm.DC(), 0, 0, SRCCOPY);
+ if (integralDeviceScaleFactor == 1) {
+ ::BitBlt(pDrawItem->hDC, pDrawItem->rcItem.left, pDrawItem->rcItem.top, extent.cx, extent.cy, graphics.bm.DC(), 0, 0, SRCCOPY);
+ } else {
+ ::StretchBlt(pDrawItem->hDC, pDrawItem->rcItem.left, pDrawItem->rcItem.top, extent.cx, extent.cy, graphics.bm.DC(), 0, 0, extent.cx * integralDeviceScaleFactor, extent.cy * integralDeviceScaleFactor, SRCCOPY);
+ }
}
void ListBoxX::AppendListItem(const char *text, const char *numword) {
@@ -748,7 +761,8 @@ void ListBoxX::CentreItem(int n) {
}
void ListBoxX::AllocateBitMap() {
- const SIZE extent { GetClientExtent().x, ItemHeight() };
+ const int integralDeviceScaleFactor = GetFirstIntegralMultipleDeviceScaleFactor();
+ const SIZE extent { GetClientExtent().x * integralDeviceScaleFactor, ItemHeight() * integralDeviceScaleFactor };
graphics.bm.Create({}, extent.cx, -extent.cy, nullptr);
if (!graphics.bm) {
@@ -765,9 +779,12 @@ void ListBoxX::AllocateBitMap() {
return;
}
+ const FLOAT dpiTarget = dpiDefault * static_cast<float>(integralDeviceScaleFactor);
+
const D2D1_RENDER_TARGET_PROPERTIES drtp = D2D1::RenderTargetProperties(
D2D1_RENDER_TARGET_TYPE_DEFAULT,
- { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED });
+ { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED },
+ dpiTarget, dpiTarget);
HRESULT hr = CreateDCRenderTarget(&drtp, graphics.pBMDCTarget);
if (FAILED(hr) || !graphics.pBMDCTarget) {
Sent from sourceforge.net because scintill...@googlegroups.com is subscribed to https://sourceforge.net/p/scintilla/bugs/
To unsubscribe from further messages, a project admin can change settings at https://sourceforge.net/p/scintilla/admin/bugs/options. Or, if this is a mailing list, you can unsubscribe from the mailing list.