0
0
mirror of https://github.com/vim/vim.git synced 2025-07-04 23:07:33 -04:00

patch 8.0.1390: DirectX scrolling can be slow, vertical positioning is off

Problem:    DirectX scrolling can be slow, vertical positioning is off.
Solution:   Make scroll slightly faster when using "scrlines:1". Fix y
            position of displayed text. Fix DirectX with non-utf8 encoding.
            (Ken Takata, closes #2440)
This commit is contained in:
Bram Moolenaar 2017-12-14 13:15:19 +01:00
parent a6d4849c71
commit 7f88b65f6c
6 changed files with 89 additions and 28 deletions

View File

@ -34,10 +34,11 @@ Contents:
11. Building with Ruby support 11. Building with Ruby support
12. Building with Tcl support 12. Building with Tcl support
13. Building with Terminal support 13. Building with Terminal support
14. Windows 3.1 14. Building with DirectX (DirectWrite) support
15. MS-DOS 15. Windows 3.1
16. MS-DOS
16. Installing after building from sources 17. Installing after building from sources
The currently recommended way (that means it has been verified to work) is The currently recommended way (that means it has been verified to work) is
@ -787,25 +788,59 @@ E.g. When using MSVC:
nmake -f Make_mvc.mak TERMINAL=yes nmake -f Make_mvc.mak TERMINAL=yes
Or when using MinGW (as one line): Or when using MinGW:
mingw32-make -f Make_ming.mak TERMINAL=yes mingw32-make -f Make_ming.mak TERMINAL=yes
14. Windows 3.1x 14. Building with DirectX (DirectWrite) support
===============================================
Vim with DirectX (DirectWrite) support can be built with either MSVC or MinGW.
This requires dwrite_2.h and some other header files which come with Windows
SDK 8.1 or later (or MinGW-w64), if you want to enable color emoji support.
This also requires MBYTE=yes which is enabled by default.
A) Using MSVC
If you use MSVC 2013 or later, Windows SDK 8.1 or later is used by default.
You just need to specify DIRECTX=yes:
nmake -f Make_mvc.mak DIRECTX=yes
If you use MSVC 2012 or earlier, the required header files are not available
by default. However, you can use the header files from newer SDKs with older
compilers. E.g.:
set "INCLUDE=%INCLUDE%;C:\Program Files (x86)\Windows Kits\8.1\Include\um"
nmake -f Make_mvc.mak DIRECTX=yes
If you don't need color emoji support, only dwrite.h is required. You can use
older compilers (e.g. VC2010) without Windows SDK 8.1. E.g.:
nmake -f Make_mvc.mak DIRECTX=yes COLOR_EMOJI=no
B) Using MinGW-w64
Just set DIRECTX to yes:
mingw32-make -f Make_ming.mak DIRECTX=yes
15. Windows 3.1x
================ ================
The Windows 3.1x support was removed in patch 7.4.1364. The Windows 3.1x support was removed in patch 7.4.1364.
15. MS-DOS 16. MS-DOS
========== ==========
The MS-DOS support was removed in patch 7.4.1399. Only very old Vim versions The MS-DOS support was removed in patch 7.4.1399. Only very old Vim versions
work on MS-DOS because of the limited amount of memory available. work on MS-DOS because of the limited amount of memory available.
16. Installing after building from sources 17. Installing after building from sources
========================================== ==========================================
[provided by Michael Soyka, updated by Ken Takata] [provided by Michael Soyka, updated by Ken Takata]

View File

@ -588,7 +588,7 @@ endif
ifeq ($(DIRECTX),yes) ifeq ($(DIRECTX),yes)
# Only allow DirectWrite for a GUI build. # Only allow DirectWrite for a GUI build.
ifeq (yes, $(GUI)) ifeq (yes, $(GUI))
DEFINES += -DFEAT_DIRECTX -DDYNAMIC_DIRECTX DEFINES += -DFEAT_DIRECTX -DDYNAMIC_DIRECTX -DFEAT_DIRECTX_COLOR_EMOJI
endif endif
endif endif

View File

