Patch 8.0.1369
Problem: MS-Windows: drawing underline, curl and strike-throw is slow,
mFallbackDC not properly updated.
Solution: Several performance improvements. (Ken Takata, Taro Muraoka,
Yasuhiro Matsumoto, closes #2401)
Files: runtime/doc/options.txt, src/gui_dwrite.cpp, src/gui_dwrite.h,
src/gui_w32.c
*** ../vim-8.0.1368/runtime/doc/options.txt 2017-12-01 20:35:54.864077110
+0100
--- runtime/doc/options.txt 2017-12-05 13:18:55.511425089 +0100
***************
*** 6017,6025 ****
geom pixelGeometry int 0 - 2 (see below)
renmode renderingMode int 0 - 6 (see below)
taamode textAntialiasMode int 0 - 3 (see below)
! See this URL for detail:
! http://msdn.microsoft.com/en-us/library/dd368190.aspx
For geom: structure of a device pixel.
0 - DWRITE_PIXEL_GEOMETRY_FLAT
--- 6122,6131 ----
geom pixelGeometry int 0 - 2 (see below)
renmode renderingMode int 0 - 6 (see below)
taamode textAntialiasMode int 0 - 3 (see below)
+ scrlines Scroll Lines int >= 0 (see below)
! See this URL for detail (except for scrlines):
! https://msdn.microsoft.com/en-us/library/dd368190.aspx
For geom: structure of a device pixel.
0 - DWRITE_PIXEL_GEOMETRY_FLAT
***************
*** 6027,6033 ****
2 - DWRITE_PIXEL_GEOMETRY_BGR
See this URL for detail:
! http://msdn.microsoft.com/en-us/library/dd368114.aspx
For renmode: method of rendering glyphs.
0 - DWRITE_RENDERING_MODE_DEFAULT
--- 6133,6139 ----
2 - DWRITE_PIXEL_GEOMETRY_BGR
See this URL for detail:
! https://msdn.microsoft.com/en-us/library/dd368114.aspx
For renmode: method of rendering glyphs.
0 - DWRITE_RENDERING_MODE_DEFAULT
***************
*** 6039,6045 ****
6 - DWRITE_RENDERING_MODE_OUTLINE
See this URL for detail:
! http://msdn.microsoft.com/en-us/library/dd368118.aspx
For taamode: antialiasing mode used for drawing text.
0 - D2D1_TEXT_ANTIALIAS_MODE_DEFAULT
--- 6145,6151 ----
6 - DWRITE_RENDERING_MODE_OUTLINE
See this URL for detail:
! https://msdn.microsoft.com/en-us/library/dd368118.aspx
For taamode: antialiasing mode used for drawing text.
0 - D2D1_TEXT_ANTIALIAS_MODE_DEFAULT
***************
*** 6048,6054 ****
3 - D2D1_TEXT_ANTIALIAS_MODE_ALIASED
See this URL for detail:
! http://msdn.microsoft.com/en-us/library/dd368170.aspx
Example: >
set encoding=utf-8
--- 6154,6178 ----
3 - D2D1_TEXT_ANTIALIAS_MODE_ALIASED
See this URL for detail:
! https://msdn.microsoft.com/en-us/library/dd368170.aspx
!
! For scrlines: threshold for lines to be scrolled.
! 0 - Always use scrolling. (default)
! 1 - Use full page redrawing.
! > 1 - If the lines to be scrolled is grater or equal to the
! specified value, use redrawing. Otherwise use
! scrolling.
!
! If you feel scrolling a page (CTRL-F) is too slow with DirectX
! renderer, try this "scrlines" option.
! When set it "1", Vim uses full page redrawing instead of
! scrolling. Redrawing a page is faster than scrolling a
! page in some environments.
! After that, when you feel scrolling lines (CTRL-Y) becomes
! slow, please try "2" or greater value for this option.
! It works threshold line number to switch scrolling to
! redrawing. Scrolling a few lines might be faster than
! redrawing a page in some environments.
Example: >
set encoding=utf-8
***************
*** 6057,6069 ****
<
If select a raster font (Courier, Terminal or FixedSys which
have ".fon" extension in file name) to 'guifont', it will be
! drawn by GDI as a fallback. This fallback will cause
! significant slow down on drawing.
NOTE: It is known that some fonts and options combination
causes trouble on drawing glyphs.
! - 'rendmode:5' and 'renmode:6' will not work with some
special made fonts (True-Type fonts which includes only
bitmap glyphs).
- 'taamode:3' will not work with some vector fonts.
--- 6181,6192 ----
<
If select a raster font (Courier, Terminal or FixedSys which
have ".fon" extension in file name) to 'guifont', it will be
! drawn by GDI as a fallback.
NOTE: It is known that some fonts and options combination
causes trouble on drawing glyphs.
! - 'renmode:5' and 'renmode:6' will not work with some
special made fonts (True-Type fonts which includes only
bitmap glyphs).
- 'taamode:3' will not work with some vector fonts.
*** ../vim-8.0.1368/src/gui_dwrite.cpp 2017-11-26 14:29:24.847931598 +0100
--- src/gui_dwrite.cpp 2017-12-05 13:18:55.511425089 +0100
***************
*** 263,276 ****
--- 263,286 ----
}
};
+ enum DrawingMode {
+ DM_GDI = 0,
+ DM_DIRECTX = 1,
+ DM_INTEROP = 2,
+ };
+
struct DWriteContext {
HDC mHDC;
+ RECT mBindRect;
+ DrawingMode mDMode;
+ HDC mInteropHDC;
bool mDrawing;
bool mFallbackDC;
ID2D1Factory *mD2D1Factory;
ID2D1DCRenderTarget *mRT;
+ ID2D1GdiInteropRenderTarget *mGDIRT;
ID2D1SolidColorBrush *mBrush;
IDWriteFactory *mDWriteFactory;
***************
*** 292,297 ****
--- 302,311 ----
virtual ~DWriteContext();
+ HRESULT CreateDeviceResources();
+
+ void DiscardDeviceResources();
+
HRESULT CreateTextFormatFromLOGFONT(const LOGFONTW &logFont,
IDWriteTextFormat **ppTextFormat);
***************
*** 299,315 ****
void SetFont(HFONT hFont);
! void BindDC(HDC hdc, RECT *rect);
! void AssureDrawing();
ID2D1Brush* SolidBrush(COLORREF color);
! void DrawText(const WCHAR* text, int len,
int x, int y, int w, int h, int cellWidth, COLORREF color,
! UINT fuOptions, CONST RECT *lprc, CONST INT * lpDx);
! void FillRect(RECT *rc, COLORREF color);
void Flush();
--- 313,333 ----
void SetFont(HFONT hFont);
! void BindDC(HDC hdc, const RECT *rect);
! HRESULT SetDrawingMode(DrawingMode mode);
ID2D1Brush* SolidBrush(COLORREF color);
! void DrawText(const WCHAR *text, int len,
int x, int y, int w, int h, int cellWidth, COLORREF color,
! UINT fuOptions, const RECT *lprc, const INT *lpDx);
! void FillRect(const RECT *rc, COLORREF color);
!
! void DrawLine(int x1, int y1, int x2, int y2, COLORREF color);
!
! void SetPixel(int x, int y, COLORREF color);
void Flush();
***************
*** 561,570 ****
--- 579,592 ----
DWriteContext::DWriteContext() :
mHDC(NULL),
+ mBindRect(),
+ mDMode(DM_GDI),
+ mInteropHDC(NULL),
mDrawing(false),
mFallbackDC(false),
mD2D1Factory(NULL),
mRT(NULL),
+ mGDIRT(NULL),
mBrush(NULL),
mDWriteFactory(NULL),
mDWriteFactory2(NULL),
***************
*** 584,608 ****
_RPT2(_CRT_WARN, "D2D1CreateFactory: hr=%p p=%p\n", hr, mD2D1Factory);
if (SUCCEEDED(hr))
! {
! D2D1_RENDER_TARGET_PROPERTIES props = {
! D2D1_RENDER_TARGET_TYPE_DEFAULT,
! { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE },
! 0, 0,
! D2D1_RENDER_TARGET_USAGE_NONE,
! D2D1_FEATURE_LEVEL_DEFAULT
! };
! hr = mD2D1Factory->CreateDCRenderTarget(&props, &mRT);
! _RPT2(_CRT_WARN, "CreateDCRenderTarget: hr=%p p=%p\n", hr, mRT);
! }
!
! if (SUCCEEDED(hr))
! {
! hr = mRT->CreateSolidColorBrush(
! D2D1::ColorF(D2D1::ColorF::Black),
! &mBrush);
! _RPT2(_CRT_WARN, "CreateSolidColorBrush: hr=%p p=%p\n", hr, mBrush);
! }
if (SUCCEEDED(hr))
{
--- 606,612 ----
_RPT2(_CRT_WARN, "D2D1CreateFactory: hr=%p p=%p\n", hr, mD2D1Factory);
if (SUCCEEDED(hr))
! hr = CreateDeviceResources();
if (SUCCEEDED(hr))
{
***************
*** 645,655 ****
--- 649,715 ----
SafeRelease(&mDWriteFactory);
SafeRelease(&mDWriteFactory2);
SafeRelease(&mBrush);
+ SafeRelease(&mGDIRT);
SafeRelease(&mRT);
SafeRelease(&mD2D1Factory);
}
HRESULT
+ DWriteContext::CreateDeviceResources()
+ {
+ HRESULT hr;
+
+ if (mRT != NULL)
+ return S_OK;
+
+ D2D1_RENDER_TARGET_PROPERTIES props = {
+ D2D1_RENDER_TARGET_TYPE_DEFAULT,
+ { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE },
+ 0, 0,
+ D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE,
+ D2D1_FEATURE_LEVEL_DEFAULT
+ };
+ hr = mD2D1Factory->CreateDCRenderTarget(&props, &mRT);
+ _RPT2(_CRT_WARN, "CreateDCRenderTarget: hr=%p p=%p\n", hr, mRT);
+
+ if (SUCCEEDED(hr))
+ {
+ // This always succeeds.
+ mRT->QueryInterface(
+ __uuidof(ID2D1GdiInteropRenderTarget),
+ reinterpret_cast<void**>(&mGDIRT));
+ _RPT1(_CRT_WARN, "GdiInteropRenderTarget: p=%p\n", mGDIRT);
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = mRT->CreateSolidColorBrush(
+ D2D1::ColorF(D2D1::ColorF::Black),
+ &mBrush);
+ _RPT2(_CRT_WARN, "CreateSolidColorBrush: hr=%p p=%p\n", hr, mBrush);
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ if (mHDC != NULL)
+ {
+ mRT->BindDC(mHDC, &mBindRect);
+ mRT->SetTransform(D2D1::IdentityMatrix());
+ }
+ }
+
+ return hr;
+ }
+
+ void
+ DWriteContext::DiscardDeviceResources()
+ {
+ SafeRelease(&mBrush);
+ SafeRelease(&mGDIRT);
+ SafeRelease(&mRT);
+ }
+
+ HRESULT
DWriteContext::CreateTextFormatFromLOGFONT(const LOGFONTW &logFont,
IDWriteTextFormat **ppTextFormat)
{
***************
*** 817,843 ****
item.pTextFormat = mTextFormat;
item.fontWeight = mFontWeight;
item.fontStyle = mFontStyle;
}
mFontCache.put(item);
}
void
! DWriteContext::BindDC(HDC hdc, RECT *rect)
{
Flush();
mRT->BindDC(hdc, rect);
mRT->SetTransform(D2D1::IdentityMatrix());
mHDC = hdc;
}
! void
! DWriteContext::AssureDrawing()
{
! if (mDrawing == false)
{
! mRT->BeginDraw();
! mDrawing = true;
}
}
ID2D1Brush*
--- 877,953 ----
item.pTextFormat = mTextFormat;
item.fontWeight = mFontWeight;
item.fontStyle = mFontStyle;
+ mFallbackDC = false;
}
+ else
+ mFallbackDC = true;
mFontCache.put(item);
}
void
! DWriteContext::BindDC(HDC hdc, const RECT *rect)
{
Flush();
mRT->BindDC(hdc, rect);
mRT->SetTransform(D2D1::IdentityMatrix());
mHDC = hdc;
+ mBindRect = *rect;
}
! HRESULT
! DWriteContext::SetDrawingMode(DrawingMode mode)
{
! HRESULT hr = S_OK;
!
! switch (mode)
{
! default:
! case DM_GDI:
! if (mInteropHDC != NULL)
! {
! mGDIRT->ReleaseDC(NULL);
! mInteropHDC = NULL;
! }
! if (mDrawing)
! {
! hr = mRT->EndDraw();
! if (hr == D2DERR_RECREATE_TARGET)
! {
! hr = S_OK;
! DiscardDeviceResources();
! CreateDeviceResources();
! }
! mDrawing = false;
! }
! break;
!
! case DM_DIRECTX:
! if (mInteropHDC != NULL)
! {
! mGDIRT->ReleaseDC(NULL);
! mInteropHDC = NULL;
! }
! else if (mDrawing == false)
! {
! CreateDeviceResources();
! mRT->BeginDraw();
! mDrawing = true;
! }
! break;
!
! case DM_INTEROP:
! if (mDrawing == false)
! {
! CreateDeviceResources();
! mRT->BeginDraw();
! mDrawing = true;
! }
! if (mInteropHDC == NULL)
! hr = mGDIRT->GetDC(D2D1_DC_INITIALIZE_MODE_COPY, &mInteropHDC);
! break;
}
+ mDMode = mode;
+ return hr;
}
ID2D1Brush*
***************
*** 849,870 ****
}
void
! DWriteContext::DrawText(const WCHAR* text, int len,
int x, int y, int w, int h, int cellWidth, COLORREF color,
! UINT fuOptions, CONST RECT *lprc, CONST INT * lpDx)
{
if (mFallbackDC)
{
! Flush();
! ExtTextOutW(mHDC, x, y, fuOptions, lprc, text, len, lpDx);
return;
}
- AssureDrawing();
-
HRESULT hr;
IDWriteTextLayout *textLayout = NULL;
hr = mDWriteFactory->CreateTextLayout(text, len, mTextFormat,
FLOAT(w), FLOAT(h), &textLayout);
--- 959,989 ----
}
void
! DWriteContext::DrawText(const WCHAR *text, int len,
int x, int y, int w, int h, int cellWidth, COLORREF color,
! UINT fuOptions, const RECT *lprc, const INT *lpDx)
{
if (mFallbackDC)
{
! // Fall back to GDI rendering.
! HRESULT hr = SetDrawingMode(DM_INTEROP);
! if (SUCCEEDED(hr))
! {
! HGDIOBJ hFont = ::GetCurrentObject(mHDC, OBJ_FONT);
! HGDIOBJ hOldFont = ::SelectObject(mInteropHDC, hFont);
! ::SetTextColor(mInteropHDC, color);
! ::SetBkMode(mInteropHDC, ::GetBkMode(mHDC));
! ::ExtTextOutW(mInteropHDC, x, y, fuOptions, lprc, text, len, lpDx);
! ::SelectObject(mInteropHDC, hOldFont);
! }
return;
}
HRESULT hr;
IDWriteTextLayout *textLayout = NULL;
+ SetDrawingMode(DM_DIRECTX);
+
hr = mDWriteFactory->CreateTextLayout(text, len, mTextFormat,
FLOAT(w), FLOAT(h), &textLayout);
***************
*** 883,908 ****
}
void
! DWriteContext::FillRect(RECT *rc, COLORREF color)
{
! AssureDrawing();
! mRT->FillRectangle(
! D2D1::RectF(FLOAT(rc->left), FLOAT(rc->top),
! FLOAT(rc->right), FLOAT(rc->bottom)),
! SolidBrush(color));
}
void
! DWriteContext::Flush()
{
! if (mDrawing)
{
! mRT->EndDraw();
! mDrawing = false;
}
}
void
DWriteContext::SetRenderingParams(
const DWriteRenderingParams *params)
{
--- 1002,1078 ----
}
void
! DWriteContext::FillRect(const RECT *rc, COLORREF color)
{
! if (mDMode == DM_INTEROP)
! {
! // GDI functions are used before this call. Keep using GDI.
! // (Switching to Direct2D causes terrible slowdown.)
! HBRUSH hbr = ::CreateSolidBrush(color);
! ::FillRect(mInteropHDC, rc, hbr);
! ::DeleteObject(HGDIOBJ(hbr));
! }
! else
! {
! SetDrawingMode(DM_DIRECTX);
! mRT->FillRectangle(
! D2D1::RectF(FLOAT(rc->left), FLOAT(rc->top),
! FLOAT(rc->right), FLOAT(rc->bottom)),
! SolidBrush(color));
! }
}
void
! DWriteContext::DrawLine(int x1, int y1, int x2, int y2, COLORREF color)
{
! if (mDMode == DM_INTEROP)
{
! // GDI functions are used before this call. Keep using GDI.
! // (Switching to Direct2D causes terrible slowdown.)
! HPEN hpen = ::CreatePen(PS_SOLID, 1, color);
! HGDIOBJ old_pen = ::SelectObject(mInteropHDC, HGDIOBJ(hpen));
! ::MoveToEx(mInteropHDC, x1, y1, NULL);
! ::LineTo(mInteropHDC, x2, y2);
! ::SelectObject(mInteropHDC, old_pen);
! ::DeleteObject(HGDIOBJ(hpen));
! }
! else
! {
! SetDrawingMode(DM_DIRECTX);
! mRT->DrawLine(
! D2D1::Point2F(FLOAT(x1), FLOAT(y1) + 0.5f),
! D2D1::Point2F(FLOAT(x2), FLOAT(y2) + 0.5f),
! SolidBrush(color));
! }
! }
!
! void
! DWriteContext::SetPixel(int x, int y, COLORREF color)
! {
! if (mDMode == DM_INTEROP)
! {
! // GDI functions are used before this call. Keep using GDI.
! // (Switching to Direct2D causes terrible slowdown.)
! ::SetPixel(mInteropHDC, x, y, color);
! }
! else
! {
! SetDrawingMode(DM_DIRECTX);
! // Direct2D doesn't have SetPixel API. Use DrawLine instead.
! mRT->DrawLine(
! D2D1::Point2F(FLOAT(x), FLOAT(y) + 0.5f),
! D2D1::Point2F(FLOAT(x+1), FLOAT(y) + 0.5f),
! SolidBrush(color));
}
}
void
+ DWriteContext::Flush()
+ {
+ SetDrawingMode(DM_GDI);
+ }
+
+ void
DWriteContext::SetRenderingParams(
const DWriteRenderingParams *params)
{
***************
*** 1000,1006 ****
}
void
! DWriteContext_BindDC(DWriteContext *ctx, HDC hdc, RECT *rect)
{
if (ctx != NULL)
ctx->BindDC(hdc, rect);
--- 1170,1176 ----
}
void
! DWriteContext_BindDC(DWriteContext *ctx, HDC hdc, const RECT *rect)
{
if (ctx != NULL)
ctx->BindDC(hdc, rect);
***************
*** 1016,1022 ****
void
DWriteContext_DrawText(
DWriteContext *ctx,
! const WCHAR* text,
int len,
int x,
int y,
--- 1186,1192 ----
void
DWriteContext_DrawText(
DWriteContext *ctx,
! const WCHAR *text,
int len,
int x,
int y,
***************
*** 1025,1032 ****
int cellWidth,
COLORREF color,
UINT fuOptions,
! CONST RECT *lprc,
! CONST INT * lpDx)
{
if (ctx != NULL)
ctx->DrawText(text, len, x, y, w, h, cellWidth, color,
--- 1195,1202 ----
int cellWidth,
COLORREF color,
UINT fuOptions,
! const RECT *lprc,
! const INT *lpDx)
{
if (ctx != NULL)
ctx->DrawText(text, len, x, y, w, h, cellWidth, color,
***************
*** 1034,1046 ****
}
void
! DWriteContext_FillRect(DWriteContext *ctx, RECT *rc, COLORREF color)
{
if (ctx != NULL)
ctx->FillRect(rc, color);
}
void
DWriteContext_Flush(DWriteContext *ctx)
{
if (ctx != NULL)
--- 1204,1231 ----
}
void
! DWriteContext_FillRect(DWriteContext *ctx, const RECT *rc, COLORREF color)
{
if (ctx != NULL)
ctx->FillRect(rc, color);
}
void
+ DWriteContext_DrawLine(DWriteContext *ctx, int x1, int y1, int x2, int y2,
+ COLORREF color)
+ {
+ if (ctx != NULL)
+ ctx->DrawLine(x1, y1, x2, y2, color);
+ }
+
+ void
+ DWriteContext_SetPixel(DWriteContext *ctx, int x, int y, COLORREF color)
+ {
+ if (ctx != NULL)
+ ctx->SetPixel(x, y, color);
+ }
+
+ void
DWriteContext_Flush(DWriteContext *ctx)
{
if (ctx != NULL)
*** ../vim-8.0.1368/src/gui_dwrite.h 2017-11-26 14:29:24.847931598 +0100
--- src/gui_dwrite.h 2017-12-05 13:18:55.511425089 +0100
***************
*** 55,65 ****
void DWrite_Final(void);
DWriteContext *DWriteContext_Open(void);
! void DWriteContext_BindDC(DWriteContext *ctx, HDC hdc, RECT *rect);
void DWriteContext_SetFont(DWriteContext *ctx, HFONT hFont);
void DWriteContext_DrawText(
DWriteContext *ctx,
! const WCHAR* text,
int len,
int x,
int y,
--- 55,65 ----
void DWrite_Final(void);
DWriteContext *DWriteContext_Open(void);
! void DWriteContext_BindDC(DWriteContext *ctx, HDC hdc, const RECT *rect);
void DWriteContext_SetFont(DWriteContext *ctx, HFONT hFont);
void DWriteContext_DrawText(
DWriteContext *ctx,
! const WCHAR *text,
int len,
int x,
int y,
***************
*** 68,76 ****
int cellWidth,
COLORREF color,
UINT fuOptions,
! CONST RECT *lprc,
! CONST INT * lpDx);
! void DWriteContext_FillRect(DWriteContext *ctx, RECT *rc, COLORREF color);
void DWriteContext_Flush(DWriteContext *ctx);
void DWriteContext_Close(DWriteContext *ctx);
--- 68,79 ----
int cellWidth,
COLORREF color,
UINT fuOptions,
! const RECT *lprc,
! const INT *lpDx);
! void DWriteContext_FillRect(DWriteContext *ctx, const RECT *rc, COLORREF
color);
! void DWriteContext_DrawLine(DWriteContext *ctx, int x1, int y1, int x2, int
y2,
! COLORREF color);
! void DWriteContext_SetPixel(DWriteContext *ctx, int x, int y, COLORREF color);
void DWriteContext_Flush(DWriteContext *ctx);
void DWriteContext_Close(DWriteContext *ctx);
*** ../vim-8.0.1368/src/gui_w32.c 2017-11-27 23:24:04.837331762 +0100
--- src/gui_w32.c 2017-12-05 13:18:55.511425089 +0100
***************
*** 33,38 ****
--- 33,39 ----
static DWriteContext *s_dwc = NULL;
static int s_directx_enabled = 0;
static int s_directx_load_attempted = 0;
+ static int s_directx_scrlines = 0;
# define IS_ENABLE_DIRECTX() (s_directx_enabled && s_dwc != NULL)
static int directx_enabled(void);
static void directx_binddc(void);
***************
*** 57,62 ****
--- 58,64 ----
int dx_geom = 0;
int dx_renmode = 0;
int dx_taamode = 0;
+ int dx_scrlines = 0;
/* parse string as rendering options. */
for (p = s; p != NULL && *p != NUL; )
***************
*** 117,122 ****
--- 119,128 ----
if (dx_taamode < 0 || dx_taamode > 3)
return FAIL;
}
+ else if (STRCMP(name, "scrlines") == 0)
+ {
+ dx_scrlines = atoi((char *)value);
+ }
else
return FAIL;
}
***************
*** 147,152 ****
--- 153,159 ----
}
}
s_directx_enabled = dx_enable;
+ s_directx_scrlines = dx_scrlines;
return OK;
#else
***************
*** 283,288 ****
--- 290,296 ----
#endif
static void _OnPaint( HWND hwnd);
+ static void fill_rect(const RECT *rcp, HBRUSH hbr, COLORREF color);
static void clear_rect(RECT *rcp);
static WORD s_dlgfntheight; /* height of the dialog font */
***************
*** 605,614 ****
blink_timer = (UINT) SetTimer(NULL, 0, (UINT)blink_ontime,
(TIMERPROC)_OnBlinkTimer);
}
! #if defined(FEAT_DIRECTX)
! if (IS_ENABLE_DIRECTX())
! DWriteContext_Flush(s_dwc);
! #endif
}
static void
--- 613,619 ----
blink_timer = (UINT) SetTimer(NULL, 0, (UINT)blink_ontime,
(TIMERPROC)_OnBlinkTimer);
}
! gui_mch_flush();
}
static void
***************
*** 634,640 ****
--- 639,648 ----
{
gui_mswin_rm_blink_timer();
if (blink_state == BLINK_OFF)
+ {
gui_update_cursor(TRUE, FALSE);
+ gui_mch_flush();
+ }
blink_state = BLINK_NONE;
}
***************
*** 654,659 ****
--- 662,668 ----
(TIMERPROC)_OnBlinkTimer);
blink_state = BLINK_ON;
gui_update_cursor(TRUE, FALSE);
+ gui_mch_flush();
}
}
***************
*** 1730,1736 ****
int h,
guicolor_T color)
{
- HBRUSH hbr;
RECT rc;
/*
--- 1739,1744 ----
***************
*** 1746,1759 ****
rc.right = rc.left + w;
rc.bottom = rc.top + h;
! #if defined(FEAT_DIRECTX)
! if (IS_ENABLE_DIRECTX())
! DWriteContext_Flush(s_dwc);
! #endif
!
! hbr = CreateSolidBrush(color);
! FillRect(s_hdc, &rc, hbr);
! DeleteBrush(hbr);
}
--- 1754,1760 ----
rc.right = rc.left + w;
rc.bottom = rc.top + h;
! fill_rect(&rc, NULL, color);
}
***************
*** 3122,3134 ****
int num_lines)
{
RECT rc;
-
- intel_gpu_workaround();
-
#if defined(FEAT_DIRECTX)
! // Commit drawing queue before ScrollWindowEx.
! if (IS_ENABLE_DIRECTX())
! DWriteContext_Flush(s_dwc);
#endif
rc.left = FILL_X(gui.scroll_region_left);
--- 3123,3130 ----
int num_lines)
{
RECT rc;
#if defined(FEAT_DIRECTX)
! int use_redraw = 0;
#endif
rc.left = FILL_X(gui.scroll_region_left);
***************
*** 3136,3143 ****
rc.top = FILL_Y(row);
rc.bottom = FILL_Y(gui.scroll_region_bot + 1);
! ScrollWindowEx(s_textArea, 0, -num_lines * gui.char_height,
&rc, &rc, NULL, NULL, get_scroll_flags());
UpdateWindow(s_textArea);
/* This seems to be required to avoid the cursor disappearing when
--- 3132,3155 ----
rc.top = FILL_Y(row);
rc.bottom = FILL_Y(gui.scroll_region_bot + 1);
! #if defined(FEAT_DIRECTX)
! if (IS_ENABLE_DIRECTX())
! {
! if (s_directx_scrlines > 0 && s_directx_scrlines <= num_lines)
! {
! RedrawWindow(s_textArea, &rc, NULL, RDW_INVALIDATE);
! use_redraw = 1;
! }
! else
! DWriteContext_Flush(s_dwc);
! }
! if (!use_redraw)
! #endif
! {
! intel_gpu_workaround();
! ScrollWindowEx(s_textArea, 0, -num_lines * gui.char_height,
&rc, &rc, NULL, NULL, get_scroll_flags());
+ }
UpdateWindow(s_textArea);
/* This seems to be required to avoid the cursor disappearing when
***************
*** 3161,3183 ****
int num_lines)
{
RECT rc;
-
- intel_gpu_workaround();
-
#if defined(FEAT_DIRECTX)
! // Commit drawing queue before ScrollWindowEx.
! if (IS_ENABLE_DIRECTX())
! DWriteContext_Flush(s_dwc);
#endif
rc.left = FILL_X(gui.scroll_region_left);
rc.right = FILL_X(gui.scroll_region_right + 1);
rc.top = FILL_Y(row);
rc.bottom = FILL_Y(gui.scroll_region_bot + 1);
! /* The SW_INVALIDATE is required when part of the window is covered or
! * off-screen. How do we avoid it when it's not needed? */
! ScrollWindowEx(s_textArea, 0, num_lines * gui.char_height,
&rc, &rc, NULL, NULL, get_scroll_flags());
UpdateWindow(s_textArea);
--- 3173,3207 ----
int num_lines)
{
RECT rc;
#if defined(FEAT_DIRECTX)
! int use_redraw = 0;
#endif
rc.left = FILL_X(gui.scroll_region_left);
rc.right = FILL_X(gui.scroll_region_right + 1);
rc.top = FILL_Y(row);
rc.bottom = FILL_Y(gui.scroll_region_bot + 1);
!
! #if defined(FEAT_DIRECTX)
! if (IS_ENABLE_DIRECTX())
! {
! if (s_directx_scrlines > 0 && s_directx_scrlines <= num_lines)
! {
! RedrawWindow(s_textArea, &rc, NULL, RDW_INVALIDATE);
! use_redraw = 1;
! }
! else
! DWriteContext_Flush(s_dwc);
! }
! if (!use_redraw)
! #endif
! {
! intel_gpu_workaround();
! /* The SW_INVALIDATE is required when part of the window is covered or
! * off-screen. How do we avoid it when it's not needed? */
! ScrollWindowEx(s_textArea, 0, num_lines * gui.char_height,
&rc, &rc, NULL, NULL, get_scroll_flags());
+ }
UpdateWindow(s_textArea);
***************
*** 5853,5858 ****
--- 5877,5883 ----
}
}
gui_update_cursor(TRUE, FALSE);
+ gui_mch_flush();
lResult = 0;
break;
}
***************
*** 6181,6186 ****
--- 6206,6272 ----
}
#endif
+ static void
+ draw_line(
+ int x1,
+ int y1,
+ int x2,
+ int y2,
+ COLORREF color)
+ {
+ #if defined(FEAT_DIRECTX)
+ if (IS_ENABLE_DIRECTX())
+ DWriteContext_DrawLine(s_dwc, x1, y1, x2, y2, color);
+ else
+ #endif
+ {
+ HPEN hpen = CreatePen(PS_SOLID, 1, color);
+ HPEN old_pen = SelectObject(s_hdc, hpen);
+ MoveToEx(s_hdc, x1, y1, NULL);
+ /* Note: LineTo() excludes the last pixel in the line. */
+ LineTo(s_hdc, x2, y2);
+ DeleteObject(SelectObject(s_hdc, old_pen));
+ }
+ }
+
+ static void
+ set_pixel(
+ int x,
+ int y,
+ COLORREF color)
+ {
+ #if defined(FEAT_DIRECTX)
+ if (IS_ENABLE_DIRECTX())
+ DWriteContext_SetPixel(s_dwc, x, y, color);
+ else
+ #endif
+ SetPixel(s_hdc, x, y, color);
+ }
+
+ static void
+ fill_rect(
+ const RECT *rcp,
+ HBRUSH hbr,
+ COLORREF color)
+ {
+ #if defined(FEAT_DIRECTX)
+ if (IS_ENABLE_DIRECTX())
+ DWriteContext_FillRect(s_dwc, rcp, color);
+ else
+ #endif
+ {
+ HBRUSH hbr2;
+
+ if (hbr == NULL)
+ hbr2 = CreateSolidBrush(color);
+ else
+ hbr2 = hbr;
+ FillRect(s_hdc, rcp, hbr2);
+ if (hbr == NULL)
+ DeleteBrush(hbr2);
+ }
+ }
+
void
gui_mch_draw_string(
int row,
***************
*** 6200,6206 ****
static int unibuflen = 0;
int n = 0;
#endif
- HPEN hpen, old_pen;
int y;
/*
--- 6286,6291 ----
***************
*** 6263,6273 ****
brush_lru = !brush_lru;
}
! #if defined(FEAT_DIRECTX)
! if (IS_ENABLE_DIRECTX())
! DWriteContext_FillRect(s_dwc, &rc, gui.currBgColor);
! #endif
! FillRect(s_hdc, &rc, hbr);
SetBkMode(s_hdc, TRANSPARENT);
--- 6348,6354 ----
brush_lru = !brush_lru;
}
! fill_rect(&rc, hbr, gui.currBgColor);
SetBkMode(s_hdc, TRANSPARENT);
***************
*** 6462,6499 ****
foptions, pcliprect, (char *)text, len, padding);
}
- #if defined(FEAT_DIRECTX)
- if (IS_ENABLE_DIRECTX() &&
- (flags & (DRAW_UNDERL | DRAW_STRIKE | DRAW_UNDERC | DRAW_CURSOR)))
- DWriteContext_Flush(s_dwc);
- #endif
-
/* Underline */
if (flags & DRAW_UNDERL)
{
- hpen = CreatePen(PS_SOLID, 1, gui.currFgColor);
- old_pen = SelectObject(s_hdc, hpen);
/* When p_linespace is 0, overwrite the bottom row of pixels.
* Otherwise put the line just below the character. */
y = FILL_Y(row + 1) - 1;
if (p_linespace > 1)
y -= p_linespace - 1;
! MoveToEx(s_hdc, FILL_X(col), y, NULL);
! /* Note: LineTo() excludes the last pixel in the line. */
! LineTo(s_hdc, FILL_X(col + len), y);
! DeleteObject(SelectObject(s_hdc, old_pen));
}
/* Strikethrough */
if (flags & DRAW_STRIKE)
{
- hpen = CreatePen(PS_SOLID, 1, gui.currSpColor);
- old_pen = SelectObject(s_hdc, hpen);
y = FILL_Y(row + 1) - gui.char_height/2;
! MoveToEx(s_hdc, FILL_X(col), y, NULL);
! /* Note: LineTo() excludes the last pixel in the line. */
! LineTo(s_hdc, FILL_X(col + len), y);
! DeleteObject(SelectObject(s_hdc, old_pen));
}
/* Undercurl */
--- 6543,6564 ----
foptions, pcliprect, (char *)text, len, padding);
}
/* Underline */
if (flags & DRAW_UNDERL)
{
/* When p_linespace is 0, overwrite the bottom row of pixels.
* Otherwise put the line just below the character. */
y = FILL_Y(row + 1) - 1;
if (p_linespace > 1)
y -= p_linespace - 1;
! draw_line(FILL_X(col), y, FILL_X(col + len), y, gui.currFgColor);
}
/* Strikethrough */
if (flags & DRAW_STRIKE)
{
y = FILL_Y(row + 1) - gui.char_height/2;
! draw_line(FILL_X(col), y, FILL_X(col + len), y, gui.currSpColor);
}
/* Undercurl */
***************
*** 6507,6513 ****
for (x = FILL_X(col); x < FILL_X(col + len); ++x)
{
offset = val[x % 8];
! SetPixel(s_hdc, x, y - offset, gui.currSpColor);
}
}
}
--- 6572,6578 ----
for (x = FILL_X(col); x < FILL_X(col + len); ++x)
{
offset = val[x % 8];
! set_pixel(x, y - offset, gui.currSpColor);
}
}
}
***************
*** 6541,6559 ****
static void
clear_rect(RECT *rcp)
{
! HBRUSH hbr;
!
! #if defined(FEAT_DIRECTX)
! if (IS_ENABLE_DIRECTX())
! {
! DWriteContext_FillRect(s_dwc, rcp, gui.back_pixel);
! return;
! }
! #endif
!
! hbr = CreateSolidBrush(gui.back_pixel);
! FillRect(s_hdc, rcp, hbr);
! DeleteBrush(hbr);
}
--- 6606,6612 ----
static void
clear_rect(RECT *rcp)
{
! fill_rect(rcp, NULL, gui.back_pixel);
}
*** ../vim-8.0.1368/src/version.c 2017-12-05 13:06:12.279454348 +0100
--- src/version.c 2017-12-05 13:19:34.047220806 +0100
***************
*** 773,774 ****
--- 773,776 ----
{ /* Add new patch number below this line */
+ /**/
+ 1369,
/**/
--
hundred-and-one symptoms of being an internet addict:
81. At social functions you introduce your husband as "my domain server."
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.