diff src/device-msw.c @ 294:4b85ae5eabfb r21-0b45

Import from CVS: tag r21-0b45
author cvs
date Mon, 13 Aug 2007 10:38:01 +0200
parents e11d67e05968
children 5a79be0ef6a8
line wrap: on
line diff
--- a/src/device-msw.c	Mon Aug 13 10:37:16 2007 +0200
+++ b/src/device-msw.c	Mon Aug 13 10:38:01 2007 +0200
@@ -62,25 +62,138 @@
 
 Lisp_Object Qinit_pre_mswindows_win, Qinit_post_mswindows_win;
 
+struct font_enum_t
+{
+  HDC hdc;
+  struct device *d;
+};
+
+
+/************************************************************************/
+/*                               helpers                                */
+/************************************************************************/
+
+static int CALLBACK
+font_enum_callback_2 (ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, 
+		      int FontType, struct font_enum_t *font_enum)
+{
+  struct mswindows_font_enum *fontlist, **fonthead;
+  char fontname[MSW_FONTSIZE];
+
+  /* The enumerated font weights are not to be trusted because:
+   *  a) lpelfe->elfStyle is only filled in for TrueType fonts.
+   *  b) Not all Bold and Italic styles of all fonts (inluding some Vector,
+   *     Truetype and Raster fonts) are enumerated.
+   * I guess that fonts for which Bold and Italic styles are generated
+   * 'on-the-fly' are not enumerated. It would be overly restrictive to
+   * disallow Bold And Italic weights for these fonts, so we just leave
+   * weights unspecified. This means that we have to weed out duplicates of
+   * those fonts that do get enumerated with different weights. */
+
+  if (FontType == 0 /*vector*/ || FontType == TRUETYPE_FONTTYPE)
+    /* Scalable, so leave pointsize blank */
+    sprintf (fontname, "%s::::%s", lpelfe->elfLogFont.lfFaceName,
+	     lpelfe->elfScript);
+  else
+    /* Formula for pointsize->height from LOGFONT docs in Platform SDK */
+    sprintf (fontname, "%s::%d::%s", lpelfe->elfLogFont.lfFaceName,
+	     MulDiv (lpntme->ntmTm.tmHeight - lpntme->ntmTm.tmInternalLeading,
+	             72, DEVICE_MSWINDOWS_LOGPIXELSY (font_enum->d)),
+             lpelfe->elfScript);
+
+  fonthead = &DEVICE_MSWINDOWS_FONTLIST (font_enum->d);
+  fontlist = *fonthead;
+  while (fontlist)
+    if (!strcmp (fontname, fontlist->fontname))
+      return 1;		/* found a duplicate */
+    else
+      fontlist = fontlist->next;
+
+  /* Insert entry at head */
+  fontlist = *fonthead;
+  *fonthead = xmalloc (sizeof (struct mswindows_font_enum));
+  if (*fonthead == NULL)
+    {
+      *fonthead = fontlist;
+      return 0;
+    }
+  strcpy ((*fonthead)->fontname, fontname);
+  (*fonthead)->next = fontlist;
+  return 1;
+}
+
+static int CALLBACK
+font_enum_callback_1 (ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, 
+		      int FontType, struct font_enum_t *font_enum)
+{
+  /* This function gets called once per facename per character set.
+   * We call a second callback to enumerate the fonts in each facename */
+  return EnumFontFamiliesEx (font_enum->hdc, &lpelfe->elfLogFont,
+			     (FONTENUMPROC) font_enum_callback_2,
+			     (LPARAM) font_enum, 0);
+}
+
+static Lisp_Object
+build_syscolor_string (int index)
+{
+  DWORD clr;
+  char buf[16];
+
+  if (index < 0)
+    return Qnil;
+
+  clr = GetSysColor (index);
+  sprintf (buf, "#%02X%02X%02X",
+	   GetRValue (clr),
+	   GetGValue (clr),
+	   GetBValue (clr));
+  return build_string (buf);
+}
+
+static Lisp_Object
+build_syscolor_cons (int index1, int index2)
+{
+  Lisp_Object color1, color2;
+  struct gcpro gcpro1;
+  GCPRO1 (color1);
+  color1 = build_syscolor_string (index1);
+  color2 = build_syscolor_string (index2);
+  RETURN_UNGCPRO (Fcons (color1, color2));
+}
+
+static Lisp_Object
+build_sysmetrics_cons (int index1, int index2)
+{
+  return Fcons (index1 < 0 ? Qnil : make_int (GetSystemMetrics (index1)),
+		index2 < 0 ? Qnil : make_int (GetSystemMetrics (index2)));
+}
+
+
+
+/************************************************************************/
+/*                               methods                                */
+/************************************************************************/
+
 static void
 mswindows_init_device (struct device *d, Lisp_Object props)
 {
   WNDCLASSEX wc;
-  HWND desktop;
   HDC hdc;
+  LOGFONT logfont;
+  struct font_enum_t font_enum;
 
+  DEVICE_CLASS (d) = Qcolor;
   DEVICE_INFD (d) = DEVICE_OUTFD (d) = -1;
   init_baud_rate (d);
   init_one_device (d);
 
   d->device_data = xnew_and_zero (struct mswindows_device);
-
-  desktop = GetDesktopWindow();
-  hdc = GetDC(desktop);
+  hdc = CreateCompatibleDC (NULL);
+  assert (hdc!=NULL);
   DEVICE_MSWINDOWS_LOGPIXELSX(d) =  GetDeviceCaps(hdc, LOGPIXELSX);
   DEVICE_MSWINDOWS_LOGPIXELSY(d) =  GetDeviceCaps(hdc, LOGPIXELSY);
   DEVICE_MSWINDOWS_PLANES(d) = GetDeviceCaps(hdc, PLANES);
-  /* FIXME: Only valid if RC_PALETTE bit set in RASTERCAPS,
+  /* #### SIZEPALETTE only valid if RC_PALETTE bit set in RASTERCAPS,
      what should we return for a non-palette-based device? */
   DEVICE_MSWINDOWS_CELLS(d) = GetDeviceCaps(hdc, SIZEPALETTE);
   DEVICE_MSWINDOWS_HORZRES(d) = GetDeviceCaps(hdc, HORZRES);
@@ -88,9 +201,16 @@
   DEVICE_MSWINDOWS_HORZSIZE(d) = GetDeviceCaps(hdc, HORZSIZE);
   DEVICE_MSWINDOWS_VERTSIZE(d) = GetDeviceCaps(hdc, VERTSIZE);
   DEVICE_MSWINDOWS_BITSPIXEL(d) = GetDeviceCaps(hdc, BITSPIXEL);
-  ReleaseDC(desktop, hdc);
 
-  DEVICE_CLASS(d) = Qcolor;
+  DEVICE_MSWINDOWS_FONTLIST (d) = NULL;
+  logfont.lfCharSet = DEFAULT_CHARSET;
+  logfont.lfFaceName[0] = '\0';
+  logfont.lfPitchAndFamily = DEFAULT_PITCH;
+  font_enum.hdc = hdc;
+  font_enum.d = d;
+  EnumFontFamiliesEx (hdc, &logfont, (FONTENUMPROC) font_enum_callback_1,
+		      (LPARAM) (&font_enum), 0);
+  DeleteDC (hdc);
 
   /* Register the main window class */
   wc.cbSize = sizeof (WNDCLASSEX);
@@ -137,45 +257,22 @@
 static void
 mswindows_delete_device (struct device *d)
 {
+  struct mswindows_font_enum *fontlist, *next;
+
+  fontlist = DEVICE_MSWINDOWS_FONTLIST (d);
+  while (fontlist)
+    {
+      next = fontlist->next;
+      free (fontlist);
+      fontlist = next;
+    }
+
 #ifdef HAVE_DRAGNDROP
   DdeNameService (mswindows_dde_mlid, 0L, 0L, DNS_REGISTER);
   DdeUninitialize (mswindows_dde_mlid);
 #endif
-}
 
-static Lisp_Object
-build_syscolor_string (int index)
-{
-  DWORD clr;
-  char buf[16];
-
-  if (index < 0)
-    return Qnil;
-
-  clr = GetSysColor (index);
-  sprintf (buf, "#%02X%02X%02X",
-	   GetRValue (clr),
-	   GetGValue (clr),
-	   GetBValue (clr));
-  return build_string (buf);
-}
-
-static Lisp_Object
-build_syscolor_cons (int index1, int index2)
-{
-  Lisp_Object color1, color2;
-  struct gcpro gcpro1;
-  GCPRO1 (color1);
-  color1 = build_syscolor_string (index1);
-  color2 = build_syscolor_string (index2);
-  RETURN_UNGCPRO (Fcons (color1, color2));
-}
-
-static Lisp_Object
-build_sysmetrics_cons (int index1, int index2)
-{
-  return Fcons (index1 < 0 ? Qnil : make_int (GetSystemMetrics (index1)),
-		index2 < 0 ? Qnil : make_int (GetSystemMetrics (index2)));
+  free (d->device_data);
 }
 
 static Lisp_Object
@@ -271,6 +368,7 @@
 {
   return XDEVIMPF_PIXEL_GEOMETRY;
 }
+
 
 /************************************************************************/
 /*                            initialization                            */