aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGeoff Voelker1999-01-28 04:52:02 +0000
committerGeoff Voelker1999-01-28 04:52:02 +0000
commit5ca0cd71d39c87064ba3946cc1d1eb9b7e912aac (patch)
tree6f33d891d0c1e15065e63f0b04c564aa2d2bba10 /src
parent416afb32052f252922ed937746580f1e1863cd48 (diff)
downloademacs-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.c185
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
5634typedef struct enumfont_t 5648typedef 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
5719int CALLBACK
5720enum_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
5733int CALLBACK
5734enum_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
5708Lisp_Object w32_list_bdf_fonts (Lisp_Object pattern) 5756Lisp_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
5787Lisp_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
5984Lisp_Object
5985w32_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. */
5891struct font_info * 6040struct font_info *
5892w32_get_font_info (f, font_idx) 6041w32_get_font_info (f, font_idx)