emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r106213: Fix bug #8562 with Emacs dis


From: Eli Zaretskii
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r106213: Fix bug #8562 with Emacs display on Windows 9X.
Date: Fri, 28 Oct 2011 11:54:02 +0200
User-agent: Bazaar (2.3.1)

------------------------------------------------------------
revno: 106213
fixes bug(s): http://debbugs.gnu.org/8562
committer: Eli Zaretskii <address@hidden>
branch nick: trunk
timestamp: Fri 2011-10-28 11:54:02 +0200
message:
  Fix bug #8562 with Emacs display on Windows 9X.
  Thanks to oslsachem <address@hidden> for helping to debug this.
  
   src/w32font.c (g_b_init_is_w9x, g_b_init_get_outline_metrics_w)
   (g_b_init_get_text_metrics_w, g_b_init_get_glyph_outline_w)
   (g_b_init_get_glyph_outline_w): New static variables.
   (GetOutlineTextMetricsW_Proc, GetTextMetricsW_Proc)
   (GetGlyphOutlineW_Proc): New typedefs.
   (w32_load_unicows_or_gdi32, get_outline_metrics_w)
   (get_text_metrics_w, get_glyph_outline_w, globals_of_w32font): New
   functions.
   (w32font_open_internal, compute_metrics): Call
   get_outline_metrics_w, get_text_metrics_w, and get_glyph_outline_w
   instead of calling the "wide" APIs directly.
   src/emacs.c (main) [HAVE_NTGUI]: Call globals_of_w32font.
   src/w32.h (syms_of_w32font): Add prototype.
