diff options
author | Neil <nyamatongwe@gmail.com> | 2025-02-11 19:13:59 +1100 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2025-02-11 19:13:59 +1100 |
commit | 876871f0391de2730ac7562491d5cffb5fdd9ed1 (patch) | |
tree | 3c2e1d6572b56f8e11bdb4f16da284cd3e1e78a5 | |
parent | f2e9767e7aa2f3e012f46bf1c5f8b41872051bf0 (diff) | |
download | scintilla-mirror-876871f0391de2730ac7562491d5cffb5fdd9ed1.tar.gz |
Update Direct2D and DirectWrite functions and types to Direct2D 1.1.
-rw-r--r-- | win32/PlatWin.cxx | 11 | ||||
-rw-r--r-- | win32/PlatWin.h | 10 | ||||
-rw-r--r-- | win32/ScintillaWin.cxx | 26 | ||||
-rw-r--r-- | win32/WinTypes.h | 18 |
4 files changed, 51 insertions, 14 deletions
diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx index f593063f5..4f54f4496 100644 --- a/win32/PlatWin.cxx +++ b/win32/PlatWin.cxx @@ -72,8 +72,8 @@ namespace Scintilla::Internal { UINT CodePageFromCharSet(CharacterSet characterSet, UINT documentCodePage) noexcept; #if defined(USE_D2D) -IDWriteFactory *pIDWriteFactory = nullptr; -ID2D1Factory *pD2DFactory = nullptr; +IDWriteFactory1 *pIDWriteFactory = nullptr; +ID2D1Factory1 *pD2DFactory = nullptr; D2D1_DRAW_TEXT_OPTIONS d2dDrawTextOptions = D2D1_DRAW_TEXT_OPTIONS_NONE; namespace { @@ -103,10 +103,11 @@ void LoadD2DOnce() noexcept { hDLLD2D = ::LoadLibraryEx(TEXT("D2D1.DLL"), 0, loadLibraryFlags); D2D1CFSig fnD2DCF = DLLFunction<D2D1CFSig>(hDLLD2D, "D2D1CreateFactory"); if (fnD2DCF) { + const D2D1_FACTORY_OPTIONS options {}; // A multi threaded factory in case Scintilla is used with multiple GUI threads fnD2DCF(D2D1_FACTORY_TYPE_MULTI_THREADED, - __uuidof(ID2D1Factory), - nullptr, + __uuidof(ID2D1Factory1), + &options, reinterpret_cast<IUnknown**>(&pD2DFactory)); } hDLLDWrite = ::LoadLibraryEx(TEXT("DWRITE.DLL"), 0, loadLibraryFlags); @@ -123,7 +124,7 @@ void LoadD2DOnce() noexcept { d2dDrawTextOptions = static_cast<D2D1_DRAW_TEXT_OPTIONS>(0x00000004); } else { fnDWCF(DWRITE_FACTORY_TYPE_SHARED, - __uuidof(IDWriteFactory), + __uuidof(IDWriteFactory1), reinterpret_cast<IUnknown**>(&pIDWriteFactory)); } } diff --git a/win32/PlatWin.h b/win32/PlatWin.h index 8a651dd74..f24689799 100644 --- a/win32/PlatWin.h +++ b/win32/PlatWin.h @@ -68,17 +68,19 @@ public: #if defined(USE_D2D) extern bool LoadD2D() noexcept; -extern ID2D1Factory *pD2DFactory; -extern IDWriteFactory *pIDWriteFactory; +extern ID2D1Factory1 *pD2DFactory; +extern IDWriteFactory1 *pIDWriteFactory; using DCRenderTarget = std::unique_ptr<ID2D1DCRenderTarget, UnknownReleaser>; using HwndRenderTarget = std::unique_ptr<ID2D1HwndRenderTarget, UnknownReleaser>; HRESULT CreateDCRenderTarget(const D2D1_RENDER_TARGET_PROPERTIES *renderTargetProperties, DCRenderTarget &dcRT) noexcept; +using WriteRenderingParams = std::unique_ptr<IDWriteRenderingParams1, UnknownReleaser>; + struct RenderingParams { - std::unique_ptr<IDWriteRenderingParams, UnknownReleaser> defaultRenderingParams; - std::unique_ptr<IDWriteRenderingParams, UnknownReleaser> customRenderingParams; + WriteRenderingParams defaultRenderingParams; + WriteRenderingParams customRenderingParams; }; struct ISetRenderingParams { diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index b0eaf979d..4411f54ef 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -98,6 +98,11 @@ #include "HanjaDic.h" #include "ScintillaWin.h" +// __uuidof is a Microsoft extension but makes COM code neater, so disable warning +#if defined(__clang__) +#pragma clang diagnostic ignored "-Wlanguage-extension-token" +#endif + namespace { // Two idle messages SC_WIN_IDLE and SC_WORK_IDLE. @@ -722,15 +727,26 @@ bool ScintillaWin::UpdateRenderingParams(bool force) noexcept { return false; } - IDWriteRenderingParams *monitorRenderingParams = nullptr; - IDWriteRenderingParams *customClearTypeRenderingParams = nullptr; - const HRESULT hr = pIDWriteFactory->CreateMonitorRenderingParams(monitor, &monitorRenderingParams); + IDWriteRenderingParams *mrpTemp{}; + HRESULT hr = pIDWriteFactory->CreateMonitorRenderingParams(monitor, &mrpTemp); + if (FAILED(hr)) { + return false; + } + std::unique_ptr<IDWriteRenderingParams, UnknownReleaser> upMrp(mrpTemp); + + // Cast to IDWriteRenderingParams1 so can call GetGrayscaleEnhancedContrast + WriteRenderingParams monitorRenderingParams{}; + hr = UniquePtrFromQI(upMrp.get(), __uuidof(IDWriteRenderingParams1), monitorRenderingParams); + + IDWriteRenderingParams1 *customClearTypeRenderingParams{}; UINT clearTypeContrast = 0; - if (SUCCEEDED(hr) && ::SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &clearTypeContrast, 0) != 0) { + if (SUCCEEDED(hr) && monitorRenderingParams && + ::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->GetGrayscaleEnhancedContrast(), monitorRenderingParams->GetClearTypeLevel(), monitorRenderingParams->GetPixelGeometry(), monitorRenderingParams->GetRenderingMode(), @@ -740,7 +756,7 @@ bool ScintillaWin::UpdateRenderingParams(bool force) noexcept { hCurrentMonitor = monitor; deviceScaleFactor = Internal::GetDeviceScaleFactorWhenGdiScalingActive(hRootWnd); - renderingParams->defaultRenderingParams.reset(monitorRenderingParams); + renderingParams->defaultRenderingParams = std::move(monitorRenderingParams); renderingParams->customRenderingParams.reset(customClearTypeRenderingParams); return true; } diff --git a/win32/WinTypes.h b/win32/WinTypes.h index 9badd70a8..9c930bb7c 100644 --- a/win32/WinTypes.h +++ b/win32/WinTypes.h @@ -38,6 +38,24 @@ struct UnknownReleaser { } }; +// Wrap COM IUnknown::QueryInterface to produce std::unique_ptr objects to help +// ensure safe reference counting. +template<typename T> +inline HRESULT UniquePtrFromQI(IUnknown *source, REFIID riid, std::unique_ptr<T, UnknownReleaser> &destination) noexcept { + T *ptr{}; + HRESULT hr = E_FAIL; + try { + hr = source->QueryInterface(riid, reinterpret_cast<void **>(&ptr)); + } catch (...) { + // Shouldn't have exceptions from QueryInterface but not marked noexcept + } + if (SUCCEEDED(hr)) { + destination.reset(ptr); + } else { + destination.reset(); + } + return hr; +} /// Find a function in a DLL and convert to a function pointer. /// This avoids undefined and conditionally defined behaviour. |