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)
diff --git a/src/gui_w32.c b/src/gui_w32.c
index 2d57fbb..b428172 100644
--- a/src/gui_w32.c
+++ b/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, &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 @@
     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 @@
 
     /* 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 @@
 #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 @@
     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 @@
 	    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 @@
 	    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 @@
 
     *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 @@
 	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 @@
     /* 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));