diff options
| -rw-r--r-- | doc/ScintillaHistory.html | 4 | ||||
| -rw-r--r-- | win32/PlatWin.cxx | 53 | ||||
| -rw-r--r-- | win32/PlatWin.h | 9 | ||||
| -rw-r--r-- | win32/ScintillaWin.cxx | 73 | 
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)  | 
