aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2025-02-11 19:13:59 +1100
committerNeil <nyamatongwe@gmail.com>2025-02-11 19:13:59 +1100
commit876871f0391de2730ac7562491d5cffb5fdd9ed1 (patch)
tree3c2e1d6572b56f8e11bdb4f16da284cd3e1e78a5
parentf2e9767e7aa2f3e012f46bf1c5f8b41872051bf0 (diff)
downloadscintilla-mirror-876871f0391de2730ac7562491d5cffb5fdd9ed1.tar.gz
Update Direct2D and DirectWrite functions and types to Direct2D 1.1.
-rw-r--r--win32/PlatWin.cxx11
-rw-r--r--win32/PlatWin.h10
-rw-r--r--win32/ScintillaWin.cxx26
-rw-r--r--win32/WinTypes.h18
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.