diff options
Diffstat (limited to 'win32/ScintillaWin.cxx')
| -rw-r--r-- | win32/ScintillaWin.cxx | 118 | 
1 files changed, 106 insertions, 12 deletions
| diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index 9925a64bb..28e48596b 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -24,6 +24,9 @@  #include <richedit.h>  #include <windowsx.h> +#include <d2d1.h> +#include <dwrite.h> +  #include "Platform.h"  #include "ILexer.h" @@ -197,6 +200,10 @@ class ScintillaWin :  	static HINSTANCE hInstance; +	IDWriteFactory *pIDWriteFactory; +	ID2D1Factory *pD2DFactory; +	ID2D1HwndRenderTarget *pRenderTarget; +  	ScintillaWin(HWND hwnd);  	ScintillaWin(const ScintillaWin &);  	virtual ~ScintillaWin(); @@ -204,6 +211,8 @@ class ScintillaWin :  	virtual void Initialise();  	virtual void Finalise(); +	void EnsureRenderTarget(); +	void DropRenderTarget();  	HWND MainHWND();  	static sptr_t DirectFunction( @@ -350,6 +359,10 @@ ScintillaWin::ScintillaWin(HWND hwnd) {  	sysCaretWidth = 0;  	sysCaretHeight = 0; +	pIDWriteFactory = 0; +	pD2DFactory = 0; +	pRenderTarget = 0; +  	keysAlwaysUnicode = false;  	caret.period = ::GetCaretBlinkTime(); @@ -378,18 +391,69 @@ void ScintillaWin::Initialise() {  				::GetProcAddress(commctrl32, "_TrackMouseEvent");  		}  	} + +	if (!pIDWriteFactory) { +		DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, +			__uuidof(IDWriteFactory), +			reinterpret_cast<IUnknown**>(&pIDWriteFactory)); +	} +	if (!pD2DFactory) { +		D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pD2DFactory); +	}  }  void ScintillaWin::Finalise() {  	ScintillaBase::Finalise();  	SetTicking(false);  	SetIdle(false); +	DropRenderTarget(); +	if (pIDWriteFactory) { +		pIDWriteFactory->Release(); +		pIDWriteFactory = 0; +	} +	if (pD2DFactory) { +		pD2DFactory->Release(); +		pD2DFactory = 0; +	}  	::RevokeDragDrop(MainHWND());  	if (SUCCEEDED(hrOle)) {  		::OleUninitialize();  	}  } +void ScintillaWin::EnsureRenderTarget() { +	if (pD2DFactory && !pRenderTarget) { +		RECT rc; +		HWND hw = MainHWND(); +		GetClientRect(hw, &rc); + +		D2D1_SIZE_U size = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top); + +		// Create a Direct2D render target. +#if 1 +		pD2DFactory->CreateHwndRenderTarget( +			D2D1::RenderTargetProperties(), +			D2D1::HwndRenderTargetProperties(hw, size), +			&pRenderTarget); +#else +		pD2DFactory->CreateHwndRenderTarget( +			D2D1::RenderTargetProperties( +				D2D1_RENDER_TARGET_TYPE_DEFAULT , +				D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED), +				96.0f, 96.0f, D2D1_RENDER_TARGET_USAGE_NONE, D2D1_FEATURE_LEVEL_DEFAULT), +			D2D1::HwndRenderTargetProperties(hw, size), +			&pRenderTarget); +#endif +	} +} + +void ScintillaWin::DropRenderTarget() { +	if (pRenderTarget) { +		pRenderTarget->Release(); +		pRenderTarget = 0; +	} +} +  HWND ScintillaWin::MainHWND() {  	return reinterpret_cast<HWND>(wMain.GetID());  } @@ -505,8 +569,11 @@ LRESULT ScintillaWin::WndPaint(uptr_t wParam) {  		pps = &ps;  		::BeginPaint(MainHWND(), pps);  	} -	AutoSurface surfaceWindow(pps->hdc, this); +	//AutoSurface surfaceWindow(pps->hdc, this); +	EnsureRenderTarget(); +	AutoSurface surfaceWindow(pRenderTarget, this);  	if (surfaceWindow) { +		pRenderTarget->BeginDraw();  		rcPaint = PRectangle(pps->rcPaint.left, pps->rcPaint.top, pps->rcPaint.right, pps->rcPaint.bottom);  		PRectangle rcClient = GetClientRectangle();  		paintingAllText = rcPaint.Contains(rcClient); @@ -517,6 +584,10 @@ LRESULT ScintillaWin::WndPaint(uptr_t wParam) {  		}  		Paint(surfaceWindow, rcPaint);  		surfaceWindow->Release(); +		HRESULT hr = pRenderTarget->EndDraw(); +		if (hr == D2DERR_RECREATE_TARGET) { +			DropRenderTarget(); +        }  	}  	if (hRgnUpdate) {  		::DeleteRgn(hRgnUpdate); @@ -674,6 +745,7 @@ sptr_t ScintillaWin::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam  			break;  		case WM_SIZE: { +				DropRenderTarget();  				//Platform::DebugPrintf("Scintilla WM_SIZE %d %d\n", LoWord(lParam), HiWord(lParam));  				ChangeSize();  			} @@ -1189,11 +1261,12 @@ bool ScintillaWin::PaintContains(PRectangle rc) {  	return contains;  } -void ScintillaWin::ScrollText(int linesToMove) { +void ScintillaWin::ScrollText(int /* linesToMove */) {  	//Platform::DebugPrintf("ScintillaWin::ScrollText %d\n", linesToMove); -	::ScrollWindow(MainHWND(), 0, -		vs.lineHeight * linesToMove, 0, 0); -	::UpdateWindow(MainHWND()); +	//::ScrollWindow(MainHWND(), 0, +	//	vs.lineHeight * linesToMove, 0, 0); +	//::UpdateWindow(MainHWND()); +	Redraw();  }  void ScintillaWin::UpdateSystemCaret() { @@ -2283,7 +2356,9 @@ void ScintillaWin::HorizontalScrollMessage(WPARAM wParam) {  	HorizontalScrollTo(xPos);  } -void ScintillaWin::RealizeWindowPalette(bool inBackGround) { +void ScintillaWin::RealizeWindowPalette(bool) { +	// No support for palette with D2D +/*  	RefreshStyleData();  	HDC hdc = ::GetDC(MainHWND());  	// Select a stock font to prevent warnings from BoundsChecker @@ -2296,6 +2371,7 @@ void ScintillaWin::RealizeWindowPalette(bool inBackGround) {  		surfaceWindow->Release();  	}  	::ReleaseDC(MainHWND(), hdc); +*/  }  /** @@ -2303,23 +2379,30 @@ void ScintillaWin::RealizeWindowPalette(bool inBackGround) {   * This paint will not be abandoned.   */  void ScintillaWin::FullPaint() { -	HDC hdc = ::GetDC(MainHWND()); -	FullPaintDC(hdc); -	::ReleaseDC(MainHWND(), hdc); +	//HDC hdc = ::GetDC(MainHWND()); +	//FullPaintDC(hdc); +	//::ReleaseDC(MainHWND(), hdc); +	FullPaintDC(0);  }  /**   * Redraw all of text area on the specified DC.   * This paint will not be abandoned.   */ -void ScintillaWin::FullPaintDC(HDC hdc) { +void ScintillaWin::FullPaintDC(HDC) {  	paintState = painting;  	rcPaint = GetClientRectangle();  	paintingAllText = true; -	AutoSurface surfaceWindow(hdc, this); +	EnsureRenderTarget(); +	AutoSurface surfaceWindow(pRenderTarget, this);  	if (surfaceWindow) { +		pRenderTarget->BeginDraw();  		Paint(surfaceWindow, rcPaint);  		surfaceWindow->Release(); +		HRESULT hr = pRenderTarget->EndDraw(); +		if (hr == D2DERR_RECREATE_TARGET) { +			DropRenderTarget(); +        }  	}  	paintState = notPainting;  } @@ -2693,10 +2776,21 @@ sptr_t PASCAL ScintillaWin::CTWndProc(  				::BeginPaint(hWnd, &ps);  				Surface *surfaceWindow = Surface::Allocate();  				if (surfaceWindow) { -					surfaceWindow->Init(ps.hdc, hWnd); +					ID2D1HwndRenderTarget *pCTRenderTarget = 0; +					RECT rc; +					GetClientRect(hWnd, &rc); +					// Create a Direct2D render target. +					sciThis->pD2DFactory->CreateHwndRenderTarget( +						D2D1::RenderTargetProperties(), +						D2D1::HwndRenderTargetProperties(hWnd, D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top)), +						&pCTRenderTarget); +					//surfaceWindow->Init(ps.hdc, hWnd); +					surfaceWindow->Init(pCTRenderTarget, hWnd);  					surfaceWindow->SetUnicodeMode(SC_CP_UTF8 == sciThis->ct.codePage);  					surfaceWindow->SetDBCSMode(sciThis->ct.codePage); +					pCTRenderTarget->BeginDraw();  					sciThis->ct.PaintCT(surfaceWindow); +					pCTRenderTarget->EndDraw();  					surfaceWindow->Release();  					delete surfaceWindow;  				} | 
