Mercurial > vim
comparison src/os_mswin.c @ 33480:f8dd278ab05f v9.0.1991
patch 9.0.1991: no cmdline completion for setting the font
Commit: https://github.com/vim/vim/commit/290b887e8cc2c0d3dfc7f315b2052472c7c589cc
Author: Yee Cheng Chin <ychin.git@gmail.com>
Date: Thu Oct 5 20:54:21 2023 +0200
patch 9.0.1991: no cmdline completion for setting the font
Problem: no cmdline completion for setting the font
Solution: enable it on Win32 and GTK builds
Add guifont cmdline completion (for Windows and GTK)
For Windows, auto-complete will only suggest monospace fonts as that's
the only types allowed. Will also suggest font options after the colon,
including suggesting the current font size for convenience, and misc
charset and quality options like `cANSI` and `qCLEARTYPE`.
For GTK, auto-complete will suggest only monospace fonts for `guifont`
but will include all fonts for `guifontwide`. The completion code
doesn't currently suggest the current font size, as the GTK guifont
format does not have a clear delimiter (':' for other platforms).
closes: #13264
Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Yee Cheng Chin <ychin.git@gmail.com>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Thu, 05 Oct 2023 21:00:07 +0200 |
parents | 397ff3169248 |
children | 1629cc65d78d |
comparison
equal
deleted
inserted
replaced
33479:e88e84676ad5 | 33480:f8dd278ab05f |
---|---|
2817 | 2817 |
2818 *end = str; | 2818 *end = str; |
2819 return pixels; | 2819 return pixels; |
2820 } | 2820 } |
2821 | 2821 |
2822 /* | |
2823 * Convert pixel into point size. This is a reverse of points_to_pixels. | |
2824 */ | |
2825 static double | |
2826 pixels_to_points(int pixels, int vertical, long_i pprinter_dc) | |
2827 { | |
2828 double points = 0; | |
2829 HWND hwnd = (HWND)0; | |
2830 HDC hdc; | |
2831 HDC printer_dc = (HDC)pprinter_dc; | |
2832 | |
2833 if (printer_dc == NULL) | |
2834 { | |
2835 hwnd = GetDesktopWindow(); | |
2836 hdc = GetWindowDC(hwnd); | |
2837 } | |
2838 else | |
2839 hdc = printer_dc; | |
2840 | |
2841 points = pixels * 72.0 / GetDeviceCaps(hdc, vertical ? LOGPIXELSY : LOGPIXELSX); | |
2842 if (printer_dc == NULL) | |
2843 ReleaseDC(hwnd, hdc); | |
2844 | |
2845 return points; | |
2846 } | |
2847 | |
2822 static int CALLBACK | 2848 static int CALLBACK |
2823 font_enumproc( | 2849 font_enumproc( |
2824 ENUMLOGFONTW *elf, | 2850 ENUMLOGFONTW *elf, |
2825 NEWTEXTMETRICW *ntm UNUSED, | 2851 NEWTEXTMETRICW *ntm UNUSED, |
2826 DWORD type UNUSED, | 2852 DWORD type UNUSED, |
2885 lf->lfStrikeOut = FALSE; | 2911 lf->lfStrikeOut = FALSE; |
2886 lf->lfWeight = FW_NORMAL; | 2912 lf->lfWeight = FW_NORMAL; |
2887 | 2913 |
2888 // Return success | 2914 // Return success |
2889 return OK; | 2915 return OK; |
2916 } | |
2917 | |
2918 /* | |
2919 * Call back for EnumFontFamiliesW in expand_font_enumproc. | |
2920 * | |
2921 */ | |
2922 static int CALLBACK | |
2923 expand_font_enumproc( | |
2924 ENUMLOGFONTW *elf, | |
2925 NEWTEXTMETRICW *ntm UNUSED, | |
2926 DWORD type UNUSED, | |
2927 LPARAM lparam) | |
2928 { | |
2929 LOGFONTW *lf = (LOGFONTW*)elf; | |
2930 | |
2931 # ifndef FEAT_PROPORTIONAL_FONTS | |
2932 // Ignore non-monospace fonts without further ado | |
2933 if ((ntm->tmPitchAndFamily & 1) != 0) | |
2934 return 1; | |
2935 # endif | |
2936 | |
2937 // Filter only on ANSI. Otherwise will see a lot of random fonts that we | |
2938 // usually don't want. | |
2939 if (lf->lfCharSet != ANSI_CHARSET) | |
2940 return 1; | |
2941 | |
2942 int (*add_match)(char_u *) = (int (*)(char_u *))lparam; | |
2943 | |
2944 WCHAR *faceNameW = lf->lfFaceName; | |
2945 char_u *faceName = utf16_to_enc(faceNameW, NULL); | |
2946 if (!faceName) | |
2947 return 0; | |
2948 | |
2949 add_match(faceName); | |
2950 vim_free(faceName); | |
2951 | |
2952 return 1; | |
2953 } | |
2954 | |
2955 /* | |
2956 * Cmdline expansion for setting 'guifont'. Will enumerate through all | |
2957 * monospace fonts for completion. If used after ':', will expand to possible | |
2958 * font configuration options like font sizes. | |
2959 * | |
2960 * This function has "gui" in its name because in some platforms (GTK) font | |
2961 * handling is done by the GUI code, whereas in Windows it's part of the | |
2962 * platform code. | |
2963 */ | |
2964 void | |
2965 gui_mch_expand_font(optexpand_T *args, void *param UNUSED, int (*add_match)(char_u *val)) | |
2966 { | |
2967 expand_T *xp = args->oe_xp; | |
2968 if (xp->xp_pattern > args->oe_set_arg && *(xp->xp_pattern-1) == ':') | |
2969 { | |
2970 char buf[30]; | |
2971 | |
2972 // Always fill in with the current font size as first option for | |
2973 // convenience. We simply round to the closest integer for simplicity. | |
2974 int font_height = (int)round( | |
2975 pixels_to_points(-current_font_height, TRUE, (long_i)NULL)); | |
2976 vim_snprintf(buf, ARRAY_LENGTH(buf), "h%d", font_height); | |
2977 add_match((char_u *)buf); | |
2978 | |
2979 // Note: Keep this in sync with get_logfont(). Don't include 'c' and | |
2980 // 'q' as we fill in all the values below. | |
2981 static char *(p_gfn_win_opt_values[]) = { | |
2982 "h" , "w" , "W" , "b" , "i" , "u" , "s"}; | |
2983 for (size_t i = 0; i < ARRAY_LENGTH(p_gfn_win_opt_values); i++) | |
2984 add_match((char_u *)p_gfn_win_opt_values[i]); | |
2985 | |
2986 struct charset_pair *cp; | |
2987 for (cp = charset_pairs; cp->name != NULL; ++cp) | |
2988 { | |
2989 vim_snprintf(buf, ARRAY_LENGTH(buf), "c%s", cp->name); | |
2990 add_match((char_u *)buf); | |
2991 } | |
2992 struct quality_pair *qp; | |
2993 for (qp = quality_pairs; qp->name != NULL; ++qp) | |
2994 { | |
2995 vim_snprintf(buf, ARRAY_LENGTH(buf), "q%s", qp->name); | |
2996 add_match((char_u *)buf); | |
2997 } | |
2998 return; | |
2999 } | |
3000 | |
3001 HWND hwnd = GetDesktopWindow(); | |
3002 HDC hdc = GetWindowDC(hwnd); | |
3003 | |
3004 EnumFontFamiliesW(hdc, | |
3005 NULL, | |
3006 (FONTENUMPROCW)expand_font_enumproc, | |
3007 (LPARAM)add_match); | |
3008 | |
3009 ReleaseDC(hwnd, hdc); | |
2890 } | 3010 } |
2891 | 3011 |
2892 /* | 3012 /* |
2893 * Compare a UTF-16 string and an ASCII string literally. | 3013 * Compare a UTF-16 string and an ASCII string literally. |
2894 * Only works all the code points are inside ASCII range. | 3014 * Only works all the code points are inside ASCII range. |
2993 // Set the values found after ':' | 3113 // Set the values found after ':' |
2994 while (*p) | 3114 while (*p) |
2995 { | 3115 { |
2996 switch (*p++) | 3116 switch (*p++) |
2997 { | 3117 { |
3118 // Note: Keep this in sync with gui_mch_expand_font(). | |
2998 case L'h': | 3119 case L'h': |
2999 lf->lfHeight = - points_to_pixels(p, &p, TRUE, (long_i)printer_dc); | 3120 lf->lfHeight = - points_to_pixels(p, &p, TRUE, (long_i)printer_dc); |
3000 break; | 3121 break; |
3001 case L'w': | 3122 case L'w': |
3002 lf->lfWidth = points_to_pixels(p, &p, FALSE, (long_i)printer_dc); | 3123 lf->lfWidth = points_to_pixels(p, &p, FALSE, (long_i)printer_dc); |