0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

updated for version 7.4.393

Problem:    Text drawing on newer MS-Windows systems is suboptimal.  Some
            multi-byte characters are not displayed, even though the same font
            in Notepad can display them. (Srinath Avadhanula)
Solution:   Add the 'renderoptions' option to enable Direct-X drawing. (Taro
            Muraoka)
This commit is contained in:
Bram Moolenaar
2014-08-06 14:52:30 +02:00
parent 8c1329cb59
commit b5a7a8b545
16 changed files with 1390 additions and 23 deletions

View File

@@ -25,6 +25,145 @@
#include "vim.h"
#if defined(FEAT_DIRECTX)
# include "gui_dwrite.h"
#endif
#if defined(FEAT_DIRECTX) || defined(PROTO)
static DWriteContext *s_dwc = NULL;
static int s_directx_enabled = 0;
static int s_directx_load_attempted = 0;
# define IS_ENABLE_DIRECTX() (s_directx_enabled && s_dwc != NULL)
int
directx_enabled(void)
{
if (s_dwc != NULL)
return 1;
else if (s_directx_load_attempted)
return 0;
/* load DirectX */
DWrite_Init();
s_directx_load_attempted = 1;
s_dwc = DWriteContext_Open();
return s_dwc != NULL ? 1 : 0;
}
#endif
#if defined(FEAT_RENDER_OPTIONS) || defined(PROTO)
int
gui_mch_set_rendering_options(char_u *s)
{
#ifdef FEAT_DIRECTX
int retval = FAIL;
char_u *p, *q;
int dx_enable = 0;
int dx_flags = 0;
float dx_gamma = 0.0f;
float dx_contrast = 0.0f;
float dx_level = 0.0f;
int dx_geom = 0;
int dx_renmode = 0;
int dx_taamode = 0;
/* parse string as rendering options. */
for (p = s; p != NULL && *p != NUL; )
{
char_u item[256];
char_u name[128];
char_u value[128];
copy_option_part(&p, item, sizeof(item), ",");
if (p == NULL)
break;
q = &item[0];
copy_option_part(&q, name, sizeof(name), ":");
if (q == NULL)
return FAIL;
copy_option_part(&q, value, sizeof(value), ":");
if (STRCMP(name, "type") == 0)
{
if (STRCMP(value, "directx") == 0)
dx_enable = 1;
else
return FAIL;
}
else if (STRCMP(name, "gamma") == 0)
{
dx_flags |= 1 << 0;
dx_gamma = (float)atof(value);
}
else if (STRCMP(name, "contrast") == 0)
{
dx_flags |= 1 << 1;
dx_contrast = (float)atof(value);
}
else if (STRCMP(name, "level") == 0)
{
dx_flags |= 1 << 2;
dx_level = (float)atof(value);
}
else if (STRCMP(name, "geom") == 0)
{
dx_flags |= 1 << 3;
dx_geom = atoi(value);
if (dx_geom < 0 || dx_geom > 2)
return FAIL;
}
else if (STRCMP(name, "renmode") == 0)
{
dx_flags |= 1 << 4;
dx_renmode = atoi(value);
if (dx_renmode < 0 || dx_renmode > 6)
return FAIL;
}
else if (STRCMP(name, "taamode") == 0)
{
dx_flags |= 1 << 5;
dx_taamode = atoi(value);
if (dx_taamode < 0 || dx_taamode > 3)
return FAIL;
}
else
return FAIL;
}
/* Enable DirectX/DirectWrite */
if (dx_enable)
{
if (!directx_enabled())
return FAIL;
DWriteContext_SetRenderingParams(s_dwc, NULL);
if (dx_flags)
{
DWriteRenderingParams param;
DWriteContext_GetRenderingParams(s_dwc, &param);
if (dx_flags & (1 << 0))
param.gamma = dx_gamma;
if (dx_flags & (1 << 1))
param.enhancedContrast = dx_contrast;
if (dx_flags & (1 << 2))
param.clearTypeLevel = dx_level;
if (dx_flags & (1 << 3))
param.pixelGeometry = dx_geom;
if (dx_flags & (1 << 4))
param.renderingMode = dx_renmode;
if (dx_flags & (1 << 5))
param.textAntialiasMode = dx_taamode;
DWriteContext_SetRenderingParams(s_dwc, &param);
}
}
s_directx_enabled = dx_enable;
return OK;
#else
return FAIL;
#endif
}
#endif
/*
* These are new in Windows ME/XP, only defined in recent compilers.
*/
@@ -1624,6 +1763,11 @@ gui_mch_init(void)
set_vim_var_nr(VV_WINDOWID, HandleToLong(s_hwnd));
#endif
#ifdef FEAT_RENDER_OPTIONS
if (p_rop)
(void)gui_mch_set_rendering_options(p_rop);
#endif
theend:
/* Display any pending error messages */
display_errors();
@@ -1695,9 +1839,9 @@ gui_mch_set_shellsize(int width, int height,
/* compute the size of the outside of the window */
win_width = width + (GetSystemMetrics(SM_CXFRAME) +
GetSystemMetrics(SM_CXPADDEDBORDER)) * 2;
GetSystemMetrics(SM_CXPADDEDBORDER)) * 2;
win_height = height + (GetSystemMetrics(SM_CYFRAME) +
GetSystemMetrics(SM_CXPADDEDBORDER)) * 2
GetSystemMetrics(SM_CXPADDEDBORDER)) * 2
+ GetSystemMetrics(SM_CYCAPTION)
#ifdef FEAT_MENU
+ gui_mswin_get_menu_height(FALSE)
@@ -2239,6 +2383,9 @@ gui_mch_draw_string(
#endif
HPEN hpen, old_pen;
int y;
#ifdef FEAT_DIRECTX
int font_is_ttf_or_vector = 0;
#endif
#ifndef MSWIN16_FASTTEXT
/*
@@ -2326,6 +2473,20 @@ gui_mch_draw_string(
SetTextColor(s_hdc, gui.currFgColor);
SelectFont(s_hdc, gui.currFont);
#ifdef FEAT_DIRECTX
if (IS_ENABLE_DIRECTX())
{
TEXTMETRIC tm;
GetTextMetrics(s_hdc, &tm);
if (tm.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR))
{
font_is_ttf_or_vector = 1;
DWriteContext_SetFont(s_dwc, (HFONT)gui.currFont);
}
}
#endif
if (pad_size != Columns || padding == NULL || padding[0] != gui.char_width)
{
vim_free(padding);
@@ -2360,6 +2521,14 @@ gui_mch_draw_string(
if (text[n] >= 0x80)
break;
#if defined(FEAT_DIRECTX)
/* Quick hack to enable DirectWrite. To use DirectWrite (antialias), it is
* required that unicode drawing routine, currently. So this forces it
* enabled. */
if (enc_utf8 && IS_ENABLE_DIRECTX())
n = 0; /* Keep n < len, to enter block for unicode. */
#endif
/* 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
* characters is always equal or smaller. */
@@ -2418,8 +2587,17 @@ gui_mch_draw_string(
i += utfc_ptr2len_len(text + i, len - i);
++clen;
}
ExtTextOutW(s_hdc, TEXT_X(col), TEXT_Y(row),
foptions, pcliprect, unicodebuf, wlen, unicodepdy);
#if defined(FEAT_DIRECTX)
if (IS_ENABLE_DIRECTX() && font_is_ttf_or_vector)
{
DWriteContext_DrawText(s_dwc, s_hdc, unicodebuf, wlen,
TEXT_X(col), TEXT_Y(row), FILL_X(cells), FILL_Y(1),
gui.char_width, gui.currFgColor);
}
else
#endif
ExtTextOutW(s_hdc, TEXT_X(col), TEXT_Y(row),
foptions, pcliprect, unicodebuf, wlen, unicodepdy);
len = cells; /* used for underlining */
}
else if ((enc_codepage > 0 && (int)GetACP() != enc_codepage) || enc_latin9)
@@ -2549,14 +2727,14 @@ gui_mch_get_screen_dimensions(int *screen_w, int *screen_h)
*screen_w = workarea_rect.right - workarea_rect.left
- (GetSystemMetrics(SM_CXFRAME) +
GetSystemMetrics(SM_CXPADDEDBORDER)) * 2;
GetSystemMetrics(SM_CXPADDEDBORDER)) * 2;
/* FIXME: dirty trick: Because the gui_get_base_height() doesn't include
* the menubar for MSwin, we subtract it from the screen height, so that
* the window size can be made to fit on the screen. */
*screen_h = workarea_rect.bottom - workarea_rect.top
- (GetSystemMetrics(SM_CYFRAME) +
GetSystemMetrics(SM_CXPADDEDBORDER)) * 2
GetSystemMetrics(SM_CXPADDEDBORDER)) * 2
- GetSystemMetrics(SM_CYCAPTION)
#ifdef FEAT_MENU
- gui_mswin_get_menu_height(FALSE)
@@ -3188,13 +3366,13 @@ gui_mch_dialog(
GetWindowRect(s_hwnd, &rect);
maxDialogWidth = rect.right - rect.left
- (GetSystemMetrics(SM_CXFRAME) +
GetSystemMetrics(SM_CXPADDEDBORDER)) * 2;
GetSystemMetrics(SM_CXPADDEDBORDER)) * 2;
if (maxDialogWidth < DLG_MIN_MAX_WIDTH)
maxDialogWidth = DLG_MIN_MAX_WIDTH;
maxDialogHeight = rect.bottom - rect.top
- (GetSystemMetrics(SM_CYFRAME) +
GetSystemMetrics(SM_CXPADDEDBORDER)) * 4
GetSystemMetrics(SM_CXPADDEDBORDER)) * 4
- GetSystemMetrics(SM_CYCAPTION);
if (maxDialogHeight < DLG_MIN_MAX_HEIGHT)
maxDialogHeight = DLG_MIN_MAX_HEIGHT;
@@ -3351,11 +3529,11 @@ gui_mch_dialog(
/* Restrict the size to a maximum. Causes a scrollbar to show up. */
if (dlgheight > maxDialogHeight)
{
msgheight = msgheight - (dlgheight - maxDialogHeight);
dlgheight = maxDialogHeight;
scroll_flag = WS_VSCROLL;
/* Make sure scrollbar doesn't appear in the middle of the dialog */
messageWidth = dlgwidth - DLG_ICON_WIDTH - 3 * dlgPaddingX;
msgheight = msgheight - (dlgheight - maxDialogHeight);
dlgheight = maxDialogHeight;
scroll_flag = WS_VSCROLL;
/* Make sure scrollbar doesn't appear in the middle of the dialog */
messageWidth = dlgwidth - DLG_ICON_WIDTH - 3 * dlgPaddingX;
}
add_word(PixelToDialogY(dlgheight));