aboutsummaryrefslogtreecommitdiffhomepage
path: root/win32/ScintillaWin.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'win32/ScintillaWin.cxx')
-rw-r--r--win32/ScintillaWin.cxx180
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;