modified:
  src/ChangeLog
  src/emacs.c
  src/w32.h
  src/w32font.c
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2011-10-27 14:35:51 +0000
+++ b/src/ChangeLog     2011-10-28 09:54:02 +0000
@@ -1,3 +1,24 @@
+2011-10-28  Eli Zaretskii  <address@hidden>
+
+       Fix Emacs on Windows 9X (bug#8562).  Thanks to oslsachem
+       <address@hidden> for helping to debug this.
+
+       * w32font.c (g_b_init_is_w9x, g_b_init_get_outline_metrics_w)
+       (g_b_init_get_text_metrics_w, g_b_init_get_glyph_outline_w)
+       (g_b_init_get_glyph_outline_w): New static variables.
+       (GetOutlineTextMetricsW_Proc, GetTextMetricsW_Proc)
+       (GetGlyphOutlineW_Proc): New typedefs.
+       (w32_load_unicows_or_gdi32, get_outline_metrics_w)
+       (get_text_metrics_w, get_glyph_outline_w, globals_of_w32font): New
+       functions.
+       (w32font_open_internal, compute_metrics): Call
+       get_outline_metrics_w, get_text_metrics_w, and get_glyph_outline_w
+       instead of calling the "wide" APIs directly.
+
+       * emacs.c (main) [HAVE_NTGUI]: Call globals_of_w32font.
+
+       * w32.h (syms_of_w32font): Add prototype.
+
 2011-10-27  Juanma Barranquero  <address@hidden>
 
        * window.c (Fframe_root_window, Fframe_first_window, Fwindow_end)

=== modified file 'src/emacs.c'
--- a/src/emacs.c       2011-09-24 09:22:06 +0000
+++ b/src/emacs.c       2011-10-28 09:54:02 +0000
@@ -1591,6 +1591,7 @@
       /* Initialization that must be done even if the global variable
         initialized is non zero.  */
 #ifdef HAVE_NTGUI
+      globals_of_w32font ();
       globals_of_w32fns ();
       globals_of_w32menu ();
       globals_of_w32select ();

=== modified file 'src/w32.h'
--- a/src/w32.h 2011-05-04 14:03:16 +0000
+++ b/src/w32.h 2011-10-28 09:54:02 +0000
@@ -139,6 +139,7 @@
 extern void syms_of_w32menu (void);
 extern void globals_of_w32menu (void);
 extern void syms_of_fontset (void);
+extern void syms_of_w32font (void);
 
 extern int _sys_read_ahead (int fd);
 extern int _sys_wait_accept (int fd);

=== modified file 'src/w32font.c'
--- a/src/w32font.c     2011-10-27 00:59:21 +0000
+++ b/src/w32font.c     2011-10-28 09:54:02 +0000
@@ -145,6 +145,137 @@
    style variations if the font name is not specified.  */
 static void list_all_matching_fonts (struct font_callback_data *);
 
+static BOOL g_b_init_is_w9x;
+static BOOL g_b_init_get_outline_metrics_w;
+static BOOL g_b_init_get_text_metrics_w;
+static BOOL g_b_init_get_glyph_outline_w;
+static BOOL g_b_init_get_glyph_outline_w;
+
+typedef UINT (WINAPI * GetOutlineTextMetricsW_Proc) (
+   HDC hdc,
+   UINT cbData,
+   LPOUTLINETEXTMETRICW lpotmw);
+typedef BOOL (WINAPI * GetTextMetricsW_Proc) (
+   HDC hdc,
+   LPTEXTMETRICW lptmw);
+typedef DWORD (WINAPI * GetGlyphOutlineW_Proc) (
+   HDC hdc,
+   UINT uChar,
+   UINT uFormat,
+   LPGLYPHMETRICS lpgm,
+   DWORD cbBuffer,
+   LPVOID lpvBuffer,
+   const MAT2 *lpmat2);
+
+/* Several "wide" functions we use to support the font backends are
+   unavailable on Windows 9X, unless UNICOWS.DLL is installed (their
+   versions in the default libraries are non-functional stubs).  On NT
+   and later systems, these functions are in GDI32.DLL.  The following
+   helper function attempts to load UNICOWS.DLL on Windows 9X, and
+   refuses to let Emacs start up if that library is not found.  On NT
+   and later versions, it simply loads GDI32.DLL, which should always
+   be available.  */
+static HMODULE
+w32_load_unicows_or_gdi32 (void)
+{
+  static BOOL is_9x = 0;
+  OSVERSIONINFO os_ver;
+  HMODULE ret;
+  if (g_b_init_is_w9x == 0)
+    {
+      g_b_init_is_w9x = 1;
+      ZeroMemory (&os_ver, sizeof (OSVERSIONINFO));
+      os_ver.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
+      if (GetVersionEx (&os_ver))
+       is_9x = (os_ver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
+    }
+  if (is_9x)
+    {
+      ret = LoadLibrary ("Unicows.dll");
+      if (!ret)
+       {
+         int button;
+
+         button = MessageBox (NULL,
+                              "Emacs cannot load the UNICOWS.DLL library.\n"
+                              "This library is essential for using Emacs\n"
+                              "on this system.  You need to install it.\n\n"
+                              "However, you can still use Emacs by invoking\n"
+                              "it with the '-nw' command-line option.\n\n"
+                              "Emacs will exit when you click OK.",
+                              "Emacs cannot load UNICOWS.DLL",
+                              MB_ICONERROR | MB_TASKMODAL
+                              | MB_SETFOREGROUND | MB_OK);
+         switch (button)
+           {
+           case IDOK:
+           default:
+             exit (1);
+           }
+       }
+    }
+  else
+    ret = LoadLibrary ("Gdi32.dll");
+}
+
+/* The following 3 functions call the problematic "wide" APIs via
+   function pointers, to avoid linking against the non-standard
+   libunicows on W9X.  */
+static UINT WINAPI
+get_outline_metrics_w(HDC hdc, UINT cbData, LPOUTLINETEXTMETRICW lpotmw)
+{
+  static GetOutlineTextMetricsW_Proc s_pfn_Get_Outline_Text_MetricsW = NULL;
+  HMODULE hm_unicows = NULL;
+  if (g_b_init_get_outline_metrics_w == 0)
+    {
+      g_b_init_get_outline_metrics_w = 1;
+      hm_unicows = w32_load_unicows_or_gdi32 ();
+      if (hm_unicows)
+       s_pfn_Get_Outline_Text_MetricsW = (GetOutlineTextMetricsW_Proc)
+         GetProcAddress (hm_unicows, "GetOutlineTextMetricsW");
+    }
+  if (s_pfn_Get_Outline_Text_MetricsW == NULL)
+    abort ();  /* cannot happen */
+  return s_pfn_Get_Outline_Text_MetricsW (hdc, cbData, lpotmw);
+}
+
+static BOOL WINAPI
+get_text_metrics_w(HDC hdc, LPTEXTMETRICW lptmw)
+{
+  static GetTextMetricsW_Proc s_pfn_Get_Text_MetricsW = NULL;
+  HMODULE hm_unicows = NULL;
+  if (g_b_init_get_text_metrics_w == 0)
+    {
+      g_b_init_get_text_metrics_w = 1;
+      hm_unicows = w32_load_unicows_or_gdi32 ();
+      if (hm_unicows)
+       s_pfn_Get_Text_MetricsW = (GetTextMetricsW_Proc)
+         GetProcAddress (hm_unicows, "GetTextMetricsW");
+    }
+  if (s_pfn_Get_Text_MetricsW == NULL)
+    abort ();  /* cannot happen */
+  return s_pfn_Get_Text_MetricsW (hdc, lptmw);
+}
+
+static DWORD WINAPI
+get_glyph_outline_w (HDC hdc, UINT uChar, UINT uFormat, LPGLYPHMETRICS lpgm,
+                    DWORD cbBuffer, LPVOID lpvBuffer, const MAT2 *lpmat2)
+{
+  static GetGlyphOutlineW_Proc s_pfn_Get_Glyph_OutlineW = NULL;
+  HMODULE hm_unicows = NULL;
+  if (g_b_init_get_glyph_outline_w == 0)
+    {
+      g_b_init_get_glyph_outline_w = 1;
+      hm_unicows = w32_load_unicows_or_gdi32 ();
+      if (hm_unicows)
+       s_pfn_Get_Glyph_OutlineW = (GetGlyphOutlineW_Proc)
+         GetProcAddress (hm_unicows, "GetGlyphOutlineW");
+    }
+  if (s_pfn_Get_Glyph_OutlineW == NULL)
+    abort ();  /* cannot happen */
+  return s_pfn_Get_Glyph_OutlineW (hdc, uChar, uFormat, lpgm, cbBuffer,
+                                  lpvBuffer, lpmat2);
+}
 
 static int
 memq_no_quit (Lisp_Object elt, Lisp_Object list)
@@ -816,11 +947,11 @@
   old_font = SelectObject (dc, hfont);
 
   /* Try getting the outline metrics (only works for truetype fonts).  */
-  len = GetOutlineTextMetricsW (dc, 0, NULL);
+  len = get_outline_metrics_w (dc, 0, NULL);
   if (len)
     {
       metrics = (OUTLINETEXTMETRICW *) alloca (len);
-      if (GetOutlineTextMetricsW (dc, len, metrics))
+      if (get_outline_metrics_w (dc, len, metrics))
         memcpy (&w32_font->metrics, &metrics->otmTextMetrics,
                sizeof (TEXTMETRICW));
       else
@@ -828,7 +959,7 @@
     }
 
   if (!metrics)
-    GetTextMetricsW (dc, &w32_font->metrics);
+    get_text_metrics_w (dc, &w32_font->metrics);
 
   w32_font->cached_metrics = NULL;
   w32_font->n_cache_blocks = 0;
@@ -2306,7 +2437,7 @@
   transform.eM11.value = 1;
   transform.eM22.value = 1;
 
-  if (GetGlyphOutlineW (dc, code, options, &gm, 0, NULL, &transform)
+  if (get_glyph_outline_w (dc, code, options, &gm, 0, NULL, &transform)
       != GDI_ERROR)
     {
       metrics->lbearing = gm.gmptGlyphOrigin.x;
@@ -2581,3 +2712,13 @@
   w32font_driver.type = Qgdi;
   register_font_driver (&w32font_driver, NULL);
 }
+
+void
+globals_of_w32font (void)
+{
+  g_b_init_is_w9x = 0;
+  g_b_init_get_outline_metrics_w = 0;
+  g_b_init_get_text_metrics_w = 0;
+  g_b_init_get_glyph_outline_w = 0;
+}
+


reply via email to

[Prev in Thread] Current Thread [Next in Thread]