unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Tom Seddon <emacs@tomseddon.plus.com>
To: 6364@debbugs.gnu.org
Subject: bug#6364: [PATCH] Use GetCharABCWidthsFloatW if GetGlyphOutlineW fails.
Date: Tue, 26 Nov 2013 00:35:05 +0000	[thread overview]
Message-ID: <713BA87B-E38A-4777-B054-E136A7C96EF9@tomseddon.plus.com> (raw)
In-Reply-To: <8CCD3BEBEE756DD-DB8-DFB9@web-mmc-m08.sysops.aol.com>

Please find below a patch to improve the poor scrolling performance when using bitmap fonts. #14721 (http://debbugs.gnu.org/cgi/bugreport.cgi?bug=14721) and and 14307 (http://debbugs.gnu.org/cgi/bugreport.cgi?bug=14307) may also be affected. The patch has been tested against emacs 24.3. It applied cleanly to git head (22687e54e0e4d7c73c098417478574a55393fe2c) but I haven't built it.

Performance with particularly long lines is still rather poor, but general responsiveness is much improved. (Once the buffer is fontified, emacs can now usually keep up if I hold down PgUp, PgDn, C-s, etc.)

(I settled on GetCharABCWidthsFloatW because it works for bitmap fonts and TrueType fonts alike. But the key thing is simply not to create a DC each time w32font_text_extents is called, so there are various other functions that could be called instead if preferred.)

--Tom

From ccedd16f6bd2027145b9e172346d2c3b31c811df Mon Sep 17 00:00:00 2001
From: Tom Seddon <tom@tmbp-w7>
Date: Mon, 25 Nov 2013 22:19:47 +0000
Subject: [PATCH] Use GetCharABCWidthsFloatW if GetGlyphOutlineW fails.

The previous fallback - which will still be used if
GetCharABCWidthsFloatW fails - was to call GetTextExtentPoint32W. This
can be rather slow due to having to create a DC for it each time.
---
 src/w32font.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/src/w32font.c b/src/w32font.c
index 5c5a15c..3577dfa 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -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_abc_widths_float_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 * GetCharABCWidthsFloatW_Proc) (
+   HDC hdc,
+   UINT uFirstChar,
+   UINT uLastChar,
+   LPABCFLOAT lpabc);
 
 /* 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_abc_widths_float_w (HDC hdc, UINT uFirstChar,
+						 UINT uLastChar, LPABCFLOAT lpabc)
+{
+  static GetCharABCWidthsFloatW_Proc s_pfn_Get_Char_ABC_Widths_FloatW = NULL;
+  HMODULE hm_unicows = NULL;
+  if (g_b_init_get_char_abc_widths_float_w == 0)
+    {
+      g_b_init_get_char_abc_widths_float_w = 1;
+      hm_unicows = w32_load_unicows_or_gdi32 ();
+      if (hm_unicows)
+	s_pfn_Get_Char_ABC_Widths_FloatW = (GetCharABCWidthsFloatW_Proc)
+	  GetProcAddress (hm_unicows, "GetCharABCWidthsFloatW");
+    }
+  eassert (s_pfn_Get_Char_ABC_Widths_FloatW != NULL);
+  return s_pfn_Get_Char_ABC_Widths_FloatW (hdc, uFirstChar, uLastChar, lpabc);
+}
+
 static int
 memq_no_quit (Lisp_Object elt, Lisp_Object list)
 {
@@ -2438,6 +2461,7 @@ compute_metrics (HDC dc, struct w32font_info *w32_font, unsigned int code,
   GLYPHMETRICS gm;
   MAT2 transform;
   unsigned int options = GGO_METRICS;
+  ABCFLOAT abc;
 
   if (w32_font->glyph_idx)
     options |= GGO_GLYPH_INDEX;
@@ -2454,6 +2478,14 @@ compute_metrics (HDC dc, struct w32font_info *w32_font, unsigned int code,
       metrics->width = gm.gmCellIncX;
       metrics->status = W32METRIC_SUCCESS;
     }
+  else if (get_char_abc_widths_float_w (dc, code, code, &abc) != 0)
+    {
+      int width = (int) (abc.abcfA + abc.abcfB + abc.abcfC);
+      metrics->lbearing = 0;
+      metrics->rbearing = width;
+      metrics->width = width;
+      metrics->status = W32METRIC_SUCCESS;
+    }
   else
     metrics->status = W32METRIC_FAIL;
 }
-- 
1.8.1.msysgit.1






  reply	other threads:[~2013-11-26  0:35 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-06-06 18:39 bug#6364: Windows: Emacs 23 slow with long lines and raster fonts bogossian
2013-11-26  0:35 ` Tom Seddon [this message]
2013-11-26 17:52   ` bug#6364: [PATCH] Use GetCharABCWidthsFloatW if GetGlyphOutlineW fails Eli Zaretskii
2013-11-26 19:39     ` Tom Seddon
2013-11-26 20:20       ` Eli Zaretskii
2013-11-26 20:30         ` Tom Seddon
2013-11-26 20:48           ` Eli Zaretskii
2013-11-26 21:50             ` Tom Seddon
2013-11-26 21:53               ` Tom Seddon
2013-11-29 11:05               ` Eli Zaretskii

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=713BA87B-E38A-4777-B054-E136A7C96EF9@tomseddon.plus.com \
    --to=emacs@tomseddon.plus.com \
    --cc=6364@debbugs.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).