@ -25,12 +25,15 @@
# #
# GUI interface: GUI=yes (default is no) # GUI interface: GUI=yes (default is no)
# #
# GUI with DirectWrite(DirectX): DIRECTX=yes # GUI with DirectWrite (DirectX): DIRECTX=yes
# (default is no, requires GUI=yes) # (default is no, requires GUI=yes and MBYTE=yes)
#
# Color emoji support: COLOR_EMOJI=yes
# (default is yes if DIRECTX=yes, requires WinSDK 8.1 or later.)
# #
# OLE interface: OLE=yes (usually with GUI=yes) # OLE interface: OLE=yes (usually with GUI=yes)
# #
# Multibyte support: MBYTE=yes (default is no) # Multibyte support: MBYTE=yes (default is yes for NORMAL, BIG, HUGE)
# #
# IME support: IME=yes (requires GUI=yes) # IME support: IME=yes (requires GUI=yes)
# DYNAMIC_IME=[yes or no] (to load the imm32.dll dynamically, default # DYNAMIC_IME=[yes or no] (to load the imm32.dll dynamically, default
@ -419,9 +422,12 @@ NBDEBUG_SRC = nbdebug.c
NETBEANS_LIB = WSock32.lib NETBEANS_LIB = WSock32.lib
!endif !endif
# DirectWrite(DirectX) # DirectWrite (DirectX)
!if "$(DIRECTX)" == "yes" !if "$(DIRECTX)" == "yes"
DIRECTX_DEFS = -DFEAT_DIRECTX -DDYNAMIC_DIRECTX DIRECTX_DEFS = -DFEAT_DIRECTX -DDYNAMIC_DIRECTX
!if "$(COLOR_EMOJI)" != "no"
DIRECTX_DEFS = $(DIRECTX_DEFS) -DFEAT_DIRECTX_COLOR_EMOJI
!endif
DIRECTX_INCL = gui_dwrite.h DIRECTX_INCL = gui_dwrite.h
DIRECTX_OBJ = $(OUTDIR)\gui_dwrite.obj DIRECTX_OBJ = $(OUTDIR)\gui_dwrite.obj
!endif !endif

View File

@ -38,7 +38,11 @@
# define _Outptr_ # define _Outptr_
#endif #endif
#include <dwrite_2.h> #ifdef FEAT_DIRECTX_COLOR_EMOJI
# include <dwrite_2.h>
#else
# include <dwrite.h>
#endif
#include "gui_dwrite.h" #include "gui_dwrite.h"
@ -284,7 +288,9 @@ struct DWriteContext {
ID2D1SolidColorBrush *mBrush; ID2D1SolidColorBrush *mBrush;
IDWriteFactory *mDWriteFactory; IDWriteFactory *mDWriteFactory;
#ifdef FEAT_DIRECTX_COLOR_EMOJI
IDWriteFactory2 *mDWriteFactory2; IDWriteFactory2 *mDWriteFactory2;
#endif
IDWriteGdiInterop *mGdiInterop; IDWriteGdiInterop *mGdiInterop;
IDWriteRenderingParams *mRenderingParams; IDWriteRenderingParams *mRenderingParams;
@ -481,6 +487,7 @@ public:
AdjustedGlyphRun adjustedGlyphRun(glyphRun, context->cellWidth, AdjustedGlyphRun adjustedGlyphRun(glyphRun, context->cellWidth,
context->offsetX); context->offsetX);
#ifdef FEAT_DIRECTX_COLOR_EMOJI
if (pDWC_->mDWriteFactory2 != NULL) if (pDWC_->mDWriteFactory2 != NULL)
{ {
IDWriteColorGlyphRunEnumerator *enumerator = NULL; IDWriteColorGlyphRunEnumerator *enumerator = NULL;
@ -517,6 +524,7 @@ public:
return S_OK; return S_OK;
} }
} }
#endif
// Draw by IDWriteFactory (without color emoji) // Draw by IDWriteFactory (without color emoji)
pDWC_->mRT->DrawGlyphRun( pDWC_->mRT->DrawGlyphRun(
@ -589,7 +597,9 @@ DWriteContext::DWriteContext() :
mGDIRT(NULL), mGDIRT(NULL),
mBrush(NULL), mBrush(NULL),
mDWriteFactory(NULL), mDWriteFactory(NULL),
#ifdef FEAT_DIRECTX_COLOR_EMOJI
mDWriteFactory2(NULL), mDWriteFactory2(NULL),
#endif
mGdiInterop(NULL), mGdiInterop(NULL),
mRenderingParams(NULL), mRenderingParams(NULL),
mFontCache(8), mFontCache(8),
@ -618,6 +628,7 @@ DWriteContext::DWriteContext() :
mDWriteFactory); mDWriteFactory);
} }
#ifdef FEAT_DIRECTX_COLOR_EMOJI
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
DWriteCreateFactory( DWriteCreateFactory(
@ -626,6 +637,7 @@ DWriteContext::DWriteContext() :
reinterpret_cast<IUnknown**>(&mDWriteFactory2)); reinterpret_cast<IUnknown**>(&mDWriteFactory2));
_RPT1(_CRT_WARN, "IDWriteFactory2: %s\n", SUCCEEDED(hr) ? "available" : "not available"); _RPT1(_CRT_WARN, "IDWriteFactory2: %s\n", SUCCEEDED(hr) ? "available" : "not available");
} }
#endif
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
@ -647,7 +659,9 @@ DWriteContext::~DWriteContext()
SafeRelease(&mRenderingParams); SafeRelease(&mRenderingParams);
SafeRelease(&mGdiInterop); SafeRelease(&mGdiInterop);
SafeRelease(&mDWriteFactory); SafeRelease(&mDWriteFactory);
#ifdef FEAT_DIRECTX_COLOR_EMOJI
SafeRelease(&mDWriteFactory2); SafeRelease(&mDWriteFactory2);
#endif
SafeRelease(&mBrush); SafeRelease(&mBrush);
SafeRelease(&mGDIRT); SafeRelease(&mGDIRT);
SafeRelease(&mRT); SafeRelease(&mRT);
@ -995,7 +1009,7 @@ DWriteContext::DrawText(const WCHAR *text, int len,
TextRenderer renderer(this); TextRenderer renderer(this);
TextRendererContext context = { color, FLOAT(cellWidth), 0.0f }; TextRendererContext context = { color, FLOAT(cellWidth), 0.0f };
textLayout->Draw(&context, &renderer, FLOAT(x), FLOAT(y)); textLayout->Draw(&context, &renderer, FLOAT(x), FLOAT(y) - 0.5f);
} }
SafeRelease(&textLayout); SafeRelease(&textLayout);

