diff options
| author | Geoff Voelker | 1999-01-28 04:52:02 +0000 |
|---|---|---|
| committer | Geoff Voelker | 1999-01-28 04:52:02 +0000 |
| commit | 5ca0cd71d39c87064ba3946cc1d1eb9b7e912aac (patch) | |
| tree | 6f33d891d0c1e15065e63f0b04c564aa2d2bba10 /src | |
| parent | 416afb32052f252922ed937746580f1e1863cd48 (diff) | |
| download | emacs-5ca0cd71d39c87064ba3946cc1d1eb9b7e912aac.tar.gz emacs-5ca0cd71d39c87064ba3946cc1d1eb9b7e912aac.zip | |
(w32_load_system_font): Do not load unlisted fonts if
list was reliable.
(enum_fontex_cb1, enum_fontex_cb2): New functions.
(w32_list_bdf_fonts): New parameter; max_names. Callers updated.
(w32_list_synthesized_fonts): New function.
(w32_list_fonts): Use maxnames. Use EnumFontFamiliesEx when
available instead of EnumFontFamilies. List synthesized fonts if
Vw32_enable_italics is non-nil.
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32fns.c | 185 |
1 files changed, 167 insertions, 18 deletions
diff --git a/src/w32fns.c b/src/w32fns.c index 4ecc38832dc..57bad3e6508 100644 --- a/src/w32fns.c +++ b/src/w32fns.c | |||
| @@ -4974,15 +4974,19 @@ int size; | |||
| 4974 | #endif | 4974 | #endif |
| 4975 | fontname = (char *) XSTRING (XCONS (font_names)->car)->data; | 4975 | fontname = (char *) XSTRING (XCONS (font_names)->car)->data; |
| 4976 | } | 4976 | } |
| 4977 | /* Because we need to support NT 3.x, we can't use EnumFontFamiliesEx | ||
| 4978 | so if fonts of the same name are available with several | ||
| 4979 | alternative character sets, the w32_list_fonts can fail to find a | ||
| 4980 | match even if the font exists. Try loading it anyway. | ||
| 4981 | */ | ||
| 4982 | #if 0 | ||
| 4983 | else | 4977 | else |
| 4984 | return NULL; | 4978 | { |
| 4985 | #endif | 4979 | /* If EnumFontFamiliesEx was available, we got a full list of |
| 4980 | fonts back so stop now to avoid the possibility of loading a | ||
| 4981 | random font. If we had to fall back to EnumFontFamilies, the | ||
| 4982 | list is incomplete, so continue whether the font we want was | ||
| 4983 | listed or not. */ | ||
| 4984 | HMODULE gdi32 = GetModuleHandle ("gdi32.dll"); | ||
| 4985 | FARPROC enum_font_families_ex | ||
| 4986 | = GetProcAddress ( gdi32, "EnumFontFamiliesExA"); | ||
| 4987 | if (enum_font_families_ex) | ||
| 4988 | return NULL; | ||
| 4989 | } | ||
| 4986 | 4990 | ||
| 4987 | /* Load the font and add it to the table. */ | 4991 | /* Load the font and add it to the table. */ |
| 4988 | { | 4992 | { |
| @@ -5631,6 +5635,16 @@ w32_font_match (lpszfont1, lpszfont2) | |||
| 5631 | } | 5635 | } |
| 5632 | } | 5636 | } |
| 5633 | 5637 | ||
| 5638 | /* Callback functions, and a structure holding info they need, for | ||
| 5639 | listing system fonts on W32. We need one set of functions to do the | ||
| 5640 | job properly, but these don't work on NT 3.51 and earlier, so we | ||
| 5641 | have a second set which don't handle character sets properly to | ||
| 5642 | fall back on. | ||
| 5643 | |||
| 5644 | In both cases, there are two passes made. The first pass gets one | ||
| 5645 | font from each family, the second pass lists all the fonts from | ||
| 5646 | each family. */ | ||
| 5647 | |||
| 5634 | typedef struct enumfont_t | 5648 | typedef struct enumfont_t |
| 5635 | { | 5649 | { |
| 5636 | HDC hdc; | 5650 | HDC hdc; |
| @@ -5676,8 +5690,8 @@ enum_font_cb2 (lplf, lptm, FontType, lpef) | |||
| 5676 | if (!w32_to_x_font (&(lplf->elfLogFont), buf, 100)) | 5690 | if (!w32_to_x_font (&(lplf->elfLogFont), buf, 100)) |
| 5677 | return (0); | 5691 | return (0); |
| 5678 | 5692 | ||
| 5679 | if (NILP (*(lpef->pattern)) || | 5693 | if (NILP (*(lpef->pattern)) |
| 5680 | w32_font_match (buf, XSTRING (*(lpef->pattern))->data)) | 5694 | || w32_font_match (buf, XSTRING (*(lpef->pattern))->data)) |
| 5681 | { | 5695 | { |
| 5682 | *lpef->tail = Fcons (Fcons (build_string (buf), width), Qnil); | 5696 | *lpef->tail = Fcons (Fcons (build_string (buf), width), Qnil); |
| 5683 | lpef->tail = &(XCONS (*lpef->tail)->cdr); | 5697 | lpef->tail = &(XCONS (*lpef->tail)->cdr); |
| @@ -5702,13 +5716,48 @@ enum_font_cb1 (lplf, lptm, FontType, lpef) | |||
| 5702 | } | 5716 | } |
| 5703 | 5717 | ||
| 5704 | 5718 | ||
| 5719 | int CALLBACK | ||
| 5720 | enum_fontex_cb2 (lplf, lptm, font_type, lpef) | ||
| 5721 | ENUMLOGFONTEX * lplf; | ||
| 5722 | NEWTEXTMETRICEX * lptm; | ||
| 5723 | int font_type; | ||
| 5724 | enumfont_t * lpef; | ||
| 5725 | { | ||
| 5726 | /* We are not interested in the extra info we get back from the 'Ex | ||
| 5727 | version - only the fact that we get character set variations | ||
| 5728 | enumerated seperately. */ | ||
| 5729 | return enum_font_cb2 ((ENUMLOGFONT *) lplf, (NEWTEXTMETRIC *) lptm, | ||
| 5730 | font_type, lpef); | ||
| 5731 | } | ||
| 5732 | |||
| 5733 | int CALLBACK | ||
| 5734 | enum_fontex_cb1 (lplf, lptm, font_type, lpef) | ||
| 5735 | ENUMLOGFONTEX * lplf; | ||
| 5736 | NEWTEXTMETRICEX * lptm; | ||
| 5737 | int font_type; | ||
| 5738 | enumfont_t * lpef; | ||
| 5739 | { | ||
| 5740 | HMODULE gdi32 = GetModuleHandle ("gdi32.dll"); | ||
| 5741 | FARPROC enum_font_families_ex | ||
| 5742 | = GetProcAddress ( gdi32, "EnumFontFamiliesExA"); | ||
| 5743 | /* We don't really expect EnumFontFamiliesEx to disappear once we | ||
| 5744 | get here, so don't bother handling it gracefully. */ | ||
| 5745 | if (enum_font_families_ex == NULL) | ||
| 5746 | error ("gdi32.dll has disappeared!"); | ||
| 5747 | return enum_font_families_ex (lpef->hdc, | ||
| 5748 | &lplf->elfLogFont, | ||
| 5749 | (FONTENUMPROC) enum_fontex_cb2, | ||
| 5750 | (LPARAM) lpef, 0); | ||
| 5751 | } | ||
| 5752 | |||
| 5705 | /* Interface to fontset handler. (adapted from mw32font.c in Meadow | 5753 | /* Interface to fontset handler. (adapted from mw32font.c in Meadow |
| 5706 | and xterm.c in Emacs 20.3) */ | 5754 | and xterm.c in Emacs 20.3) */ |
| 5707 | 5755 | ||
| 5708 | Lisp_Object w32_list_bdf_fonts (Lisp_Object pattern) | 5756 | Lisp_Object w32_list_bdf_fonts (Lisp_Object pattern, int max_names) |
| 5709 | { | 5757 | { |
| 5710 | char *fontname, *ptnstr; | 5758 | char *fontname, *ptnstr; |
| 5711 | Lisp_Object list, tem, newlist = Qnil; | 5759 | Lisp_Object list, tem, newlist = Qnil; |
| 5760 | int n_fonts; | ||
| 5712 | 5761 | ||
| 5713 | list = Vw32_bdf_filename_alist; | 5762 | list = Vw32_bdf_filename_alist; |
| 5714 | ptnstr = XSTRING (pattern)->data; | 5763 | ptnstr = XSTRING (pattern)->data; |
| @@ -5724,12 +5773,20 @@ Lisp_Object w32_list_bdf_fonts (Lisp_Object pattern) | |||
| 5724 | continue; | 5773 | continue; |
| 5725 | 5774 | ||
| 5726 | if (w32_font_match (fontname, ptnstr)) | 5775 | if (w32_font_match (fontname, ptnstr)) |
| 5727 | newlist = Fcons (XCONS (tem)->car, newlist); | 5776 | { |
| 5777 | newlist = Fcons (XCONS (tem)->car, newlist); | ||
| 5778 | n_fonts++; | ||
| 5779 | if (n_fonts >= max_names) | ||
| 5780 | break; | ||
| 5781 | } | ||
| 5728 | } | 5782 | } |
| 5729 | 5783 | ||
| 5730 | return newlist; | 5784 | return newlist; |
| 5731 | } | 5785 | } |
| 5732 | 5786 | ||
| 5787 | Lisp_Object w32_list_synthesized_fonts (FRAME_PTR f, Lisp_Object pattern, | ||
| 5788 | int size, int max_names); | ||
| 5789 | |||
| 5733 | /* Return a list of names of available fonts matching PATTERN on frame | 5790 | /* Return a list of names of available fonts matching PATTERN on frame |
| 5734 | F. If SIZE is not 0, it is the size (maximum bound width) of fonts | 5791 | F. If SIZE is not 0, it is the size (maximum bound width) of fonts |
| 5735 | to be listed. Frame F NULL means we have not yet created any | 5792 | to be listed. Frame F NULL means we have not yet created any |
| @@ -5743,6 +5800,7 @@ w32_list_fonts (FRAME_PTR f, Lisp_Object pattern, int size, int maxnames ) | |||
| 5743 | Lisp_Object patterns, key, tem, tpat; | 5800 | Lisp_Object patterns, key, tem, tpat; |
| 5744 | Lisp_Object list = Qnil, newlist = Qnil, second_best = Qnil; | 5801 | Lisp_Object list = Qnil, newlist = Qnil, second_best = Qnil; |
| 5745 | struct w32_display_info *dpyinfo = &one_w32_display_info; | 5802 | struct w32_display_info *dpyinfo = &one_w32_display_info; |
| 5803 | int n_fonts = 0; | ||
| 5746 | 5804 | ||
| 5747 | patterns = Fassoc (pattern, Valternate_fontname_alist); | 5805 | patterns = Fassoc (pattern, Valternate_fontname_alist); |
| 5748 | if (NILP (patterns)) | 5806 | if (NILP (patterns)) |
| @@ -5773,13 +5831,34 @@ w32_list_fonts (FRAME_PTR f, Lisp_Object pattern, int size, int maxnames ) | |||
| 5773 | ef.tail = &list; | 5831 | ef.tail = &list; |
| 5774 | ef.numFonts = 0; | 5832 | ef.numFonts = 0; |
| 5775 | 5833 | ||
| 5834 | /* Use EnumFontFamiliesEx where it is available, as it knows | ||
| 5835 | about character sets. Fall back to EnumFontFamilies for | ||
| 5836 | older versions of NT that don't support the 'Ex function. */ | ||
| 5776 | x_to_w32_font (STRINGP (tpat) ? XSTRING (tpat)->data : | 5837 | x_to_w32_font (STRINGP (tpat) ? XSTRING (tpat)->data : |
| 5777 | NULL, &ef.logfont); | 5838 | NULL, &ef.logfont); |
| 5778 | { | 5839 | { |
| 5840 | LOGFONT font_match_pattern; | ||
| 5841 | HMODULE gdi32 = GetModuleHandle ("gdi32.dll"); | ||
| 5842 | FARPROC enum_font_families_ex | ||
| 5843 | = GetProcAddress ( gdi32, "EnumFontFamiliesExA"); | ||
| 5844 | |||
| 5845 | /* We do our own pattern matching so we can handle wildcards. */ | ||
| 5846 | font_match_pattern.lfFaceName[0] = 0; | ||
| 5847 | font_match_pattern.lfPitchAndFamily = 0; | ||
| 5848 | /* We can use the charset, because if it is a wildcard it will | ||
| 5849 | be DEFAULT_CHARSET anyway. */ | ||
| 5850 | font_match_pattern.lfCharSet = ef.logfont.lfCharSet; | ||
| 5851 | |||
| 5779 | ef.hdc = GetDC (dpyinfo->root_window); | 5852 | ef.hdc = GetDC (dpyinfo->root_window); |
| 5780 | 5853 | ||
| 5781 | EnumFontFamilies (ef.hdc, NULL, (FONTENUMPROC) enum_font_cb1, | 5854 | if (enum_font_families_ex) |
| 5782 | (LPARAM)&ef); | 5855 | enum_font_families_ex (ef.hdc, |
| 5856 | &font_match_pattern, | ||
| 5857 | (FONTENUMPROC) enum_fontex_cb1, | ||
| 5858 | (LPARAM) &ef, 0); | ||
| 5859 | else | ||
| 5860 | EnumFontFamilies (ef.hdc, NULL, (FONTENUMPROC) enum_font_cb1, | ||
| 5861 | (LPARAM)&ef); | ||
| 5783 | 5862 | ||
| 5784 | ReleaseDC (dpyinfo->root_window, ef.hdc); | 5863 | ReleaseDC (dpyinfo->root_window, ef.hdc); |
| 5785 | } | 5864 | } |
| @@ -5810,7 +5889,11 @@ w32_list_fonts (FRAME_PTR f, Lisp_Object pattern, int size, int maxnames ) | |||
| 5810 | if (!size) | 5889 | if (!size) |
| 5811 | { | 5890 | { |
| 5812 | newlist = Fcons (XCONS (tem)->car, newlist); | 5891 | newlist = Fcons (XCONS (tem)->car, newlist); |
| 5813 | continue; | 5892 | n_fonts++; |
| 5893 | if (n_fonts >= maxnames) | ||
| 5894 | break; | ||
| 5895 | else | ||
| 5896 | continue; | ||
| 5814 | } | 5897 | } |
| 5815 | if (!INTEGERP (XCONS (tem)->cdr)) | 5898 | if (!INTEGERP (XCONS (tem)->cdr)) |
| 5816 | { | 5899 | { |
| @@ -5843,14 +5926,19 @@ w32_list_fonts (FRAME_PTR f, Lisp_Object pattern, int size, int maxnames ) | |||
| 5843 | } | 5926 | } |
| 5844 | found_size = XINT (XCONS (tem)->cdr); | 5927 | found_size = XINT (XCONS (tem)->cdr); |
| 5845 | if (found_size == size) | 5928 | if (found_size == size) |
| 5846 | newlist = Fcons (XCONS (tem)->car, newlist); | 5929 | { |
| 5847 | 5930 | newlist = Fcons (XCONS (tem)->car, newlist); | |
| 5931 | n_fonts++; | ||
| 5932 | if (n_fonts >= maxnames) | ||
| 5933 | break; | ||
| 5934 | } | ||
| 5848 | /* keep track of the closest matching size in case | 5935 | /* keep track of the closest matching size in case |
| 5849 | no exact match is found. */ | 5936 | no exact match is found. */ |
| 5850 | else if (found_size > 0) | 5937 | else if (found_size > 0) |
| 5851 | { | 5938 | { |
| 5852 | if (NILP (second_best)) | 5939 | if (NILP (second_best)) |
| 5853 | second_best = tem; | 5940 | second_best = tem; |
| 5941 | |||
| 5854 | else if (found_size < size) | 5942 | else if (found_size < size) |
| 5855 | { | 5943 | { |
| 5856 | if (XINT (XCONS (second_best)->cdr) > size | 5944 | if (XINT (XCONS (second_best)->cdr) > size |
| @@ -5877,16 +5965,77 @@ w32_list_fonts (FRAME_PTR f, Lisp_Object pattern, int size, int maxnames ) | |||
| 5877 | } | 5965 | } |
| 5878 | 5966 | ||
| 5879 | /* Include any bdf fonts. */ | 5967 | /* Include any bdf fonts. */ |
| 5968 | if (n_fonts < maxnames) | ||
| 5880 | { | 5969 | { |
| 5881 | Lisp_Object combined[2]; | 5970 | Lisp_Object combined[2]; |
| 5882 | combined[0] = w32_list_bdf_fonts (pattern); | 5971 | combined[0] = w32_list_bdf_fonts (pattern, maxnames - n_fonts); |
| 5883 | combined[1] = newlist; | 5972 | combined[1] = newlist; |
| 5884 | newlist = Fnconc(2, combined); | 5973 | newlist = Fnconc(2, combined); |
| 5885 | } | 5974 | } |
| 5886 | 5975 | ||
| 5976 | /* If we can't find a font that matches, check if Windows would be | ||
| 5977 | able to synthesize it from a different style. */ | ||
| 5978 | if (NILP (newlist) && !NILP (Vw32_enable_italics)) | ||
| 5979 | newlist = w32_list_synthesized_fonts (f, pattern, size, maxnames); | ||
| 5980 | |||
| 5887 | return newlist; | 5981 | return newlist; |
| 5888 | } | 5982 | } |
| 5889 | 5983 | ||
| 5984 | Lisp_Object | ||
| 5985 | w32_list_synthesized_fonts (f, pattern, size, max_names) | ||
| 5986 | FRAME_PTR f; | ||
| 5987 | Lisp_Object pattern; | ||
| 5988 | int size; | ||
| 5989 | int max_names; | ||
| 5990 | { | ||
| 5991 | int fields; | ||
| 5992 | char *full_pattn, *new_pattn, foundary[50], family[50], *pattn_part2; | ||
| 5993 | char style[20], slant; | ||
| 5994 | Lisp_Object matches, match, tem, synthed_matches = Qnil; | ||
| 5995 | |||
| 5996 | full_pattn = XSTRING (pattern)->data; | ||
| 5997 | |||
| 5998 | pattn_part2 = alloca (XSTRING (pattern)->size); | ||
| 5999 | /* Allow some space for wildcard expansion. */ | ||
| 6000 | new_pattn = alloca (XSTRING (pattern)->size + 100); | ||
| 6001 | |||
| 6002 | fields = sscanf (full_pattn, "-%49[^-]-%49[^-]-%19[^-]-%c-%s", | ||
| 6003 | foundary, family, style, &slant, pattn_part2); | ||
| 6004 | if (fields == EOF || fields < 5) | ||
| 6005 | return Qnil; | ||
| 6006 | |||
| 6007 | /* If the style and slant are wildcards already there is no point | ||
| 6008 | checking again (and we don't want to keep recursing). */ | ||
| 6009 | if (*style == '*' && slant == '*') | ||
| 6010 | return Qnil; | ||
| 6011 | |||
| 6012 | sprintf (new_pattn, "-%s-%s-*-*-%s", foundary, family, pattn_part2); | ||
| 6013 | |||
| 6014 | matches = w32_list_fonts (f, build_string (new_pattn), size, max_names); | ||
| 6015 | |||
| 6016 | for ( ; CONSP (matches); matches = XCONS (matches)->cdr) | ||
| 6017 | { | ||
| 6018 | tem = XCONS (matches)->car; | ||
| 6019 | if (!STRINGP (tem)) | ||
| 6020 | continue; | ||
| 6021 | |||
| 6022 | full_pattn = XSTRING (tem)->data; | ||
| 6023 | fields = sscanf (full_pattn, "-%49[^-]-%49[^-]-%*[^-]-%*c-%s", | ||
| 6024 | foundary, family, pattn_part2); | ||
| 6025 | if (fields == EOF || fields < 3) | ||
| 6026 | continue; | ||
| 6027 | |||
| 6028 | sprintf (new_pattn, "-%s-%s-%s-%c-%s", foundary, family, style, | ||
| 6029 | slant, pattn_part2); | ||
| 6030 | |||
| 6031 | synthed_matches = Fcons (build_string (new_pattn), | ||
| 6032 | synthed_matches); | ||
| 6033 | } | ||
| 6034 | |||
| 6035 | return synthed_matches; | ||
| 6036 | } | ||
| 6037 | |||
| 6038 | |||
| 5890 | /* Return a pointer to struct font_info of font FONT_IDX of frame F. */ | 6039 | /* Return a pointer to struct font_info of font FONT_IDX of frame F. */ |
| 5891 | struct font_info * | 6040 | struct font_info * |
| 5892 | w32_get_font_info (f, font_idx) | 6041 | w32_get_font_info (f, font_idx) |