diff options
Diffstat (limited to 'win32/ScintillaWin.cxx')
| -rw-r--r-- | win32/ScintillaWin.cxx | 180 | 
1 files changed, 146 insertions, 34 deletions
| diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index d1f450479..a3c141aff 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" @@ -54,6 +57,7 @@  #include "Editor.h"  #include "ScintillaBase.h"  #include "UniConversion.h" +#include "PlatWin.h"  #ifdef SCI_LEXER  #include "ExternalLexer.h" @@ -87,11 +91,6 @@  #define SC_WIN_IDLE 5001 -// Functions imported from PlatWin -extern bool IsNT(); -extern void Platform_Initialise(void *hInstance); -extern void Platform_Finalise(); -  typedef BOOL (WINAPI *TrackMouseEventSig)(LPTRACKMOUSEEVENT);  // GCC has trouble with the standard COM ABI so do it the old C way with explicit vtables. @@ -197,6 +196,8 @@ class ScintillaWin :  	static HINSTANCE hInstance; +	ID2D1HwndRenderTarget *pRenderTarget; +  	ScintillaWin(HWND hwnd);  	ScintillaWin(const ScintillaWin &);  	virtual ~ScintillaWin(); @@ -204,6 +205,8 @@ class ScintillaWin :  	virtual void Initialise();  	virtual void Finalise(); +	void EnsureRenderTarget(); +	void DropRenderTarget();  	HWND MainHWND();  	static sptr_t DirectFunction( @@ -350,6 +353,8 @@ ScintillaWin::ScintillaWin(HWND hwnd) {  	sysCaretWidth = 0;  	sysCaretHeight = 0; +	pRenderTarget = 0; +  	keysAlwaysUnicode = false;  	caret.period = ::GetCaretBlinkTime(); @@ -384,12 +389,46 @@ void ScintillaWin::Finalise() {  	ScintillaBase::Finalise();  	SetTicking(false);  	SetIdle(false); +	DropRenderTarget();  	::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,18 +544,35 @@ LRESULT ScintillaWin::WndPaint(uptr_t wParam) {  		pps = &ps;  		::BeginPaint(MainHWND(), pps);  	} -	AutoSurface surfaceWindow(pps->hdc, this); -	if (surfaceWindow) { -		rcPaint = PRectangle(pps->rcPaint.left, pps->rcPaint.top, pps->rcPaint.right, pps->rcPaint.bottom); -		PRectangle rcClient = GetClientRectangle(); -		paintingAllText = rcPaint.Contains(rcClient); -		if (paintingAllText) { -			//Platform::DebugPrintf("Performing full text paint\n"); -		} else { -			//Platform::DebugPrintf("Performing partial paint %d .. %d\n", rcPaint.top, rcPaint.bottom); +	if (technology == SC_TECHNOLOGY_DEFAULT) { +		AutoSurface surfaceWindow(pps->hdc, this); +		if (surfaceWindow) { +			rcPaint = PRectangle(pps->rcPaint.left, pps->rcPaint.top, pps->rcPaint.right, pps->rcPaint.bottom); +			PRectangle rcClient = GetClientRectangle(); +			paintingAllText = rcPaint.Contains(rcClient); +			Paint(surfaceWindow, rcPaint); +			surfaceWindow->Release(); +		} +	} else { +		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); +			if (paintingAllText) { +				//Platform::DebugPrintf("Performing full text paint\n"); +			} else { +				//Platform::DebugPrintf("Performing partial paint %d .. %d\n", rcPaint.top, rcPaint.bottom); +			} +			Paint(surfaceWindow, rcPaint); +			surfaceWindow->Release(); +			HRESULT hr = pRenderTarget->EndDraw(); +			if (hr == D2DERR_RECREATE_TARGET) { +				DropRenderTarget(); +			}  		} -		Paint(surfaceWindow, rcPaint); -		surfaceWindow->Release();  	}  	if (hRgnUpdate) {  		::DeleteRgn(hRgnUpdate); @@ -674,6 +730,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();  			} @@ -1085,6 +1142,22 @@ sptr_t ScintillaWin::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam  		case SCI_GETKEYSUNICODE:  			return keysAlwaysUnicode; +		 +		case SCI_SETTECHNOLOGY: +			if ((wParam == SC_TECHNOLOGY_DEFAULT) || (wParam == SC_TECHNOLOGY_DIRECTWRITE)) { +				if (technology != static_cast<int>(wParam)) { +					if (static_cast<int>(wParam) == SC_TECHNOLOGY_DIRECTWRITE) { +						if (!LoadD2D()) +							// Failed to load Direct2D or DirectWrite so no effect +							return 0; +					} +					technology = wParam; +					// Invalidate all cached information including layout. +					DropGraphics(true); +					InvalidateStyleRedraw(); +				} +			} +			break;  #ifdef SCI_LEXER  		case SCI_LOADLEXERLIBRARY: @@ -1196,11 +1269,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() { @@ -2085,9 +2159,9 @@ void ScintillaWin::ImeStartComposition() {  			// The logfont for the IME is recreated here.  			int styleHere = (pdoc->StyleAt(sel.MainCaret())) & 31;  			LOGFONTA lf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ""}; -			int sizeZoomed = vs.styles[styleHere].size + vs.zoomLevel; -			if (sizeZoomed <= 2)	// Hangs if sizeZoomed <= 1 -				sizeZoomed = 2; +			int sizeZoomed = vs.styles[styleHere].size + vs.zoomLevel * SC_FONT_SIZE_MULTIPLIER; +			if (sizeZoomed <= 2 * SC_FONT_SIZE_MULTIPLIER)	// Hangs if sizeZoomed <= 1 +				sizeZoomed = 2 * SC_FONT_SIZE_MULTIPLIER;  			AutoSurface surface(this);  			int deviceHeight = sizeZoomed;  			if (surface) { @@ -2095,7 +2169,7 @@ void ScintillaWin::ImeStartComposition() {  			}  			// The negative is to allow for leading  			lf.lfHeight = -(abs(deviceHeight)); -			lf.lfWeight = vs.styles[styleHere].bold ? FW_BOLD : FW_NORMAL; +			lf.lfWeight = vs.styles[styleHere].weight;  			lf.lfItalic = static_cast<BYTE>(vs.styles[styleHere].italic ? 1 : 0);  			lf.lfCharSet = DEFAULT_CHARSET;  			lf.lfFaceName[0] = '\0'; @@ -2290,7 +2364,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 @@ -2303,6 +2379,7 @@ void ScintillaWin::RealizeWindowPalette(bool inBackGround) {  		surfaceWindow->Release();  	}  	::ReleaseDC(MainHWND(), hdc); +*/  }  /** @@ -2310,9 +2387,13 @@ void ScintillaWin::RealizeWindowPalette(bool inBackGround) {   * This paint will not be abandoned.   */  void ScintillaWin::FullPaint() { -	HDC hdc = ::GetDC(MainHWND()); -	FullPaintDC(hdc); -	::ReleaseDC(MainHWND(), hdc); +	if (technology == SC_TECHNOLOGY_DEFAULT) { +		HDC hdc = ::GetDC(MainHWND()); +		FullPaintDC(hdc); +		::ReleaseDC(MainHWND(), hdc); +	} else { +		FullPaintDC(0); +	}  }  /** @@ -2323,10 +2404,24 @@ void ScintillaWin::FullPaintDC(HDC hdc) {  	paintState = painting;  	rcPaint = GetClientRectangle();  	paintingAllText = true; -	AutoSurface surfaceWindow(hdc, this); -	if (surfaceWindow) { -		Paint(surfaceWindow, rcPaint); -		surfaceWindow->Release(); +	if (technology == SC_TECHNOLOGY_DEFAULT) { +		AutoSurface surfaceWindow(hdc, this); +		if (surfaceWindow) { +			Paint(surfaceWindow, rcPaint); +			surfaceWindow->Release(); +		} +	} else { +		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;  } @@ -2698,14 +2793,31 @@ sptr_t PASCAL ScintillaWin::CTWndProc(  			} else if (iMessage == WM_PAINT) {  				PAINTSTRUCT ps;  				::BeginPaint(hWnd, &ps); -				Surface *surfaceWindow = Surface::Allocate(); +				Surface *surfaceWindow = Surface::Allocate(sciThis->technology);  				if (surfaceWindow) { -					surfaceWindow->Init(ps.hdc, hWnd); +					ID2D1HwndRenderTarget *pCTRenderTarget = 0; +					RECT rc; +					GetClientRect(hWnd, &rc); +					// Create a Direct2D render target. +					if (sciThis->technology == SC_TECHNOLOGY_DEFAULT) { +						surfaceWindow->Init(ps.hdc, hWnd); +					} else { +						pD2DFactory->CreateHwndRenderTarget( +							D2D1::RenderTargetProperties(), +							D2D1::HwndRenderTargetProperties(hWnd, D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top)), +							&pCTRenderTarget); +						surfaceWindow->Init(pCTRenderTarget, hWnd); +						pCTRenderTarget->BeginDraw(); +					}  					surfaceWindow->SetUnicodeMode(SC_CP_UTF8 == sciThis->ct.codePage);  					surfaceWindow->SetDBCSMode(sciThis->ct.codePage);  					sciThis->ct.PaintCT(surfaceWindow); +					if (pCTRenderTarget) +						pCTRenderTarget->EndDraw();  					surfaceWindow->Release();  					delete surfaceWindow; +					if (pCTRenderTarget) +						pCTRenderTarget->Release();  				}  				::EndPaint(hWnd, &ps);  				return 0; | 
