aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--doc/ScintillaHistory.html4
-rw-r--r--win32/PlatWin.cxx53
-rw-r--r--win32/PlatWin.h9
-rw-r--r--win32/ScintillaWin.cxx73
4 files changed, 104 insertions, 35 deletions
diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html
index 0c7885d21..ba65ea3e2 100644
--- a/doc/ScintillaHistory.html
+++ b/doc/ScintillaHistory.html
@@ -588,6 +588,10 @@
Fix position of end-of-line annotation when fold display text is visible.
<a href="https://sourceforge.net/p/scintilla/bugs/2320/">Bug #2320</a>.
</li>
+ <li>
+ On Direct2D, support per-monitor text rendering parameters.
+ <a href="https://sourceforge.net/p/scintilla/feature-requests/1432/">Feature #1432</a>.
+ </li>
</ul>
<h3>
<a href="https://www.scintilla.org/scintilla521.zip">Release 5.2.1</a>
diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx
index 3d8595b1d..af1e41b5f 100644
--- a/win32/PlatWin.cxx
+++ b/win32/PlatWin.cxx
@@ -72,8 +72,6 @@ UINT CodePageFromCharSet(CharacterSet characterSet, UINT documentCodePage) noexc
#if defined(USE_D2D)
IDWriteFactory *pIDWriteFactory = nullptr;
ID2D1Factory *pD2DFactory = nullptr;
-IDWriteRenderingParams *defaultRenderingParams = nullptr;
-IDWriteRenderingParams *customClearTypeRenderingParams = nullptr;
D2D1_DRAW_TEXT_OPTIONS d2dDrawTextOptions = D2D1_DRAW_TEXT_OPTIONS_NONE;
static HMODULE hDLLD2D {};
@@ -123,24 +121,6 @@ void LoadD2DOnce() noexcept {
reinterpret_cast<IUnknown**>(&pIDWriteFactory));
}
}
-
- if (pIDWriteFactory) {
- const HRESULT hr = pIDWriteFactory->CreateRenderingParams(&defaultRenderingParams);
- if (SUCCEEDED(hr)) {
- unsigned int clearTypeContrast = 0;
- if (::SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &clearTypeContrast, 0)) {
-
- FLOAT gamma;
- if (clearTypeContrast >= 1000 && clearTypeContrast <= 2200)
- gamma = static_cast<FLOAT>(clearTypeContrast) / 1000.0f;
- else
- gamma = defaultRenderingParams->GetGamma();
-
- pIDWriteFactory->CreateCustomRenderingParams(gamma, defaultRenderingParams->GetEnhancedContrast(), defaultRenderingParams->GetClearTypeLevel(),
- defaultRenderingParams->GetPixelGeometry(), defaultRenderingParams->GetRenderingMode(), &customClearTypeRenderingParams);
- }
- }
- }
}
bool LoadD2D() {
@@ -1294,7 +1274,7 @@ constexpr D2D1_RECT_F RectangleInset(D2D1_RECT_F rect, FLOAT inset) noexcept {
class BlobInline;
-class SurfaceD2D : public Surface {
+class SurfaceD2D : public Surface, public ISetRenderingParams {
SurfaceMode mode;
ID2D1RenderTarget *pRenderTarget = nullptr;
@@ -1304,8 +1284,10 @@ class SurfaceD2D : public Surface {
ID2D1SolidColorBrush *pBrush = nullptr;
- FontQuality fontQuality = FontQuality::QualityMask;
+ static constexpr FontQuality invalidFontQuality = FontQuality::QualityMask;
+ FontQuality fontQuality = invalidFontQuality;
int logPixelsY = USER_DEFAULT_SCREEN_DPI;
+ std::shared_ptr<RenderingParams> renderingParams;
void Clear() noexcept;
void SetFontQuality(FontQuality extraFontFlag);
@@ -1379,6 +1361,8 @@ public:
void PopClip() override;
void FlushCachedState() override;
void FlushDrawing() override;
+
+ void SetRenderingParams(std::shared_ptr<RenderingParams> renderingParams_) override;
};
SurfaceD2D::SurfaceD2D() noexcept {
@@ -1430,7 +1414,7 @@ void SurfaceD2D::Release() noexcept {
}
void SurfaceD2D::SetScale(WindowID wid) noexcept {
- fontQuality = FontQuality::QualityMask;
+ fontQuality = invalidFontQuality;
logPixelsY = DpiForWindow(wid);
}
@@ -1458,7 +1442,9 @@ void SurfaceD2D::Init(SurfaceID sid, WindowID wid) {
}
std::unique_ptr<Surface> SurfaceD2D::AllocatePixMap(int width, int height) {
- return std::make_unique<SurfaceD2D>(pRenderTarget, width, height, mode, logPixelsY);
+ std::unique_ptr<SurfaceD2D> surf = std::make_unique<SurfaceD2D>(pRenderTarget, width, height, mode, logPixelsY);
+ surf->SetRenderingParams(renderingParams);
+ return surf;
}
void SurfaceD2D::SetMode(SurfaceMode mode_) {
@@ -1485,15 +1471,14 @@ void SurfaceD2D::D2DPenColourAlpha(ColourRGBA fore) noexcept {
}
void SurfaceD2D::SetFontQuality(FontQuality extraFontFlag) {
- if (fontQuality != extraFontFlag) {
+ if ((fontQuality != extraFontFlag) && renderingParams) {
fontQuality = extraFontFlag;
const D2D1_TEXT_ANTIALIAS_MODE aaMode = DWriteMapFontQuality(extraFontFlag);
-
- if (aaMode == D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE && customClearTypeRenderingParams)
- pRenderTarget->SetTextRenderingParams(customClearTypeRenderingParams);
- else if (defaultRenderingParams)
- pRenderTarget->SetTextRenderingParams(defaultRenderingParams);
-
+ if (aaMode == D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE && renderingParams->customRenderingParams) {
+ pRenderTarget->SetTextRenderingParams(renderingParams->customRenderingParams.get());
+ } else if (renderingParams->defaultRenderingParams) {
+ pRenderTarget->SetTextRenderingParams(renderingParams->defaultRenderingParams.get());
+ }
pRenderTarget->SetTextAntialiasMode(aaMode);
}
}
@@ -2629,6 +2614,10 @@ void SurfaceD2D::FlushDrawing() {
}
}
+void SurfaceD2D::SetRenderingParams(std::shared_ptr<RenderingParams> renderingParams_) {
+ renderingParams = renderingParams_;
+}
+
#endif
std::unique_ptr<Surface> Surface::Allocate(Technology technology) {
@@ -3863,8 +3852,6 @@ void Platform_Initialise(void *hInstance) noexcept {
void Platform_Finalise(bool fromDllMain) noexcept {
#if defined(USE_D2D)
if (!fromDllMain) {
- ReleaseUnknown(defaultRenderingParams);
- ReleaseUnknown(customClearTypeRenderingParams);
ReleaseUnknown(pIDWriteFactory);
ReleaseUnknown(pD2DFactory);
if (hDLLDWrite) {
diff --git a/win32/PlatWin.h b/win32/PlatWin.h
index 68b5dd9ef..893618b38 100644
--- a/win32/PlatWin.h
+++ b/win32/PlatWin.h
@@ -53,6 +53,15 @@ HCURSOR LoadReverseArrowCursor(UINT dpi) noexcept;
extern bool LoadD2D();
extern ID2D1Factory *pD2DFactory;
extern IDWriteFactory *pIDWriteFactory;
+
+struct RenderingParams {
+ std::unique_ptr<IDWriteRenderingParams, UnknownReleaser> defaultRenderingParams;
+ std::unique_ptr<IDWriteRenderingParams, UnknownReleaser> customRenderingParams;
+};
+
+struct ISetRenderingParams {
+ virtual void SetRenderingParams(std::shared_ptr<RenderingParams> renderingParams_) = 0;
+};
#endif
}
diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx
index 7bb8d43db..52473bfa6 100644
--- a/win32/ScintillaWin.cxx
+++ b/win32/ScintillaWin.cxx
@@ -318,6 +318,9 @@ class ScintillaWin :
#if defined(USE_D2D)
ID2D1RenderTarget *pRenderTarget;
bool renderTargetValid;
+ // rendering parameters for current monitor
+ HMONITOR hCurrentMonitor;
+ std::shared_ptr<RenderingParams> renderingParams;
#endif
explicit ScintillaWin(HWND hwnd);
@@ -330,6 +333,7 @@ class ScintillaWin :
void Finalise() override;
#if defined(USE_D2D)
+ bool UpdateRenderingParams(bool force) noexcept;
void EnsureRenderTarget(HDC hdc);
#endif
void DropRenderTarget() noexcept;
@@ -354,6 +358,8 @@ class ScintillaWin :
Sci::Position TargetAsUTF8(char *text) const;
Sci::Position EncodedFromUTF8(const char *utf8, char *encoded) const;
+ void SetRenderingParams(Surface *psurf) const;
+
bool PaintDC(HDC hdc);
sptr_t WndPaint();
@@ -533,6 +539,7 @@ ScintillaWin::ScintillaWin(HWND hwnd) {
#if defined(USE_D2D)
pRenderTarget = nullptr;
renderTargetValid = true;
+ hCurrentMonitor = {};
#endif
caret.period = ::GetCaretBlinkTime();
@@ -577,6 +584,38 @@ void ScintillaWin::Finalise() {
#if defined(USE_D2D)
+bool ScintillaWin::UpdateRenderingParams(bool force) noexcept {
+ if (!renderingParams) {
+ renderingParams = std::make_shared<RenderingParams>();
+ }
+ HMONITOR monitor = ::MonitorFromWindow(MainHWND(), MONITOR_DEFAULTTONEAREST);
+ if (!force && monitor == hCurrentMonitor && renderingParams->defaultRenderingParams) {
+ return false;
+ }
+
+ IDWriteRenderingParams *monitorRenderingParams = nullptr;
+ IDWriteRenderingParams *customClearTypeRenderingParams = nullptr;
+ const HRESULT hr = pIDWriteFactory->CreateMonitorRenderingParams(monitor, &monitorRenderingParams);
+ UINT clearTypeContrast = 0;
+ if (SUCCEEDED(hr) && ::SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &clearTypeContrast, 0) != 0) {
+ if (clearTypeContrast >= 1000 && clearTypeContrast <= 2200) {
+ const FLOAT gamma = static_cast<FLOAT>(clearTypeContrast) / 1000.0f;
+ pIDWriteFactory->CreateCustomRenderingParams(gamma,
+ monitorRenderingParams->GetEnhancedContrast(),
+ monitorRenderingParams->GetClearTypeLevel(),
+ monitorRenderingParams->GetPixelGeometry(),
+ monitorRenderingParams->GetRenderingMode(),
+ &customClearTypeRenderingParams);
+ }
+ }
+
+ hCurrentMonitor = monitor;
+ renderingParams->defaultRenderingParams.reset(monitorRenderingParams);
+ renderingParams->customRenderingParams.reset(customClearTypeRenderingParams);
+ return true;
+}
+
+
void ScintillaWin::EnsureRenderTarget(HDC hdc) {
if (!renderTargetValid) {
DropRenderTarget();
@@ -646,7 +685,6 @@ void ScintillaWin::EnsureRenderTarget(HDC hdc) {
}
#endif
-
void ScintillaWin::DropRenderTarget() noexcept {
#if defined(USE_D2D)
ReleaseUnknown(pRenderTarget);
@@ -873,6 +911,17 @@ Sci::Position ScintillaWin::EncodedFromUTF8(const char *utf8, char *encoded) con
}
}
+void ScintillaWin::SetRenderingParams([[maybe_unused]] Surface *psurf) const {
+#if defined(USE_D2D)
+ if (psurf) {
+ ISetRenderingParams *setDrawingParams = dynamic_cast<ISetRenderingParams *>(psurf);
+ if (setDrawingParams) {
+ setDrawingParams->SetRenderingParams(renderingParams);
+ }
+ }
+#endif
+}
+
bool ScintillaWin::PaintDC(HDC hdc) {
if (technology == Technology::Default) {
AutoSurface surfaceWindow(hdc, this);
@@ -886,6 +935,7 @@ bool ScintillaWin::PaintDC(HDC hdc) {
if (pRenderTarget) {
AutoSurface surfaceWindow(pRenderTarget, this);
if (surfaceWindow) {
+ SetRenderingParams(surfaceWindow);
pRenderTarget->BeginDraw();
Paint(surfaceWindow, rcPaint);
surfaceWindow->Release();
@@ -1824,9 +1874,11 @@ sptr_t ScintillaWin::SciMessage(Message iMessage, uptr_t wParam, sptr_t lParam)
if (technology != technologyNew) {
if (technologyNew > Technology::Default) {
#if defined(USE_D2D)
- if (!LoadD2D())
+ if (!LoadD2D()) {
// Failed to load Direct2D or DirectWrite so no effect
return 0;
+ }
+ UpdateRenderingParams(true);
#else
return 0;
#endif
@@ -1952,6 +2004,12 @@ sptr_t ScintillaWin::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
case WM_SETTINGCHANGE:
//Platform::DebugPrintf("Setting Changed\n");
+#if defined(USE_D2D)
+ if (technology != Technology::Default) {
+ UpdateRenderingParams(true);
+ Redraw();
+ }
+#endif
UpdateBaseElements();
InvalidateStyleData();
// Get Intellimouse scroll line parameters
@@ -2016,7 +2074,17 @@ sptr_t ScintillaWin::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
case WM_NCLBUTTONDOWN:
case WM_SYSCOMMAND:
case WM_WINDOWPOSCHANGING:
+ return ::DefWindowProc(MainHWND(), msg, wParam, lParam);
+
case WM_WINDOWPOSCHANGED:
+#if defined(USE_D2D)
+ if (technology != Technology::Default) {
+ if (UpdateRenderingParams(false)) {
+ DropGraphics();
+ Redraw();
+ }
+ }
+#endif
return ::DefWindowProc(MainHWND(), msg, wParam, lParam);
case WM_GETTEXTLENGTH:
@@ -3528,6 +3596,7 @@ LRESULT PASCAL ScintillaWin::CTWndProc(
#endif
}
surfaceWindow->SetMode(sciThis->CurrentSurfaceMode());
+ sciThis->SetRenderingParams(surfaceWindow.get());
sciThis->ct.PaintCT(surfaceWindow.get());
#if defined(USE_D2D)
if (pCTRenderTarget)