changeset 5714:22d7af9ff3e5 v7.4.202

updated for version 7.4.202 Problem: MS-Windows: non-ASCII font names don't work. Solution: Convert between the current code page and 'encoding'. (Ken Takata)
author Bram Moolenaar <bram@vim.org>
date Wed, 12 Mar 2014 19:24:37 +0100
parents 7f6acd6dc5b3
children c493330e972c
files src/gui_w48.c src/os_mswin.c src/proto/winclip.pro src/version.c src/winclip.c
diffstat 5 files changed, 73 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/gui_w48.c
+++ b/src/gui_w48.c
@@ -3069,15 +3069,26 @@ logfont2name(LOGFONT lf)
     char	*p;
     char	*res;
     char	*charset_name;
+    char	*font_name = lf.lfFaceName;
 
     charset_name = charset_id2name((int)lf.lfCharSet);
-    res = alloc((unsigned)(strlen(lf.lfFaceName) + 20
+#ifdef FEAT_MBYTE
+    /* Convert a font name from the current codepage to 'encoding'.
+     * TODO: Use Wide APIs (including LOGFONTW) instead of ANSI APIs. */
+    if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
+    {
+	int	len;
+	acp_to_enc(lf.lfFaceName, strlen(lf.lfFaceName),
+						(char_u **)&font_name, &len);
+    }
+#endif
+    res = alloc((unsigned)(strlen(font_name) + 20
 		    + (charset_name == NULL ? 0 : strlen(charset_name) + 2)));
     if (res != NULL)
     {
 	p = res;
 	/* make a normal font string out of the lf thing:*/
-	sprintf((char *)p, "%s:h%d", lf.lfFaceName, pixels_to_points(
+	sprintf((char *)p, "%s:h%d", font_name, pixels_to_points(
 			 lf.lfHeight < 0 ? -lf.lfHeight : lf.lfHeight, TRUE));
 	while (*p)
 	{
@@ -3102,6 +3113,10 @@ logfont2name(LOGFONT lf)
 	}
     }
 
+#ifdef FEAT_MBYTE
+    if (font_name != lf.lfFaceName)
+	vim_free(font_name);
+#endif
     return res;
 }
 
--- a/src/os_mswin.c
+++ b/src/os_mswin.c
@@ -2867,12 +2867,27 @@ get_logfont(
 {
     char_u	*p;
     int		i;
+    int		ret = FAIL;
     static LOGFONT *lastlf = NULL;
+#ifdef FEAT_MBYTE
+    char_u	*acpname = NULL;
+#endif
 
     *lf = s_lfDefault;
     if (name == NULL)
 	return OK;
 
+#ifdef FEAT_MBYTE
+    /* Convert 'name' from 'encoding' to the current codepage, because
+     * lf->lfFaceName uses the current codepage.
+     * TODO: Use Wide APIs instead of ANSI APIs. */
+    if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
+    {
+	int	len;
+	enc_to_acp(name, strlen(name), &acpname, &len);
+	name = acpname;
+    }
+#endif
     if (STRCMP(name, "*") == 0)
     {
 #if defined(FEAT_GUI_W32)
@@ -2887,10 +2902,9 @@ get_logfont(
 	cf.lpLogFont = lf;
 	cf.nFontType = 0 ; //REGULAR_FONTTYPE;
 	if (ChooseFont(&cf))
-	    goto theend;
-#else
-	return FAIL;
+	    ret = OK;
 #endif
+	goto theend;
     }
 
     /*
@@ -2899,7 +2913,7 @@ get_logfont(
     for (p = name; *p && *p != ':'; p++)
     {
 	if (p - name + 1 > LF_FACESIZE)
-	    return FAIL;			/* Name too long */
+	    goto theend;			/* Name too long */
 	lf->lfFaceName[p - name] = *p;
     }
     if (p != name)
@@ -2927,7 +2941,7 @@ get_logfont(
 		did_replace = TRUE;
 	    }
 	if (!did_replace || init_logfont(lf) == FAIL)
-	    return FAIL;
+	    goto theend;
     }
 
     while (*p == ':')
@@ -2988,25 +3002,27 @@ get_logfont(
 			    p[-1], name);
 		    EMSG(IObuff);
 		}
-		return FAIL;
+		goto theend;
 	}
 	while (*p == ':')
 	    p++;
     }
-
-#if defined(FEAT_GUI_W32)
+    ret = OK;
+
 theend:
-#endif
     /* ron: init lastlf */
-    if (printer_dc == NULL)
+    if (ret == OK && printer_dc == NULL)
     {
 	vim_free(lastlf);
 	lastlf = (LOGFONT *)alloc(sizeof(LOGFONT));
 	if (lastlf != NULL)
 	    mch_memmove(lastlf, lf, sizeof(LOGFONT));
     }
-
-    return OK;
+#ifdef FEAT_MBYTE
+    vim_free(acpname);
+#endif
+
+    return ret;
 }
 
 #endif /* defined(FEAT_GUI) || defined(FEAT_PRINTER) */
--- a/src/proto/winclip.pro
+++ b/src/proto/winclip.pro
@@ -11,4 +11,5 @@ void clip_mch_set_selection __ARGS((VimC
 short_u *enc_to_utf16 __ARGS((char_u *str, int *lenp));
 char_u *utf16_to_enc __ARGS((short_u *str, int *lenp));
 void acp_to_enc __ARGS((char_u *str, int str_size, char_u **out, int *outlen));
+void enc_to_acp __ARGS((char_u *str, int str_size, char_u **out, int *outlen));
 /* vim: set ft=c : */
--- a/src/version.c
+++ b/src/version.c
@@ -739,6 +739,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    202,
+/**/
     201,
 /**/
     200,
--- a/src/winclip.c
+++ b/src/winclip.c
@@ -797,4 +797,29 @@ acp_to_enc(str, str_size, out, outlen)
 	vim_free(widestr);
     }
 }
+
+/*
+ * Convert from 'encoding' to the active codepage.
+ * Input is "str[str_size]".
+ * The result is in allocated memory: "out[outlen]".  With terminating NUL.
+ */
+    void
+enc_to_acp(str, str_size, out, outlen)
+    char_u	*str;
+    int		str_size;
+    char_u	**out;
+    int		*outlen;
+
+{
+    LPWSTR	widestr;
+    int		len = str_size;
+
+    widestr = (WCHAR *)enc_to_utf16(str, &len);
+    if (widestr != NULL)
+    {
+	WideCharToMultiByte_alloc(GetACP(), 0, widestr, len,
+						(LPSTR *)out, outlen, 0, 0);
+	vim_free(widestr);
+    }
+}
 #endif