comparison src/w32fns.c @ 96133:e7d9b9d2e1ef

[OLD_FONT]: Remove obsolete font code.
author Jason Rumney <jasonr@gnu.org>
date Fri, 20 Jun 2008 21:46:05 +0000
parents 0623378cdbca
children c3309dba6542
comparison
equal deleted inserted replaced
96132:94707ef52511 96133:e7d9b9d2e1ef
69 extern void free_frame_menubar (); 69 extern void free_frame_menubar ();
70 extern double atof (); 70 extern double atof ();
71 extern int w32_console_toggle_lock_key P_ ((int, Lisp_Object)); 71 extern int w32_console_toggle_lock_key P_ ((int, Lisp_Object));
72 extern void w32_menu_display_help P_ ((HWND, HMENU, UINT, UINT)); 72 extern void w32_menu_display_help P_ ((HWND, HMENU, UINT, UINT));
73 extern void w32_free_menu_strings P_ ((HWND)); 73 extern void w32_free_menu_strings P_ ((HWND));
74 #if OLD_FONT
75 extern XCharStruct *w32_per_char_metric P_ ((XFontStruct *, wchar_t *, int));
76 #endif
77 74
78 extern int quit_char; 75 extern int quit_char;
79 76
80 extern char *lispy_function_keys[]; 77 extern char *lispy_function_keys[];
81 78
4645 x_focus_on_frame (check_x_frame (frame)); 4642 x_focus_on_frame (check_x_frame (frame));
4646 return Qnil; 4643 return Qnil;
4647 } 4644 }
4648 4645
4649 4646
4650 #if OLD_FONT
4651
4652 /* Return the charset portion of a font name. */
4653 char *
4654 xlfd_charset_of_font (char * fontname)
4655 {
4656 char *charset, *encoding;
4657
4658 encoding = strrchr (fontname, '-');
4659 if (!encoding || encoding == fontname)
4660 return NULL;
4661
4662 for (charset = encoding - 1; charset >= fontname; charset--)
4663 if (*charset == '-')
4664 break;
4665
4666 if (charset == fontname || strcmp (charset, "-*-*") == 0)
4667 return NULL;
4668
4669 return charset + 1;
4670 }
4671
4672 struct font_info *w32_load_bdf_font (struct frame *f, char *fontname,
4673 int size, char* filename);
4674 static Lisp_Object w32_list_bdf_fonts (Lisp_Object pattern, int max_names);
4675 static BOOL w32_to_x_font (LOGFONT * lplf, char * lpxstr, int len,
4676 char * charset);
4677 static BOOL x_to_w32_font (char *lpxstr, LOGFONT *lplogfont);
4678
4679 static struct font_info *
4680 w32_load_system_font (f, fontname, size)
4681 struct frame *f;
4682 char * fontname;
4683 int size;
4684 {
4685 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
4686 Lisp_Object font_names;
4687
4688 /* Get a list of all the fonts that match this name. Once we
4689 have a list of matching fonts, we compare them against the fonts
4690 we already have loaded by comparing names. */
4691 font_names = w32_list_fonts (f, build_string (fontname), size, 100);
4692
4693 if (!NILP (font_names))
4694 {
4695 Lisp_Object tail;
4696 int i;
4697
4698 /* First check if any are already loaded, as that is cheaper
4699 than loading another one. */
4700 for (i = 0; i < dpyinfo->n_fonts; i++)
4701 for (tail = font_names; CONSP (tail); tail = XCDR (tail))
4702 if (dpyinfo->font_table[i].name
4703 && (!strcmp (dpyinfo->font_table[i].name,
4704 SDATA (XCAR (tail)))
4705 || !strcmp (dpyinfo->font_table[i].full_name,
4706 SDATA (XCAR (tail)))))
4707 return (dpyinfo->font_table + i);
4708
4709 fontname = (char *) SDATA (XCAR (font_names));
4710 }
4711 else if (w32_strict_fontnames)
4712 {
4713 /* If EnumFontFamiliesEx was available, we got a full list of
4714 fonts back so stop now to avoid the possibility of loading a
4715 random font. If we had to fall back to EnumFontFamilies, the
4716 list is incomplete, so continue whether the font we want was
4717 listed or not. */
4718 HMODULE gdi32 = GetModuleHandle ("gdi32.dll");
4719 FARPROC enum_font_families_ex
4720 = GetProcAddress (gdi32, "EnumFontFamiliesExA");
4721 if (enum_font_families_ex)
4722 return NULL;
4723 }
4724
4725 /* Load the font and add it to the table. */
4726 {
4727 char *full_name, *encoding, *charset;
4728 XFontStruct *font;
4729 struct font_info *fontp;
4730 LOGFONT lf;
4731 BOOL ok;
4732 int codepage;
4733 int i;
4734
4735 if (!fontname || !x_to_w32_font (fontname, &lf))
4736 return (NULL);
4737
4738 if (!*lf.lfFaceName)
4739 /* If no name was specified for the font, we get a random font
4740 from CreateFontIndirect - this is not particularly
4741 desirable, especially since CreateFontIndirect does not
4742 fill out the missing name in lf, so we never know what we
4743 ended up with. */
4744 return NULL;
4745
4746 lf.lfQuality = DEFAULT_QUALITY;
4747
4748 font = (XFontStruct *) xmalloc (sizeof (XFontStruct));
4749 bzero (font, sizeof (*font));
4750
4751 /* Set bdf to NULL to indicate that this is a Windows font. */
4752 font->bdf = NULL;
4753
4754 BLOCK_INPUT;
4755
4756 font->hfont = CreateFontIndirect (&lf);
4757
4758 if (font->hfont == NULL)
4759 {
4760 ok = FALSE;
4761 }
4762 else
4763 {
4764 HDC hdc;
4765 HANDLE oldobj;
4766
4767 codepage = w32_codepage_for_font (fontname);
4768
4769 hdc = GetDC (dpyinfo->root_window);
4770 oldobj = SelectObject (hdc, font->hfont);
4771
4772 ok = GetTextMetrics (hdc, &font->tm);
4773 if (codepage == CP_UNICODE)
4774 font->double_byte_p = 1;
4775 else
4776 {
4777 /* Unfortunately, some fonts (eg. MingLiU, a big5 ttf font)
4778 don't report themselves as double byte fonts, when
4779 patently they are. So instead of trusting
4780 GetFontLanguageInfo, we check the properties of the
4781 codepage directly, since that is ultimately what we are
4782 working from anyway. */
4783 /* font->double_byte_p = GetFontLanguageInfo (hdc) & GCP_DBCS; */
4784 CPINFO cpi = {0};
4785 GetCPInfo (codepage, &cpi);
4786 font->double_byte_p = cpi.MaxCharSize > 1;
4787 }
4788
4789 SelectObject (hdc, oldobj);
4790 ReleaseDC (dpyinfo->root_window, hdc);
4791 /* Fill out details in lf according to the font that was
4792 actually loaded. */
4793 lf.lfHeight = font->tm.tmInternalLeading - font->tm.tmHeight;
4794 lf.lfWidth = font->tm.tmMaxCharWidth;
4795 lf.lfWeight = font->tm.tmWeight;
4796 lf.lfItalic = font->tm.tmItalic;
4797 lf.lfCharSet = font->tm.tmCharSet;
4798 lf.lfPitchAndFamily = ((font->tm.tmPitchAndFamily & TMPF_FIXED_PITCH)
4799 ? VARIABLE_PITCH : FIXED_PITCH);
4800 lf.lfOutPrecision = ((font->tm.tmPitchAndFamily & TMPF_VECTOR)
4801 ? OUT_STROKE_PRECIS : OUT_STRING_PRECIS);
4802
4803 w32_cache_char_metrics (font);
4804 }
4805
4806 UNBLOCK_INPUT;
4807
4808 if (!ok)
4809 {
4810 w32_unload_font (dpyinfo, font);
4811 return (NULL);
4812 }
4813
4814 /* Find a free slot in the font table. */
4815 for (i = 0; i < dpyinfo->n_fonts; ++i)
4816 if (dpyinfo->font_table[i].name == NULL)
4817 break;
4818
4819 /* If no free slot found, maybe enlarge the font table. */
4820 if (i == dpyinfo->n_fonts
4821 && dpyinfo->n_fonts == dpyinfo->font_table_size)
4822 {
4823 int sz;
4824 dpyinfo->font_table_size = max (16, 2 * dpyinfo->font_table_size);
4825 sz = dpyinfo->font_table_size * sizeof *dpyinfo->font_table;
4826 dpyinfo->font_table
4827 = (struct font_info *) xrealloc (dpyinfo->font_table, sz);
4828 }
4829
4830 fontp = dpyinfo->font_table + i;
4831 if (i == dpyinfo->n_fonts)
4832 ++dpyinfo->n_fonts;
4833
4834 /* Now fill in the slots of *FONTP. */
4835 BLOCK_INPUT;
4836 bzero (fontp, sizeof (*fontp));
4837 fontp->font = font;
4838 fontp->font_idx = i;
4839 fontp->name = (char *) xmalloc (strlen (fontname) + 1);
4840 bcopy (fontname, fontp->name, strlen (fontname) + 1);
4841
4842 if ((lf.lfPitchAndFamily & 0x03) == FIXED_PITCH)
4843 {
4844 /* Fixed width font. */
4845 fontp->average_width = fontp->space_width = FONT_AVG_WIDTH (font);
4846 }
4847 else
4848 {
4849 wchar_t space = 32;
4850 XCharStruct* pcm;
4851 pcm = w32_per_char_metric (font, &space, ANSI_FONT);
4852 if (pcm)
4853 fontp->space_width = pcm->width;
4854 else
4855 fontp->space_width = FONT_AVG_WIDTH (font);
4856
4857 fontp->average_width = font->tm.tmAveCharWidth;
4858 }
4859
4860 fontp->charset = -1;
4861 charset = xlfd_charset_of_font (fontname);
4862
4863 /* Cache the W32 codepage for a font. This makes w32_encode_char
4864 (called for every glyph during redisplay) much faster. */
4865 fontp->codepage = codepage;
4866
4867 /* Work out the font's full name. */
4868 full_name = (char *)xmalloc (100);
4869 if (full_name && w32_to_x_font (&lf, full_name, 100, charset))
4870 fontp->full_name = full_name;
4871 else
4872 {
4873 /* If all else fails - just use the name we used to load it. */
4874 xfree (full_name);
4875 fontp->full_name = fontp->name;
4876 }
4877
4878 fontp->size = FONT_WIDTH (font);
4879 fontp->height = FONT_HEIGHT (font);
4880
4881 /* The slot `encoding' specifies how to map a character
4882 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
4883 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
4884 (0:0x20..0x7F, 1:0xA0..0xFF,
4885 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
4886 2:0xA020..0xFF7F). For the moment, we don't know which charset
4887 uses this font. So, we set information in fontp->encoding_type
4888 which is never used by any charset. If mapping can't be
4889 decided, set FONT_ENCODING_NOT_DECIDED. */
4890
4891 /* SJIS fonts need to be set to type 4, all others seem to work as
4892 type FONT_ENCODING_NOT_DECIDED. */
4893 encoding = strrchr (fontp->name, '-');
4894 if (encoding && strnicmp (encoding+1, "sjis", 4) == 0)
4895 fontp->encoding_type = 4;
4896 else
4897 fontp->encoding_type = FONT_ENCODING_NOT_DECIDED;
4898
4899 /* The following three values are set to 0 under W32, which is
4900 what they get set to if XGetFontProperty fails under X. */
4901 fontp->baseline_offset = 0;
4902 fontp->relative_compose = 0;
4903 fontp->default_ascent = 0;
4904
4905 /* Set global flag fonts_changed_p to non-zero if the font loaded
4906 has a character with a smaller width than any other character
4907 before, or if the font loaded has a smaller height than any
4908 other font loaded before. If this happens, it will make a
4909 glyph matrix reallocation necessary. */
4910 fonts_changed_p |= x_compute_min_glyph_bounds (f);
4911 UNBLOCK_INPUT;
4912 return fontp;
4913 }
4914 }
4915
4916 /* Load font named FONTNAME of size SIZE for frame F, and return a
4917 pointer to the structure font_info while allocating it dynamically.
4918 If loading fails, return NULL. */
4919 struct font_info *
4920 w32_load_font (f, fontname, size)
4921 struct frame *f;
4922 char * fontname;
4923 int size;
4924 {
4925 Lisp_Object bdf_fonts;
4926 struct font_info *retval = NULL;
4927 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
4928
4929 bdf_fonts = w32_list_bdf_fonts (build_string (fontname), 1);
4930
4931 while (!retval && CONSP (bdf_fonts))
4932 {
4933 char *bdf_name, *bdf_file;
4934 Lisp_Object bdf_pair;
4935 int i;
4936
4937 bdf_name = SDATA (XCAR (bdf_fonts));
4938 bdf_pair = Fassoc (XCAR (bdf_fonts), Vw32_bdf_filename_alist);
4939 bdf_file = SDATA (XCDR (bdf_pair));
4940
4941 /* If the font is already loaded, do not load it again. */
4942 for (i = 0; i < dpyinfo->n_fonts; i++)
4943 {
4944 if ((dpyinfo->font_table[i].name
4945 && !strcmp (dpyinfo->font_table[i].name, bdf_name))
4946 || (dpyinfo->font_table[i].full_name
4947 && !strcmp (dpyinfo->font_table[i].full_name, bdf_name)))
4948 return dpyinfo->font_table + i;
4949 }
4950
4951 retval = w32_load_bdf_font (f, bdf_name, size, bdf_file);
4952
4953 bdf_fonts = XCDR (bdf_fonts);
4954 }
4955
4956 if (retval)
4957 return retval;
4958
4959 return w32_load_system_font (f, fontname, size);
4960 }
4961
4962
4963 void
4964 w32_unload_font (dpyinfo, font)
4965 struct w32_display_info *dpyinfo;
4966 XFontStruct * font;
4967 {
4968 if (font)
4969 {
4970 xfree (font->per_char);
4971 if (font->bdf) w32_free_bdf_font (font->bdf);
4972
4973 if (font->hfont) DeleteObject (font->hfont);
4974 xfree (font);
4975 }
4976 }
4977 #endif /* OLD_FONT */
4978
4979 /* The font conversion stuff between x and w32 */ 4647 /* The font conversion stuff between x and w32 */
4980 4648
4981 /* X font string is as follows (from faces.el) 4649 /* X font string is as follows (from faces.el)
4982 * (let ((- "[-?]") 4650 * (let ((- "[-?]")
4983 * (foundry "[^-]+") 4651 * (foundry "[^-]+")
5471 5139
5472 return retval; 5140 return retval;
5473 } 5141 }
5474 } 5142 }
5475 5143
5476 #if OLD_FONT
5477
5478 /* Get the Windows codepage corresponding to the specified font. The
5479 charset info in the font name is used to look up
5480 w32-charset-to-codepage-alist. */
5481 int
5482 w32_codepage_for_font (char *fontname)
5483 {
5484 Lisp_Object codepage, entry;
5485 char *charset_str, *charset, *end;
5486
5487 /* Extract charset part of font string. */
5488 charset = xlfd_charset_of_font (fontname);
5489
5490 if (!charset)
5491 return CP_UNKNOWN;
5492
5493 charset_str = (char *) alloca (strlen (charset) + 1);
5494 strcpy (charset_str, charset);
5495
5496 #if 0
5497 /* Remove leading "*-". */
5498 if (strncmp ("*-", charset_str, 2) == 0)
5499 charset = charset_str + 2;
5500 else
5501 #endif
5502 charset = charset_str;
5503
5504 /* Stop match at wildcard (including preceding '-'). */
5505 if (end = strchr (charset, '*'))
5506 {
5507 if (end > charset && *(end-1) == '-')
5508 end--;
5509 *end = '\0';
5510 }
5511
5512 if (!strcmp (charset, "iso10646"))
5513 return CP_UNICODE;
5514
5515 if (NILP (Vw32_charset_info_alist))
5516 return CP_DEFAULT;
5517
5518 entry = Fassoc (build_string(charset), Vw32_charset_info_alist);
5519 if (NILP (entry))
5520 return CP_UNKNOWN;
5521
5522 codepage = Fcdr (Fcdr (entry));
5523
5524 if (NILP (codepage))
5525 return CP_8BIT;
5526 else if (XFASTINT (codepage) == XFASTINT (Qt))
5527 return CP_UNICODE;
5528 else if (INTEGERP (codepage))
5529 return XINT (codepage);
5530 else
5531 return CP_UNKNOWN;
5532 }
5533 #endif /* OLD_FONT */
5534
5535 static BOOL 5144 static BOOL
5536 w32_to_x_font (lplogfont, lpxstr, len, specific_charset) 5145 w32_to_x_font (lplogfont, lpxstr, len, specific_charset)
5537 LOGFONT * lplogfont; 5146 LOGFONT * lplogfont;
5538 char * lpxstr; 5147 char * lpxstr;
5539 int len; 5148 int len;
5814 lplogfont->lfHeight = - eabs (lplogfont->lfHeight); 5423 lplogfont->lfHeight = - eabs (lplogfont->lfHeight);
5815 5424
5816 return (TRUE); 5425 return (TRUE);
5817 } 5426 }
5818 5427
5819 #if OLD_FONT
5820
5821 /* Strip the pixel height and point height from the given xlfd, and
5822 return the pixel height. If no pixel height is specified, calculate
5823 one from the point height, or if that isn't defined either, return
5824 0 (which usually signifies a scalable font).
5825 */
5826 static int
5827 xlfd_strip_height (char *fontname)
5828 {
5829 int pixel_height, field_number;
5830 char *read_from, *write_to;
5831
5832 xassert (fontname);
5833
5834 pixel_height = field_number = 0;
5835 write_to = NULL;
5836
5837 /* Look for height fields. */
5838 for (read_from = fontname; *read_from; read_from++)
5839 {
5840 if (*read_from == '-')
5841 {
5842 field_number++;
5843 if (field_number == 7) /* Pixel height. */
5844 {
5845 read_from++;
5846 write_to = read_from;
5847
5848 /* Find end of field. */
5849 for (;*read_from && *read_from != '-'; read_from++)
5850 ;
5851
5852 /* Split the fontname at end of field. */
5853 if (*read_from)
5854 {
5855 *read_from = '\0';
5856 read_from++;
5857 }
5858 pixel_height = atoi (write_to);
5859 /* Blank out field. */
5860 if (read_from > write_to)
5861 {
5862 *write_to = '-';
5863 write_to++;
5864 }
5865 /* If the pixel height field is at the end (partial xlfd),
5866 return now. */
5867 else
5868 return pixel_height;
5869
5870 /* If we got a pixel height, the point height can be
5871 ignored. Just blank it out and break now. */
5872 if (pixel_height)
5873 {
5874 /* Find end of point size field. */
5875 for (; *read_from && *read_from != '-'; read_from++)
5876 ;
5877
5878 if (*read_from)
5879 read_from++;
5880
5881 /* Blank out the point size field. */
5882 if (read_from > write_to)
5883 {
5884 *write_to = '-';
5885 write_to++;
5886 }
5887 else
5888 return pixel_height;
5889
5890 break;
5891 }
5892 /* If the point height is already blank, break now. */
5893 if (*read_from == '-')
5894 {
5895 read_from++;
5896 break;
5897 }
5898 }
5899 else if (field_number == 8)
5900 {
5901 /* If we didn't get a pixel height, try to get the point
5902 height and convert that. */
5903 int point_size;
5904 char *point_size_start = read_from++;
5905
5906 /* Find end of field. */
5907 for (; *read_from && *read_from != '-'; read_from++)
5908 ;
5909
5910 if (*read_from)
5911 {
5912 *read_from = '\0';
5913 read_from++;
5914 }
5915
5916 point_size = atoi (point_size_start);
5917
5918 /* Convert to pixel height. */
5919 pixel_height = point_size
5920 * one_w32_display_info.height_in / 720;
5921
5922 /* Blank out this field and break. */
5923 *write_to = '-';
5924 write_to++;
5925 break;
5926 }
5927 }
5928 }
5929
5930 /* Shift the rest of the font spec into place. */
5931 if (write_to && read_from > write_to)
5932 {
5933 for (; *read_from; read_from++, write_to++)
5934 *write_to = *read_from;
5935 *write_to = '\0';
5936 }
5937
5938 return pixel_height;
5939 }
5940
5941 /* Assume parameter 1 is fully qualified, no wildcards. */
5942 static BOOL
5943 w32_font_match (fontname, pattern)
5944 char * fontname;
5945 char * pattern;
5946 {
5947 char *ptr;
5948 char *font_name_copy;
5949 char *regex = alloca (strlen (pattern) * 2 + 3);
5950
5951 font_name_copy = alloca (strlen (fontname) + 1);
5952 strcpy (font_name_copy, fontname);
5953
5954 ptr = regex;
5955 *ptr++ = '^';
5956
5957 /* Turn pattern into a regexp and do a regexp match. */
5958 for (; *pattern; pattern++)
5959 {
5960 if (*pattern == '?')
5961 *ptr++ = '.';
5962 else if (*pattern == '*')
5963 {
5964 *ptr++ = '.';
5965 *ptr++ = '*';
5966 }
5967 else
5968 *ptr++ = *pattern;
5969 }
5970 *ptr = '$';
5971 *(ptr + 1) = '\0';
5972
5973 /* Strip out font heights and compare them seperately, since
5974 rounding error can cause mismatches. This also allows a
5975 comparison between a font that declares only a pixel height and a
5976 pattern that declares the point height.
5977 */
5978 {
5979 int font_height, pattern_height;
5980
5981 font_height = xlfd_strip_height (font_name_copy);
5982 pattern_height = xlfd_strip_height (regex);
5983
5984 /* Compare now, and don't bother doing expensive regexp matching
5985 if the heights differ. */
5986 if (font_height && pattern_height && (font_height != pattern_height))
5987 return FALSE;
5988 }
5989
5990 return (fast_string_match_ignore_case (build_string (regex),
5991 build_string (font_name_copy)) >= 0);
5992 }
5993
5994 /* Callback functions, and a structure holding info they need, for
5995 listing system fonts on W32. We need one set of functions to do the
5996 job properly, but these don't work on NT 3.51 and earlier, so we
5997 have a second set which don't handle character sets properly to
5998 fall back on.
5999
6000 In both cases, there are two passes made. The first pass gets one
6001 font from each family, the second pass lists all the fonts from
6002 each family. */
6003
6004 typedef struct enumfont_t
6005 {
6006 HDC hdc;
6007 int numFonts;
6008 LOGFONT logfont;
6009 XFontStruct *size_ref;
6010 Lisp_Object pattern;
6011 Lisp_Object list;
6012 } enumfont_t;
6013
6014
6015 static void
6016 enum_font_maybe_add_to_list (enumfont_t *, LOGFONT *, char *, Lisp_Object);
6017
6018
6019 static int CALLBACK
6020 enum_font_cb2 (lplf, lptm, FontType, lpef)
6021 ENUMLOGFONT * lplf;
6022 NEWTEXTMETRIC * lptm;
6023 int FontType;
6024 enumfont_t * lpef;
6025 {
6026 /* Ignore struck out and underlined versions of fonts. */
6027 if (lplf->elfLogFont.lfStrikeOut || lplf->elfLogFont.lfUnderline)
6028 return 1;
6029
6030 /* Only return fonts with names starting with @ if they were
6031 explicitly specified, since Microsoft uses an initial @ to
6032 denote fonts for vertical writing, without providing a more
6033 convenient way of identifying them. */
6034 if (lplf->elfLogFont.lfFaceName[0] == '@'
6035 && lpef->logfont.lfFaceName[0] != '@')
6036 return 1;
6037
6038 /* Check that the character set matches if it was specified */
6039 if (lpef->logfont.lfCharSet != DEFAULT_CHARSET &&
6040 lplf->elfLogFont.lfCharSet != lpef->logfont.lfCharSet)
6041 return 1;
6042
6043 if (FontType == RASTER_FONTTYPE)
6044 {
6045 /* DBCS raster fonts have problems displaying, so skip them. */
6046 int charset = lplf->elfLogFont.lfCharSet;
6047 if (charset == SHIFTJIS_CHARSET
6048 || charset == HANGEUL_CHARSET
6049 || charset == CHINESEBIG5_CHARSET
6050 || charset == GB2312_CHARSET
6051 #ifdef JOHAB_CHARSET
6052 || charset == JOHAB_CHARSET
6053 #endif
6054 )
6055 return 1;
6056 }
6057
6058 {
6059 char buf[100];
6060 Lisp_Object width = Qnil;
6061 Lisp_Object charset_list = Qnil;
6062 char *charset = NULL;
6063
6064 /* Truetype fonts do not report their true metrics until loaded */
6065 if (FontType != RASTER_FONTTYPE)
6066 {
6067 if (!NILP (lpef->pattern))
6068 {
6069 /* Scalable fonts are as big as you want them to be. */
6070 lplf->elfLogFont.lfHeight = lpef->logfont.lfHeight;
6071 lplf->elfLogFont.lfWidth = lpef->logfont.lfWidth;
6072 width = make_number (lpef->logfont.lfWidth);
6073 }
6074 else
6075 {
6076 lplf->elfLogFont.lfHeight = 0;
6077 lplf->elfLogFont.lfWidth = 0;
6078 }
6079 }
6080
6081 /* Make sure the height used here is the same as everywhere
6082 else (ie character height, not cell height). */
6083 if (lplf->elfLogFont.lfHeight > 0)
6084 {
6085 /* lptm can be trusted for RASTER fonts, but not scalable ones. */
6086 if (FontType == RASTER_FONTTYPE)
6087 lplf->elfLogFont.lfHeight = lptm->tmInternalLeading - lptm->tmHeight;
6088 else
6089 lplf->elfLogFont.lfHeight = -lplf->elfLogFont.lfHeight;
6090 }
6091
6092 if (!NILP (lpef->pattern))
6093 {
6094 charset = xlfd_charset_of_font (SDATA (lpef->pattern));
6095
6096 /* We already checked charsets above, but DEFAULT_CHARSET
6097 slipped through. So only allow exact matches for DEFAULT_CHARSET. */
6098 if (charset
6099 && strncmp (charset, "*-*", 3) != 0
6100 && lpef->logfont.lfCharSet == DEFAULT_CHARSET
6101 && strcmp (charset, w32_to_x_charset (DEFAULT_CHARSET, NULL)) != 0)
6102 return 1;
6103
6104 /* Reject raster fonts if we are looking for a unicode font. */
6105 if (charset
6106 && FontType == RASTER_FONTTYPE
6107 && strncmp (charset, "iso10646", 8) == 0)
6108 return 1;
6109 }
6110
6111 if (charset)
6112 charset_list = Fcons (build_string (charset), Qnil);
6113 else
6114 /* Always prefer unicode. */
6115 charset_list
6116 = Fcons (build_string ("iso10646-1"),
6117 w32_to_all_x_charsets (lplf->elfLogFont.lfCharSet));
6118
6119 /* Loop through the charsets. */
6120 for ( ; CONSP (charset_list); charset_list = Fcdr (charset_list))
6121 {
6122 Lisp_Object this_charset = Fcar (charset_list);
6123 charset = SDATA (this_charset);
6124
6125 /* Don't list raster fonts as unicode. */
6126 if (charset
6127 && FontType == RASTER_FONTTYPE
6128 && strncmp (charset, "iso10646", 8) == 0)
6129 continue;
6130
6131 enum_font_maybe_add_to_list (lpef, &(lplf->elfLogFont),
6132 charset, width);
6133
6134 /* List bold and italic variations if w32-enable-synthesized-fonts
6135 is non-nil and this is a plain font. */
6136 if (w32_enable_synthesized_fonts
6137 && lplf->elfLogFont.lfWeight == FW_NORMAL
6138 && lplf->elfLogFont.lfItalic == FALSE)
6139 {
6140 /* bold. */
6141 lplf->elfLogFont.lfWeight = FW_BOLD;
6142 enum_font_maybe_add_to_list (lpef, &(lplf->elfLogFont),
6143 charset, width);
6144 /* bold italic. */
6145 lplf->elfLogFont.lfItalic = TRUE;
6146 enum_font_maybe_add_to_list (lpef, &(lplf->elfLogFont),
6147 charset, width);
6148 /* italic. */
6149 lplf->elfLogFont.lfWeight = FW_NORMAL;
6150 enum_font_maybe_add_to_list (lpef, &(lplf->elfLogFont),
6151 charset, width);
6152 }
6153 }
6154 }
6155
6156 return 1;
6157 }
6158
6159 static void
6160 enum_font_maybe_add_to_list (lpef, logfont, match_charset, width)
6161 enumfont_t * lpef;
6162 LOGFONT * logfont;
6163 char * match_charset;
6164 Lisp_Object width;
6165 {
6166 char buf[100];
6167
6168 if (!w32_to_x_font (logfont, buf, 100, match_charset))
6169 return;
6170
6171 if (NILP (lpef->pattern)
6172 || w32_font_match (buf, SDATA (lpef->pattern)))
6173 {
6174 /* Check if we already listed this font. This may happen if
6175 w32_enable_synthesized_fonts is non-nil, and there are real
6176 bold and italic versions of the font. */
6177 Lisp_Object font_name = build_string (buf);
6178 if (NILP (Fmember (font_name, lpef->list)))
6179 {
6180 Lisp_Object entry = Fcons (font_name, width);
6181 lpef->list = Fcons (entry, lpef->list);
6182 lpef->numFonts++;
6183 }
6184 }
6185 }
6186
6187
6188 static int CALLBACK
6189 enum_font_cb1 (lplf, lptm, FontType, lpef)
6190 ENUMLOGFONT * lplf;
6191 NEWTEXTMETRIC * lptm;
6192 int FontType;
6193 enumfont_t * lpef;
6194 {
6195 return EnumFontFamilies (lpef->hdc,
6196 lplf->elfLogFont.lfFaceName,
6197 (FONTENUMPROC) enum_font_cb2,
6198 (LPARAM) lpef);
6199 }
6200
6201
6202 static int CALLBACK
6203 enum_fontex_cb2 (lplf, lptm, font_type, lpef)
6204 ENUMLOGFONTEX * lplf;
6205 NEWTEXTMETRICEX * lptm;
6206 int font_type;
6207 enumfont_t * lpef;
6208 {
6209 /* We are not interested in the extra info we get back from the 'Ex
6210 version - only the fact that we get character set variations
6211 enumerated seperately. */
6212 return enum_font_cb2 ((ENUMLOGFONT *) lplf, (NEWTEXTMETRIC *) lptm,
6213 font_type, lpef);
6214 }
6215
6216 static int CALLBACK
6217 enum_fontex_cb1 (lplf, lptm, font_type, lpef)
6218 ENUMLOGFONTEX * lplf;
6219 NEWTEXTMETRICEX * lptm;
6220 int font_type;
6221 enumfont_t * lpef;
6222 {
6223 HMODULE gdi32 = GetModuleHandle ("gdi32.dll");
6224 FARPROC enum_font_families_ex
6225 = GetProcAddress ( gdi32, "EnumFontFamiliesExA");
6226 /* We don't really expect EnumFontFamiliesEx to disappear once we
6227 get here, so don't bother handling it gracefully. */
6228 if (enum_font_families_ex == NULL)
6229 error ("gdi32.dll has disappeared!");
6230 return enum_font_families_ex (lpef->hdc,
6231 &lplf->elfLogFont,
6232 (FONTENUMPROC) enum_fontex_cb2,
6233 (LPARAM) lpef, 0);
6234 }
6235
6236 /* Interface to fontset handler. (adapted from mw32font.c in Meadow
6237 and xterm.c in Emacs 20.3) */
6238
6239 static Lisp_Object
6240 w32_list_bdf_fonts (Lisp_Object pattern, int max_names)
6241 {
6242 char *fontname, *ptnstr;
6243 Lisp_Object list, tem, newlist = Qnil;
6244 int n_fonts = 0;
6245
6246 list = Vw32_bdf_filename_alist;
6247 ptnstr = SDATA (pattern);
6248
6249 for ( ; CONSP (list); list = XCDR (list))
6250 {
6251 tem = XCAR (list);
6252 if (CONSP (tem))
6253 fontname = SDATA (XCAR (tem));
6254 else if (STRINGP (tem))
6255 fontname = SDATA (tem);
6256 else
6257 continue;
6258
6259 if (w32_font_match (fontname, ptnstr))
6260 {
6261 newlist = Fcons (XCAR (tem), newlist);
6262 n_fonts++;
6263 if (max_names >= 0 && n_fonts >= max_names)
6264 break;
6265 }
6266 }
6267
6268 return newlist;
6269 }
6270
6271
6272 /* Return a list of names of available fonts matching PATTERN on frame
6273 F. If SIZE is not 0, it is the size (maximum bound width) of fonts
6274 to be listed. Frame F NULL means we have not yet created any
6275 frame, which means we can't get proper size info, as we don't have
6276 a device context to use for GetTextMetrics.
6277 MAXNAMES sets a limit on how many fonts to match. If MAXNAMES is
6278 negative, then all matching fonts are returned. */
6279
6280 Lisp_Object
6281 w32_list_fonts (f, pattern, size, maxnames)
6282 struct frame *f;
6283 Lisp_Object pattern;
6284 int size;
6285 int maxnames;
6286 {
6287 Lisp_Object patterns, key = Qnil, tem, tpat;
6288 Lisp_Object list = Qnil, newlist = Qnil, second_best = Qnil;
6289 struct w32_display_info *dpyinfo = &one_w32_display_info;
6290 int n_fonts = 0;
6291
6292 patterns = Fassoc (pattern, Valternate_fontname_alist);
6293 if (NILP (patterns))
6294 patterns = Fcons (pattern, Qnil);
6295
6296 for (; CONSP (patterns); patterns = XCDR (patterns))
6297 {
6298 enumfont_t ef;
6299 int codepage;
6300
6301 tpat = XCAR (patterns);
6302
6303 if (!STRINGP (tpat))
6304 continue;
6305
6306 /* Avoid expensive EnumFontFamilies functions if we are not
6307 going to be able to output one of these anyway. */
6308 codepage = w32_codepage_for_font (SDATA (tpat));
6309 if (codepage != CP_8BIT && codepage != CP_UNICODE
6310 && codepage != CP_DEFAULT && codepage != CP_UNKNOWN
6311 && !IsValidCodePage (codepage))
6312 continue;
6313
6314 /* See if we cached the result for this particular query.
6315 The cache is an alist of the form:
6316 ((PATTERN (FONTNAME . WIDTH) ...) ...)
6317 */
6318 if (tem = XCDR (dpyinfo->name_list_element),
6319 !NILP (list = Fassoc (tpat, tem)))
6320 {
6321 list = Fcdr_safe (list);
6322 /* We have a cached list. Don't have to get the list again. */
6323 goto label_cached;
6324 }
6325
6326 BLOCK_INPUT;
6327 /* At first, put PATTERN in the cache. */
6328 ef.pattern = tpat;
6329 ef.list = Qnil;
6330 ef.numFonts = 0;
6331
6332 /* Use EnumFontFamiliesEx where it is available, as it knows
6333 about character sets. Fall back to EnumFontFamilies for
6334 older versions of NT that don't support the 'Ex function. */
6335 x_to_w32_font (SDATA (tpat), &ef.logfont);
6336 {
6337 LOGFONT font_match_pattern;
6338 HMODULE gdi32 = GetModuleHandle ("gdi32.dll");
6339 FARPROC enum_font_families_ex
6340 = GetProcAddress ( gdi32, "EnumFontFamiliesExA");
6341
6342 /* We do our own pattern matching so we can handle wildcards. */
6343 font_match_pattern.lfFaceName[0] = 0;
6344 font_match_pattern.lfPitchAndFamily = 0;
6345 /* We can use the charset, because if it is a wildcard it will
6346 be DEFAULT_CHARSET anyway. */
6347 font_match_pattern.lfCharSet = ef.logfont.lfCharSet;
6348
6349 ef.hdc = GetDC (dpyinfo->root_window);
6350
6351 if (enum_font_families_ex)
6352 enum_font_families_ex (ef.hdc,
6353 &font_match_pattern,
6354 (FONTENUMPROC) enum_fontex_cb1,
6355 (LPARAM) &ef, 0);
6356 else
6357 EnumFontFamilies (ef.hdc, NULL, (FONTENUMPROC) enum_font_cb1,
6358 (LPARAM)&ef);
6359
6360 ReleaseDC (dpyinfo->root_window, ef.hdc);
6361 }
6362
6363 UNBLOCK_INPUT;
6364 list = ef.list;
6365
6366 /* Make a list of the fonts we got back.
6367 Store that in the font cache for the display. */
6368 XSETCDR (dpyinfo->name_list_element,
6369 Fcons (Fcons (tpat, list),
6370 XCDR (dpyinfo->name_list_element)));
6371
6372 label_cached:
6373 if (NILP (list)) continue; /* Try the remaining alternatives. */
6374
6375 newlist = second_best = Qnil;
6376
6377 /* Make a list of the fonts that have the right width. */
6378 for (; CONSP (list); list = XCDR (list))
6379 {
6380 int found_size;
6381 tem = XCAR (list);
6382
6383 if (!CONSP (tem))
6384 continue;
6385 if (NILP (XCAR (tem)))
6386 continue;
6387 if (!size)
6388 {
6389 newlist = Fcons (XCAR (tem), newlist);
6390 n_fonts++;
6391 if (maxnames >= 0 && n_fonts >= maxnames)
6392 break;
6393 else
6394 continue;
6395 }
6396 if (!INTEGERP (XCDR (tem)))
6397 {
6398 /* Since we don't yet know the size of the font, we must
6399 load it and try GetTextMetrics. */
6400 W32FontStruct thisinfo;
6401 LOGFONT lf;
6402 HDC hdc;
6403 HANDLE oldobj;
6404
6405 if (!x_to_w32_font (SDATA (XCAR (tem)), &lf))
6406 continue;
6407
6408 BLOCK_INPUT;
6409 thisinfo.bdf = NULL;
6410 thisinfo.hfont = CreateFontIndirect (&lf);
6411 if (thisinfo.hfont == NULL)
6412 continue;
6413
6414 hdc = GetDC (dpyinfo->root_window);
6415 oldobj = SelectObject (hdc, thisinfo.hfont);
6416 if (GetTextMetrics (hdc, &thisinfo.tm))
6417 XSETCDR (tem, make_number (FONT_AVG_WIDTH (&thisinfo)));
6418 else
6419 XSETCDR (tem, make_number (0));
6420 SelectObject (hdc, oldobj);
6421 ReleaseDC (dpyinfo->root_window, hdc);
6422 DeleteObject (thisinfo.hfont);
6423 UNBLOCK_INPUT;
6424 }
6425 found_size = XINT (XCDR (tem));
6426 if (found_size == size)
6427 {
6428 newlist = Fcons (XCAR (tem), newlist);
6429 n_fonts++;
6430 if (maxnames >= 0 && n_fonts >= maxnames)
6431 break;
6432 }
6433 /* keep track of the closest matching size in case
6434 no exact match is found. */
6435 else if (found_size > 0)
6436 {
6437 if (NILP (second_best))
6438 second_best = tem;
6439
6440 else if (found_size < size)
6441 {
6442 if (XINT (XCDR (second_best)) > size
6443 || XINT (XCDR (second_best)) < found_size)
6444 second_best = tem;
6445 }
6446 else
6447 {
6448 if (XINT (XCDR (second_best)) > size
6449 && XINT (XCDR (second_best)) >
6450 found_size)
6451 second_best = tem;
6452 }
6453 }
6454 }
6455
6456 if (!NILP (newlist))
6457 break;
6458 else if (!NILP (second_best))
6459 {
6460 newlist = Fcons (XCAR (second_best), Qnil);
6461 break;
6462 }
6463 }
6464
6465 /* Include any bdf fonts. */
6466 if (n_fonts < maxnames || maxnames < 0)
6467 {
6468 Lisp_Object combined[2];
6469 combined[0] = w32_list_bdf_fonts (pattern, maxnames - n_fonts);
6470 combined[1] = newlist;
6471 newlist = Fnconc (2, combined);
6472 }
6473
6474 return newlist;
6475 }
6476
6477
6478 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
6479 struct font_info *
6480 w32_get_font_info (f, font_idx)
6481 FRAME_PTR f;
6482 int font_idx;
6483 {
6484 return (FRAME_W32_FONT_TABLE (f) + font_idx);
6485 }
6486
6487
6488 struct font_info*
6489 w32_query_font (struct frame *f, char *fontname)
6490 {
6491 int i;
6492 struct font_info *pfi;
6493
6494 pfi = FRAME_W32_FONT_TABLE (f);
6495
6496 for (i = 0; i < one_w32_display_info.n_fonts ;i++, pfi++)
6497 {
6498 if (xstrcasecmp (pfi->name, fontname) == 0) return pfi;
6499 }
6500
6501 return NULL;
6502 }
6503
6504 /* Find a CCL program for a font specified by FONTP, and set the member
6505 `encoder' of the structure. */
6506
6507 void
6508 w32_find_ccl_program (fontp)
6509 struct font_info *fontp;
6510 {
6511 Lisp_Object list, elt;
6512
6513 for (list = Vfont_ccl_encoder_alist; CONSP (list); list = XCDR (list))
6514 {
6515 elt = XCAR (list);
6516 if (CONSP (elt)
6517 && STRINGP (XCAR (elt))
6518 && (fast_c_string_match_ignore_case (XCAR (elt), fontp->name)
6519 >= 0))
6520 break;
6521 }
6522 if (! NILP (list))
6523 {
6524 struct ccl_program *ccl
6525 = (struct ccl_program *) xmalloc (sizeof (struct ccl_program));
6526
6527 if (setup_ccl_program (ccl, XCDR (elt)) < 0)
6528 xfree (ccl);
6529 else
6530 fontp->font_encoder = ccl;
6531 }
6532 }
6533
6534 #endif /* OLD_FONT */
6535
6536 /* directory-files from dired.c. */
6537 Lisp_Object Fdirectory_files P_ ((Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object));
6538
6539
6540 #if OLD_FONT
6541
6542 /* Find BDF files in a specified directory. (use GCPRO when calling,
6543 as this calls lisp to get a directory listing). */
6544 static Lisp_Object
6545 w32_find_bdf_fonts_in_dir (Lisp_Object directory)
6546 {
6547 Lisp_Object filelist, list = Qnil;
6548 char fontname[100];
6549
6550 if (!STRINGP (directory))
6551 return Qnil;
6552
6553 filelist = Fdirectory_files (directory, Qt,
6554 build_string (".*\\.[bB][dD][fF]"), Qt);
6555
6556 for ( ; CONSP (filelist); filelist = XCDR (filelist))
6557 {
6558 Lisp_Object filename = XCAR (filelist);
6559 if (w32_BDF_to_x_font (SDATA (filename), fontname, 100))
6560 store_in_alist (&list, build_string (fontname), filename);
6561 }
6562 return list;
6563 }
6564
6565 DEFUN ("w32-find-bdf-fonts", Fw32_find_bdf_fonts, Sw32_find_bdf_fonts,
6566 1, 1, 0,
6567 doc: /* Return a list of BDF fonts in DIRECTORY.
6568 The list is suitable for appending to `w32-bdf-filename-alist'.
6569 Fonts which do not contain an xlfd description will not be included
6570 in the list. DIRECTORY may be a list of directories. */)
6571 (directory)
6572 Lisp_Object directory;
6573 {
6574 Lisp_Object list = Qnil;
6575 struct gcpro gcpro1, gcpro2;
6576
6577 if (!CONSP (directory))
6578 return w32_find_bdf_fonts_in_dir (directory);
6579
6580 for ( ; CONSP (directory); directory = XCDR (directory))
6581 {
6582 Lisp_Object pair[2];
6583 pair[0] = list;
6584 pair[1] = Qnil;
6585 GCPRO2 (directory, list);
6586 pair[1] = w32_find_bdf_fonts_in_dir ( XCAR (directory) );
6587 list = Fnconc ( 2, pair );
6588 UNGCPRO;
6589 }
6590 return list;
6591 }
6592 #endif /* OLD_FONT */
6593 5428
6594 5429
6595 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0, 5430 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
6596 doc: /* Internal function called by `color-defined-p', which see. */) 5431 doc: /* Internal function called by `color-defined-p', which see. */)
6597 (color, frame) 5432 (color, frame)
7058 5893
7059 if (dpyinfo->reference_count > 0) 5894 if (dpyinfo->reference_count > 0)
7060 error ("Display still has frames on it"); 5895 error ("Display still has frames on it");
7061 5896
7062 BLOCK_INPUT; 5897 BLOCK_INPUT;
7063 #if OLD_FONT
7064 /* Free the fonts in the font table. */
7065 for (i = 0; i < dpyinfo->n_fonts; i++)
7066 if (dpyinfo->font_table[i].name)
7067 {
7068 if (dpyinfo->font_table[i].name != dpyinfo->font_table[i].full_name)
7069 xfree (dpyinfo->font_table[i].full_name);
7070 xfree (dpyinfo->font_table[i].name);
7071 w32_unload_font (dpyinfo, dpyinfo->font_table[i].font);
7072 }
7073 #endif
7074 x_destroy_all_bitmaps (dpyinfo); 5898 x_destroy_all_bitmaps (dpyinfo);
7075 5899
7076 x_delete_display (dpyinfo); 5900 x_delete_display (dpyinfo);
7077 UNBLOCK_INPUT; 5901 UNBLOCK_INPUT;
7078 5902
9274 defsubr (&Sw32_unregister_hot_key); 8098 defsubr (&Sw32_unregister_hot_key);
9275 defsubr (&Sw32_registered_hot_keys); 8099 defsubr (&Sw32_registered_hot_keys);
9276 defsubr (&Sw32_reconstruct_hot_key); 8100 defsubr (&Sw32_reconstruct_hot_key);
9277 defsubr (&Sw32_toggle_lock_key); 8101 defsubr (&Sw32_toggle_lock_key);
9278 defsubr (&Sw32_window_exists_p); 8102 defsubr (&Sw32_window_exists_p);
9279 #if OLD_FONT
9280 defsubr (&Sw32_find_bdf_fonts);
9281 #endif
9282 defsubr (&Sw32_battery_status); 8103 defsubr (&Sw32_battery_status);
9283 8104
9284 defsubr (&Sfile_system_info); 8105 defsubr (&Sfile_system_info);
9285 defsubr (&Sdefault_printer_name); 8106 defsubr (&Sdefault_printer_name);
9286 8107
9287 #if OLD_FONT
9288 /* Setting callback functions for fontset handler. */
9289 get_font_info_func = w32_get_font_info;
9290
9291 #if 0 /* This function pointer doesn't seem to be used anywhere.
9292 And the pointer assigned has the wrong type, anyway. */
9293 list_fonts_func = w32_list_fonts;
9294 #endif
9295
9296 load_font_func = w32_load_font;
9297 find_ccl_program_func = w32_find_ccl_program;
9298 query_font_func = w32_query_font;
9299 set_frame_fontset_func = x_set_font;
9300 get_font_repertory_func = x_get_font_repertory;
9301 #endif
9302 check_window_system_func = check_w32; 8108 check_window_system_func = check_w32;
9303 8109
9304 8110
9305 hourglass_timer = 0; 8111 hourglass_timer = 0;
9306 hourglass_hwnd = NULL; 8112 hourglass_hwnd = NULL;