Fix bug #6364 with slow scrolling on MS-Windows with bitmap fonts.
authorTom Seddon <emacs@tomseddon.plus.com>
Fri, 29 Nov 2013 11:01:45 +0000 (13:01 +0200)
committerEli Zaretskii <eliz@gnu.org>
Fri, 29 Nov 2013 11:01:45 +0000 (13:01 +0200)
 src/w32font.c (g_b_init_get_char_width_32_w): New static var.
 (globals_of_w32font): Zero it out.
 (GetCharWidth32W_Proc): New function pointer.
 (get_char_width_32_w): New function.
 (compute_metrics): If get_glyph_outline_w returns an error, try
 get_char_width_32_w before declaring a failure.  This avoids
 punishing raster (a.k.a. "bitmap") fonts by slowing down
 redisplay.

src/ChangeLog
src/w32font.c

index c05845c..668bba1 100644 (file)
@@ -1,4 +1,13 @@
-2013-11-29  Eli Zaretskii  <eliz@gnu.org>
+2013-11-29  Tom Seddon  <emacs@tomseddon.plus.com>  (tiny change)
+
+       * w32font.c (g_b_init_get_char_width_32_w): New static var.
+       (globals_of_w32font): Zero it out.
+       (GetCharWidth32W_Proc): New function pointer.
+       (get_char_width_32_w): New function.
+       (compute_metrics): If get_glyph_outline_w returns an error, try
+       get_char_width_32_w before declaring a failure.  This avoids
+       punishing raster (a.k.a. "bitmap") fonts by slowing down
+       redisplay.  (Bug#6364).
 
        * xdisp.c (clear_mouse_face): Don't invalidate the entire
        mouse-highlight info, just signal frame_up_to_date_hook that mouse
index effedfc..923c71b 100644 (file)
@@ -149,6 +149,7 @@ 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;
+static BOOL g_b_init_get_char_width_32_w;
 
 typedef UINT (WINAPI * GetOutlineTextMetricsW_Proc) (
    HDC hdc,
@@ -165,6 +166,11 @@ typedef DWORD (WINAPI * GetGlyphOutlineW_Proc) (
    DWORD cbBuffer,
    LPVOID lpvBuffer,
    const MAT2 *lpmat2);
+typedef BOOL (WINAPI * GetCharWidth32W_Proc) (
+   HDC hdc,
+   UINT uFirstChar,
+   UINT uLastChar,
+   LPINT lpBuffer);
 
 /* Several "wide" functions we use to support the font backends are
    unavailable on Windows 9X, unless UNICOWS.DLL is installed (their
@@ -274,6 +280,23 @@ get_glyph_outline_w (HDC hdc, UINT uChar, UINT uFormat, LPGLYPHMETRICS lpgm,
                                   lpvBuffer, lpmat2);
 }
 
+static DWORD WINAPI get_char_width_32_w (HDC hdc, UINT uFirstChar,
+                                        UINT uLastChar, LPINT lpBuffer)
+{
+  static GetCharWidth32W_Proc s_pfn_Get_Char_Width_32W = NULL;
+  HMODULE hm_unicows = NULL;
+  if (g_b_init_get_char_width_32_w == 0)
+    {
+      g_b_init_get_char_width_32_w = 1;
+      hm_unicows = w32_load_unicows_or_gdi32 ();
+      if (hm_unicows)
+       s_pfn_Get_Char_Width_32W = (GetCharWidth32W_Proc)
+         GetProcAddress (hm_unicows, "GetCharWidth32W");
+    }
+  eassert (s_pfn_Get_Char_Width_32W != NULL);
+  return s_pfn_Get_Char_Width_32W (hdc, uFirstChar, uLastChar, lpBuffer);
+}
+
 static int
 memq_no_quit (Lisp_Object elt, Lisp_Object list)
 {
@@ -2437,6 +2460,7 @@ compute_metrics (HDC dc, struct w32font_info *w32_font, unsigned int code,
   GLYPHMETRICS gm;
   MAT2 transform;
   unsigned int options = GGO_METRICS;
+  INT width;
 
   if (w32_font->glyph_idx)
     options |= GGO_GLYPH_INDEX;
@@ -2453,6 +2477,13 @@ compute_metrics (HDC dc, struct w32font_info *w32_font, unsigned int code,
       metrics->width = gm.gmCellIncX;
       metrics->status = W32METRIC_SUCCESS;
     }
+  else if (get_char_width_32_w (dc, code, code, &width) != 0)
+    {
+      metrics->lbearing = 0;
+      metrics->rbearing = width;
+      metrics->width = width;
+      metrics->status = W32METRIC_SUCCESS;
+    }
   else
     metrics->status = W32METRIC_FAIL;
 }
@@ -2727,4 +2758,5 @@ globals_of_w32font (void)
   g_b_init_get_outline_metrics_w = 0;
   g_b_init_get_text_metrics_w = 0;
   g_b_init_get_glyph_outline_w = 0;
+  g_b_init_get_char_width_32_w = 0;
 }