diff options
author | Neil <nyamatongwe@gmail.com> | 2025-02-12 13:19:09 +1100 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2025-02-12 13:19:09 +1100 |
commit | 1ff212a46192cb86fcb6451848b200898a28f6ff (patch) | |
tree | d3083f62f7c814c28fa73a57c3f2465e80259ab4 | |
parent | 876871f0391de2730ac7562491d5cffb5fdd9ed1 (diff) | |
download | scintilla-mirror-1ff212a46192cb86fcb6451848b200898a28f6ff.tar.gz |
Implement Direct2D/DirectWrite 1.1. Add SC_TECHNOLOGY_DIRECT_WRITE_1 to use an
explicit swap chain and ID2D1DeviceContext.
Stop supporting DirectWrite on Windows Vista.
-rw-r--r-- | doc/ScintillaHistory.html | 6 | ||||
-rw-r--r-- | include/Scintilla.h | 1 | ||||
-rw-r--r-- | include/Scintilla.iface | 1 | ||||
-rw-r--r-- | include/ScintillaTypes.h | 1 | ||||
-rw-r--r-- | scripts/HeaderOrder.txt | 1 | ||||
-rw-r--r-- | win32/PlatWin.cxx | 78 | ||||
-rw-r--r-- | win32/PlatWin.h | 5 | ||||
-rw-r--r-- | win32/ScintillaWin.cxx | 303 |
8 files changed, 347 insertions, 49 deletions
diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index 5bcc93dfb..c9f423488 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -605,6 +605,12 @@ Serialize selection type and ranges with SCI_GETSELECTIONSERIALIZED and SCI_SETSELECTIONSERIALIZED. </li> <li> + For Win32, update Direct2D and DirectWrite interfaces used to 1.1 and add a lower-level approach to calling DirectWrite 1.1 + by specifying SC_TECHNOLOGY_DIRECT_WRITE_1. + Since Windows Vista does not support these API versions, Scintilla o longer supports DirectWrite on Windows Vista and will + fall back to using GDI. + </li> + <li> Fix segmentation of long lexemes to avoid breaking before modifiers like accents that must be drawn with their base letters. </li> <li> diff --git a/include/Scintilla.h b/include/Scintilla.h index 4de92e1b8..c976af1ea 100644 --- a/include/Scintilla.h +++ b/include/Scintilla.h @@ -1127,6 +1127,7 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP #define SC_TECHNOLOGY_DIRECTWRITE 1 #define SC_TECHNOLOGY_DIRECTWRITERETAIN 2 #define SC_TECHNOLOGY_DIRECTWRITEDC 3 +#define SC_TECHNOLOGY_DIRECT_WRITE_1 4 #define SCI_SETTECHNOLOGY 2630 #define SCI_GETTECHNOLOGY 2631 #define SCI_CREATELOADER 2632 diff --git a/include/Scintilla.iface b/include/Scintilla.iface index 4ce9d5703..f32148b69 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -3092,6 +3092,7 @@ val SC_TECHNOLOGY_DEFAULT=0 val SC_TECHNOLOGY_DIRECTWRITE=1 val SC_TECHNOLOGY_DIRECTWRITERETAIN=2 val SC_TECHNOLOGY_DIRECTWRITEDC=3 +val SC_TECHNOLOGY_DIRECT_WRITE_1=4 ali SC_TECHNOLOGY_DIRECTWRITE=DIRECT_WRITE ali SC_TECHNOLOGY_DIRECTWRITERETAIN=DIRECT_WRITE_RETAIN diff --git a/include/ScintillaTypes.h b/include/ScintillaTypes.h index af726b2ab..71e2be398 100644 --- a/include/ScintillaTypes.h +++ b/include/ScintillaTypes.h @@ -515,6 +515,7 @@ enum class Technology { DirectWrite = 1, DirectWriteRetain = 2, DirectWriteDC = 3, + DirectWrite1 = 4, }; enum class LineEndType { diff --git a/scripts/HeaderOrder.txt b/scripts/HeaderOrder.txt index 8ac8c3c48..eb0a16dd1 100644 --- a/scripts/HeaderOrder.txt +++ b/scripts/HeaderOrder.txt @@ -81,6 +81,7 @@ #include <zmouse.h> #include <ole2.h> #include <d2d1_1.h> +#include <d3d11_1.h> #include <dwrite_1.h> // Cocoa headers diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx index 4f54f4496..79a5f151f 100644 --- a/win32/PlatWin.cxx +++ b/win32/PlatWin.cxx @@ -45,6 +45,7 @@ #if defined(USE_D2D) #include <d2d1_1.h> +#include <d3d11_1.h> #include <dwrite_1.h> #endif @@ -79,8 +80,11 @@ D2D1_DRAW_TEXT_OPTIONS d2dDrawTextOptions = D2D1_DRAW_TEXT_OPTIONS_NONE; namespace { HMODULE hDLLD2D{}; +HMODULE hDLLD3D{}; HMODULE hDLLDWrite{}; +PFN_D3D11_CREATE_DEVICE fnDCD {}; + } void LoadD2DOnce() noexcept { @@ -128,6 +132,77 @@ void LoadD2DOnce() noexcept { reinterpret_cast<IUnknown**>(&pIDWriteFactory)); } } + + hDLLD3D = ::LoadLibraryEx(TEXT("D3D11.DLL"), 0, loadLibraryFlags); + if (!hDLLD3D) { + Platform::DebugPrintf("Direct3D not loaded\n"); + } + fnDCD = DLLFunction<PFN_D3D11_CREATE_DEVICE>(hDLLD3D, "D3D11CreateDevice"); + if (!fnDCD) { + Platform::DebugPrintf("Direct3D does not have D3D11CreateDevice\n"); + } +} + +HRESULT CreateD3D(D3D11Device &device, D3D11DeviceContext &context) noexcept { + device.reset(); + context.reset(); + if (!fnDCD) { + return E_FAIL; + } + + const D3D_FEATURE_LEVEL featureLevels[] = { + D3D_FEATURE_LEVEL_11_1, + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, + D3D_FEATURE_LEVEL_9_3, + D3D_FEATURE_LEVEL_9_2, + D3D_FEATURE_LEVEL_9_1 + }; + + // Create device and context. + // Try for a hardware device but, if that fails, fall back to the Warp software rasterizer. + D3D_FEATURE_LEVEL returnedFeatureLevel{}; + ID3D11Device *pDevice{}; + ID3D11DeviceContext *pContext{}; + HRESULT hr = S_OK; + const D3D_DRIVER_TYPE typesToTry[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP }; + for (const D3D_DRIVER_TYPE type : typesToTry) { + hr = fnDCD(nullptr, + type, + 0, + D3D11_CREATE_DEVICE_BGRA_SUPPORT, + featureLevels, + ARRAYSIZE(featureLevels), + D3D11_SDK_VERSION, + &pDevice, + &returnedFeatureLevel, + &pContext); + if (SUCCEEDED(hr)) + break; + } + if (FAILED(hr)) { + Platform::DebugPrintf("Failed to create D3D11 device and context 0x%lx\n", hr); + return hr; + } + + // Ensure released + std::unique_ptr<ID3D11Device, UnknownReleaser> upDevice(pDevice); + std::unique_ptr<ID3D11DeviceContext, UnknownReleaser> upContext(pContext); + + // Convert from D3D11 to D3D11.1 + hr = UniquePtrFromQI(upDevice.get(), __uuidof(ID3D11Device1), device); + if (FAILED(hr)) { + Platform::DebugPrintf("Failed to create D3D11.1 device 0x%lx\n", hr); + return hr; + } + hr = UniquePtrFromQI(upContext.get(), __uuidof(ID3D11DeviceContext1), context); + if (FAILED(hr)) { + // Either both device and context or neither + device.reset(); + Platform::DebugPrintf("Failed to create D3D11.1 device context 0x%lx\n", hr); + } + return hr; } bool LoadD2D() noexcept { @@ -4112,7 +4187,7 @@ void Platform::DebugDisplay(const char *s) noexcept { ::OutputDebugStringA(s); } -//#define TRACE +#define TRACE #ifdef TRACE void Platform::DebugPrintf(const char *format, ...) noexcept { @@ -4179,6 +4254,7 @@ void Platform_Finalise(bool fromDllMain) noexcept { ReleaseUnknown(pIDWriteFactory); ReleaseUnknown(pD2DFactory); ReleaseLibrary(hDLLDWrite); + ReleaseLibrary(hDLLD3D); ReleaseLibrary(hDLLD2D); #endif ReleaseLibrary(hDLLShcore); diff --git a/win32/PlatWin.h b/win32/PlatWin.h index f24689799..1b5b7b1b9 100644 --- a/win32/PlatWin.h +++ b/win32/PlatWin.h @@ -73,8 +73,13 @@ extern IDWriteFactory1 *pIDWriteFactory; using DCRenderTarget = std::unique_ptr<ID2D1DCRenderTarget, UnknownReleaser>; using HwndRenderTarget = std::unique_ptr<ID2D1HwndRenderTarget, UnknownReleaser>; +using D2DeviceContext = std::unique_ptr<ID2D1DeviceContext, UnknownReleaser>; + +using D3D11Device = std::unique_ptr<ID3D11Device1, UnknownReleaser>; +using D3D11DeviceContext = std::unique_ptr<ID3D11DeviceContext1, UnknownReleaser>; HRESULT CreateDCRenderTarget(const D2D1_RENDER_TARGET_PROPERTIES *renderTargetProperties, DCRenderTarget &dcRT) noexcept; +extern HRESULT CreateD3D(D3D11Device &device, D3D11DeviceContext &context) noexcept; using WriteRenderingParams = std::unique_ptr<IDWriteRenderingParams1, UnknownReleaser>; diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index 4411f54ef..dcfcde2f6 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -49,6 +49,7 @@ #if defined(USE_D2D) #include <d2d1_1.h> +#include <d3d11_1.h> #include <dwrite_1.h> #endif @@ -372,20 +373,75 @@ namespace Scintilla::Internal { struct RenderTargets { HwndRenderTarget pHwndRT; DCRenderTarget pDCRT; + D2DeviceContext pDeviceContext; bool valid = true; ID2D1RenderTarget *RenderTarget() const noexcept { if (pHwndRT) return pHwndRT.get(); if (pDCRT) return pDCRT.get(); + if (pDeviceContext) + return pDeviceContext.get(); return nullptr; } void Release() noexcept { pHwndRT.reset(); pDCRT.reset(); + pDeviceContext.reset(); } }; +using D2D1Device = std::unique_ptr<ID2D1Device, UnknownReleaser>; +using DXGIDevice = std::unique_ptr<IDXGIDevice, UnknownReleaser>; + +// These resources are device-dependent but not window-dependent +struct DirectDevice { + D3D11Device pDirect3DDevice; + D3D11DeviceContext pDirect3DContext; + D2D1Device pDirect2DDevice; + DXGIDevice pDXGIDevice; + + void Release() noexcept; + HRESULT CreateDevice() noexcept; +}; + +void DirectDevice::Release() noexcept { + pDirect3DDevice.reset(); + pDirect3DContext.reset(); + pDirect2DDevice.reset(); + pDXGIDevice.reset(); +} + +HRESULT DirectDevice::CreateDevice() noexcept { + if (pDirect2DDevice) { // Must be released before creation + return E_FAIL; + } + + HRESULT hr = CreateD3D(pDirect3DDevice, pDirect3DContext); + if (FAILED(hr)) { + Platform::DebugPrintf("Failed to create D3D device 0x%lx\n", hr); + return hr; + } + + hr = UniquePtrFromQI(pDirect3DDevice.get(), __uuidof(IDXGIDevice), pDXGIDevice); + if (FAILED(hr)) { + Platform::DebugPrintf("Failed to create DXGI device 0x%lx\n", hr); + return hr; + } + + ID2D1Device *pDirect2DDevice_{}; + hr = pD2DFactory->CreateDevice(pDXGIDevice.get(), &pDirect2DDevice_); + if (FAILED(hr)) { + Platform::DebugPrintf("Failed to create D2D device 0x%lx\n", hr); + return hr; + } + pDirect2DDevice.reset(pDirect2DDevice_); + + return S_OK; +} + +using DXGISwapChain = std::unique_ptr<IDXGISwapChain1, UnknownReleaser>; + #endif /** @@ -435,6 +491,8 @@ class ScintillaWin : } #if defined(USE_D2D) + DirectDevice device; + DXGISwapChain pDXGISwapChain; RenderTargets targets; // rendering parameters for current monitor HMONITOR hCurrentMonitor; @@ -452,6 +510,10 @@ class ScintillaWin : void Finalise() override; #if defined(USE_D2D) bool UpdateRenderingParams(bool force) noexcept; + HRESULT Create3D() noexcept; + void CreateRenderTarget(); + HRESULT SetBackBuffer(HWND hwnd, IDXGISwapChain1 *pSwapChain); + HRESULT CreateSwapChain(HWND hwnd); void EnsureRenderTarget(HDC hdc); #endif void DropRenderTarget() noexcept; @@ -713,6 +775,16 @@ HRESULT CreateHwndRenderTarget(const D2D1_RENDER_TARGET_PROPERTIES *renderTarget return hr; } +HRESULT CreateDeviceContext(ID2D1Device *pDirect2DDevice, D2DeviceContext &deviceContext) noexcept { + deviceContext.reset(); + ID2D1DeviceContext *pD2DC{}; + const HRESULT hr = pDirect2DDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &pD2DC); + if (SUCCEEDED(hr) && pD2DC) { + deviceContext.reset(pD2DC); + } + return hr; +} + bool ScintillaWin::UpdateRenderingParams(bool force) noexcept { if (!renderingParams) { try { @@ -761,59 +833,171 @@ bool ScintillaWin::UpdateRenderingParams(bool force) noexcept { return true; } -void ScintillaWin::EnsureRenderTarget(HDC hdc) { - if (!targets.valid) { - DropRenderTarget(); - targets.valid = true; +HRESULT ScintillaWin::Create3D() noexcept { + if (device.pDirect2DDevice) { + return S_OK; } - if (!targets.RenderTarget()) { - HWND hw = MainHWND(); - const RECT rc = GetClientRect(hw); - - // Create a Direct2D render target. - D2D1_RENDER_TARGET_PROPERTIES drtp {}; - drtp.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; - drtp.usage = D2D1_RENDER_TARGET_USAGE_NONE; - drtp.minLevel = D2D1_FEATURE_LEVEL_DEFAULT; - - if (technology == Technology::DirectWriteDC) { - drtp.dpiX = 96.f; - drtp.dpiY = 96.f; - // Explicit pixel format needed. - drtp.pixelFormat = D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, - D2D1_ALPHA_MODE_IGNORE); - - const HRESULT hr = CreateDCRenderTarget(&drtp, targets.pDCRT); + targets.Release(); + pDXGISwapChain.reset(); + device.Release(); + const HRESULT hr = device.CreateDevice(); + if (FAILED(hr)) { + device.Release(); + } + return hr; +} + +void ScintillaWin::CreateRenderTarget() { + HWND hw = MainHWND(); + const RECT rc = GetClientRect(hw); + + // Create a Direct2D render target. + D2D1_RENDER_TARGET_PROPERTIES drtp{}; + drtp.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; + drtp.usage = D2D1_RENDER_TARGET_USAGE_NONE; + drtp.minLevel = D2D1_FEATURE_LEVEL_DEFAULT; + + if (technology == Technology::DirectWriteDC) { + drtp.dpiX = 96.f; + drtp.dpiY = 96.f; + // Explicit pixel format needed. + drtp.pixelFormat = D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, + D2D1_ALPHA_MODE_IGNORE); + + const HRESULT hr = CreateDCRenderTarget(&drtp, targets.pDCRT); + if (FAILED(hr)) { + Platform::DebugPrintf("Failed CreateDCRenderTarget 0x%lx\n", hr); + targets.Release(); + } + + } else if (technology == Technology::DirectWrite1) { + HRESULT hr = Create3D(); // Need pDirect2DDevice + if (SUCCEEDED(hr)) { + hr = CreateDeviceContext(device.pDirect2DDevice.get(), targets.pDeviceContext); if (FAILED(hr)) { - Platform::DebugPrintf("Failed CreateDCRenderTarget 0x%lx\n", hr); - targets.Release(); + Platform::DebugPrintf("Failed CreateDeviceContext 0x%lx\n", hr); + } else { + hr = CreateSwapChain(hw); + if (FAILED(hr)) { + Platform::DebugPrintf("Failed CreateSwapChain 0x%lx\n", hr); + targets.Release(); + } } + } - } else { - const int integralDeviceScaleFactor = GetFirstIntegralMultipleDeviceScaleFactor(); - drtp.dpiX = 96.f * integralDeviceScaleFactor; - drtp.dpiY = 96.f * integralDeviceScaleFactor; - drtp.pixelFormat = D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, - D2D1_ALPHA_MODE_UNKNOWN); - - D2D1_HWND_RENDER_TARGET_PROPERTIES dhrtp {}; - dhrtp.hwnd = hw; - dhrtp.pixelSize = ::GetSizeUFromRect(rc, integralDeviceScaleFactor); - dhrtp.presentOptions = (technology == Technology::DirectWriteRetain) ? + } else { // DirectWrite or DirectWriteRetain + const int integralDeviceScaleFactor = GetFirstIntegralMultipleDeviceScaleFactor(); + drtp.dpiX = 96.f * integralDeviceScaleFactor; + drtp.dpiY = 96.f * integralDeviceScaleFactor; + drtp.pixelFormat = D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, + D2D1_ALPHA_MODE_UNKNOWN); + + D2D1_HWND_RENDER_TARGET_PROPERTIES dhrtp{}; + dhrtp.hwnd = hw; + dhrtp.pixelSize = ::GetSizeUFromRect(rc, integralDeviceScaleFactor); + dhrtp.presentOptions = (technology == Technology::DirectWriteRetain) ? D2D1_PRESENT_OPTIONS_RETAIN_CONTENTS : D2D1_PRESENT_OPTIONS_NONE; - const HRESULT hr = CreateHwndRenderTarget(&drtp, &dhrtp, targets.pHwndRT); - if (FAILED(hr)) { - Platform::DebugPrintf("Failed CreateHwndRenderTarget 0x%lx\n", hr); - targets.Release(); - } + const HRESULT hr = CreateHwndRenderTarget(&drtp, &dhrtp, targets.pHwndRT); + if (FAILED(hr)) { + Platform::DebugPrintf("Failed CreateHwndRenderTarget 0x%lx\n", hr); + targets.Release(); } + + } +} + +HRESULT ScintillaWin::SetBackBuffer(HWND hwnd, IDXGISwapChain1 *pSwapChain) { + assert(targets.pDeviceContext); + // Back buffer as an IDXGISurface + IDXGISurface *dxgiBackBuffer_{}; + HRESULT hr = pSwapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackBuffer_)); + if (FAILED(hr)) + return hr; + std::unique_ptr<IDXGISurface, UnknownReleaser> dxgiBackBuffer(dxgiBackBuffer_); + + const FLOAT dpiX = static_cast<FLOAT>(DpiForWindow(hwnd)); + const FLOAT dpiY = dpiX; + + // Direct2D bitmap linked to Direct3D texture through DXGI back buffer + const D2D1_BITMAP_PROPERTIES1 bitmapProperties = + D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, + D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE), dpiX, dpiY); + ID2D1Bitmap1 *pDirect2DBackBuffer{}; + hr = targets.pDeviceContext->CreateBitmapFromDxgiSurface(dxgiBackBuffer.get(), &bitmapProperties, &pDirect2DBackBuffer); + if (FAILED(hr)) + return hr; + + // Bitmap is render target + targets.pDeviceContext->SetTarget(pDirect2DBackBuffer); + ReleaseUnknown(pDirect2DBackBuffer); + + return S_OK; +} + +HRESULT ScintillaWin::CreateSwapChain(HWND hwnd) { + // Sets pDXGISwapChain but only when each call succeeds + // Needs pDXGIDevice, pDirect3DDevice + pDXGISwapChain.reset(); + assert(device.pDXGIDevice); + + // At each stage, place object in a unique_ptr to ensure release occurs + + IDXGIAdapter *dxgiAdapter_{}; + HRESULT hr = device.pDXGIDevice->GetAdapter(&dxgiAdapter_); + if (FAILED(hr)) + return hr; + std::unique_ptr<IDXGIAdapter, UnknownReleaser> dxgiAdapter(dxgiAdapter_); + + IDXGIFactory2 *dxgiFactory_{}; + hr = dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory_)); + if (FAILED(hr)) + return hr; + std::unique_ptr<IDXGIFactory2, UnknownReleaser> dxgiFactory(dxgiFactory_); + + DXGI_SWAP_CHAIN_DESC1 swapChainDesc{}; + swapChainDesc.Width = 0; + swapChainDesc.Height = 0; + swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + swapChainDesc.Stereo = false; + swapChainDesc.SampleDesc.Count = 1; + swapChainDesc.SampleDesc.Quality = 0; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.BufferCount = 2; + swapChainDesc.Scaling = DXGI_SCALING_STRETCH; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + swapChainDesc.Flags = 0; + + // DXGI swap chain for window + IDXGISwapChain1 *pSwapChain_{}; + hr = dxgiFactory->CreateSwapChainForHwnd(device.pDirect3DDevice.get(), hwnd, &swapChainDesc, + nullptr, nullptr, &pSwapChain_); + if (FAILED(hr)) + return hr; + DXGISwapChain pSwapChain(pSwapChain_); + + hr = SetBackBuffer(hwnd, pSwapChain.get()); + if (FAILED(hr)) + return hr; + + // All successful so export swap chain for later presentation + pDXGISwapChain = std::move(pSwapChain); + return S_OK; +} + +void ScintillaWin::EnsureRenderTarget(HDC hdc) { + if (!targets.valid) { + DropRenderTarget(); + targets.valid = true; + } + if (!targets.RenderTarget()) { + CreateRenderTarget(); // Pixmaps were created to be compatible with previous render target so // need to be recreated. DropGraphics(); } - if ((technology == Technology::DirectWriteDC) && targets.pDCRT) { + if ((technology == Technology::DirectWriteDC) && targets.pDCRT) { // DC RenderTarget needs binding const RECT rcWindow = GetClientRect(MainHWND()); const HRESULT hr = targets.pDCRT->BindDC(hdc, &rcWindow); if (FAILED(hr)) { @@ -1070,6 +1254,11 @@ bool ScintillaWin::PaintDC(HDC hdc) { } } else { #if defined(USE_D2D) + // RefreshStyleData may set scroll bars and resize the window. + // Avoid issues resizing inside Paint when calling IDXGISwapChain1->ResizeBuffers + // with committed resources by refreshing the style data first. + RefreshStyleData(); + EnsureRenderTarget(hdc); if (ID2D1RenderTarget *pRenderTarget = targets.RenderTarget()) { AutoSurface surfaceWindow(pRenderTarget, this); @@ -1083,6 +1272,14 @@ bool ScintillaWin::PaintDC(HDC hdc) { DropRenderTarget(); return false; } + if ((technology == Technology::DirectWrite1) && pDXGISwapChain) { + const DXGI_PRESENT_PARAMETERS parameters{}; + const HRESULT hrPresent = pDXGISwapChain->Present1(1, 0, ¶meters); + if (FAILED(hrPresent)) { + DropRenderTarget(); + return false; + } + } } } #endif @@ -1596,9 +1793,9 @@ PRectangle ScintillaWin::GetClientRectangle() const { } void ScintillaWin::SizeWindow() { + rectangleClient = wMain.GetClientPosition(); #if defined(USE_D2D) HRESULT hrResize = E_FAIL; - if (((technology == Technology::DirectWrite) || (technology == Technology::DirectWriteRetain)) && targets.pHwndRT) { // May be able to just resize the HWND render target const int scaleFactor = GetFirstIntegralMultipleDeviceScaleFactor(); @@ -1608,16 +1805,25 @@ void ScintillaWin::SizeWindow() { Platform::DebugPrintf("Failed to Resize ID2D1HwndRenderTarget 0x%lx\n", hrResize); } } - if (paintState == PaintState::notPainting) { - if (FAILED(hrResize)) { + if ((technology == Technology::DirectWrite1) && pDXGISwapChain && targets.pDeviceContext && + (paintState == PaintState::notPainting)) { + targets.pDeviceContext->SetTarget(NULL); // ResizeBuffers fails if bitmap still owned by swap chain + hrResize = pDXGISwapChain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0); + if (SUCCEEDED(hrResize)) { + hrResize = SetBackBuffer(MainHWND(), pDXGISwapChain.get()); + } else { + Platform::DebugPrintf("Failed ResizeBuffers 0x%lx\n", hrResize); + } + } + if (FAILED(hrResize)) { + if (paintState == PaintState::notPainting) { DropRenderTarget(); + } else { + targets.valid = false; } - } else { - targets.valid = false; } #endif //Platform::DebugPrintf("Scintilla WM_SIZE %d %d\n", LOWORD(lParam), HIWORD(lParam)); - rectangleClient = wMain.GetClientPosition(); ChangeSize(); } @@ -2032,7 +2238,8 @@ sptr_t ScintillaWin::SciMessage(Message iMessage, uptr_t wParam, sptr_t lParam) (technologyNew == Technology::Default) || (technologyNew == Technology::DirectWriteRetain) || (technologyNew == Technology::DirectWriteDC) || - (technologyNew == Technology::DirectWrite)) { + (technologyNew == Technology::DirectWrite) || + (technologyNew == Technology::DirectWrite1)) { if (technology != technologyNew) { if (technologyNew > Technology::Default) { #if defined(USE_D2D) |