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:
204
src/gui_w32.c
204
src/gui_w32.c
@@ -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, ¶m);
|
||||
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, ¶m);
|
||||
}
|
||||
}
|
||||
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));
|
||||
|
Reference in New Issue
Block a user