View File

@ -30,11 +30,14 @@
#endif #endif
#if defined(FEAT_DIRECTX) #if defined(FEAT_DIRECTX)
# ifndef FEAT_MBYTE
# error FEAT_MBYTE is required for FEAT_DIRECTX.
# endif
static DWriteContext *s_dwc = NULL; static DWriteContext *s_dwc = NULL;
static int s_directx_enabled = 0; static int s_directx_enabled = 0;
static int s_directx_load_attempted = 0; static int s_directx_load_attempted = 0;
static int s_directx_scrlines = 0; static int s_directx_scrlines = 0;
# define IS_ENABLE_DIRECTX() (s_directx_enabled && s_dwc != NULL) # define IS_ENABLE_DIRECTX() (s_directx_enabled && s_dwc != NULL && enc_utf8)
static int directx_enabled(void); static int directx_enabled(void);
static void directx_binddc(void); static void directx_binddc(void);
#endif #endif
@ -47,7 +50,7 @@ static int gui_mswin_get_menu_height(int fix_window);
int int
gui_mch_set_rendering_options(char_u *s) gui_mch_set_rendering_options(char_u *s)
{ {
#ifdef FEAT_DIRECTX # ifdef FEAT_DIRECTX
char_u *p, *q; char_u *p, *q;
int dx_enable = 0; int dx_enable = 0;
@ -159,9 +162,9 @@ gui_mch_set_rendering_options(char_u *s)
s_directx_scrlines = dx_scrlines; s_directx_scrlines = dx_scrlines;
return OK; return OK;
#else # else
return FAIL; return FAIL;
#endif # endif
} }
#endif #endif
@ -3140,7 +3143,8 @@ gui_mch_delete_lines(
{ {
if (s_directx_scrlines > 0 && s_directx_scrlines <= num_lines) if (s_directx_scrlines > 0 && s_directx_scrlines <= num_lines)
{ {
RedrawWindow(s_textArea, &rc, NULL, RDW_INVALIDATE); gui_redraw(rc.left, rc.top,
rc.right - rc.left + 1, rc.bottom - rc.top + 1);
use_redraw = 1; use_redraw = 1;
} }
else else
@ -3152,9 +3156,9 @@ gui_mch_delete_lines(
intel_gpu_workaround(); intel_gpu_workaround();
ScrollWindowEx(s_textArea, 0, -num_lines * gui.char_height, ScrollWindowEx(s_textArea, 0, -num_lines * gui.char_height,
&rc, &rc, NULL, NULL, get_scroll_flags()); &rc, &rc, NULL, NULL, get_scroll_flags());
UpdateWindow(s_textArea);
} }
UpdateWindow(s_textArea);
/* This seems to be required to avoid the cursor disappearing when /* This seems to be required to avoid the cursor disappearing when
* scrolling such that the cursor ends up in the top-left character on * scrolling such that the cursor ends up in the top-left character on
* the screen... But why? (Webb) */ * the screen... But why? (Webb) */
@ -3190,7 +3194,8 @@ gui_mch_insert_lines(
{ {
if (s_directx_scrlines > 0 && s_directx_scrlines <= num_lines) if (s_directx_scrlines > 0 && s_directx_scrlines <= num_lines)
{ {
RedrawWindow(s_textArea, &rc, NULL, RDW_INVALIDATE); gui_redraw(rc.left, rc.top,
rc.right - rc.left + 1, rc.bottom - rc.top + 1);
use_redraw = 1; use_redraw = 1;
} }
else else
@ -3204,10 +3209,9 @@ gui_mch_insert_lines(
* off-screen. How do we avoid it when it's not needed? */ * off-screen. How do we avoid it when it's not needed? */
ScrollWindowEx(s_textArea, 0, num_lines * gui.char_height, ScrollWindowEx(s_textArea, 0, num_lines * gui.char_height,
&rc, &rc, NULL, NULL, get_scroll_flags()); &rc, &rc, NULL, NULL, get_scroll_flags());
UpdateWindow(s_textArea);
} }
UpdateWindow(s_textArea);
gui_clear_block(row, gui.scroll_region_left, gui_clear_block(row, gui.scroll_region_left,
row + num_lines - 1, gui.scroll_region_right); row + num_lines - 1, gui.scroll_region_right);
} }
@ -6401,13 +6405,13 @@ gui_mch_draw_string(
if (text[n] >= 0x80) if (text[n] >= 0x80)
break; break;
#if defined(FEAT_DIRECTX) # if defined(FEAT_DIRECTX)
/* Quick hack to enable DirectWrite. To use DirectWrite (antialias), it is /* Quick hack to enable DirectWrite. To use DirectWrite (antialias), it is
* required that unicode drawing routine, currently. So this forces it * required that unicode drawing routine, currently. So this forces it
* enabled. */ * enabled. */
if (enc_utf8 && IS_ENABLE_DIRECTX()) if (IS_ENABLE_DIRECTX())
n = 0; /* Keep n < len, to enter block for unicode. */ n = 0; /* Keep n < len, to enter block for unicode. */
#endif # endif
/* Check if the Unicode buffer exists and is big enough. Create it /* Check if the Unicode buffer exists and is big enough. Create it
* with the same length as the multi-byte string, the number of wide * with the same length as the multi-byte string, the number of wide
@ -6480,7 +6484,7 @@ gui_mch_draw_string(
i += utf_ptr2len_len(text + i, len - i); i += utf_ptr2len_len(text + i, len - i);
++clen; ++clen;
} }
#if defined(FEAT_DIRECTX) # if defined(FEAT_DIRECTX)
if (IS_ENABLE_DIRECTX()) if (IS_ENABLE_DIRECTX())
{ {
/* Add one to "cells" for italics. */ /* Add one to "cells" for italics. */
@ -6490,7 +6494,7 @@ gui_mch_draw_string(
foptions, pcliprect, unicodepdy); foptions, pcliprect, unicodepdy);
} }
else else
#endif # endif
ExtTextOutW(s_hdc, TEXT_X(col), TEXT_Y(row), ExtTextOutW(s_hdc, TEXT_X(col), TEXT_Y(row),
foptions, pcliprect, unicodebuf, wlen, unicodepdy); foptions, pcliprect, unicodebuf, wlen, unicodepdy);
len = cells; /* used for underlining */ len = cells; /* used for underlining */

View File

@ -771,6 +771,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1390,
/**/ /**/
1389, 1389,
/**/ /**/