Subject: bug#77171: 31.0.50; Some lines in etc/HELLO display with large height on MS-Windows

From: Cecilio Pardo <[email-masked]>
Date: Tue, 1 Apr 2025 10:47:11 +0200

On 22/03/2025 11:36, Eli Zaretskii wrote:

> Cecilio, could you please look into this?  I'm guessing that the code
> we now use to return the metrics of character glyphs somehow returns
> different results from what was used before, in this particular
> aspect. 

The attached patch fixes this by using the GDI measurement for the 
vertical size of text.

Doing the same with DirectWrite would be too expensive, and would imply 
using the "layout" parts of DirectWrite, to get the same results most of 
the time.

Horizontal extents is different, we need to keep using DirectWrite for that.

From 601655a4effc7b68448e80b7b798a738d66c7cb1 Mon Sep 17 00:00:00 2001
From: Cecilio Pardo <[email-masked]>
Date: Tue, 1 Apr 2025 10:18:14 +0200
Subject: [PATCH] w32: fix problem with font vertical measurement for dwrite

Glyph by glyph measurement of vertical size is too expensive with
DirectWrite.  GDI measurement for vertical size is good for DirectWrite
too.

* src/w32dwrite.c (w32_dwrite_text_extents): Use the vertical
measurement from GDI.
* src/w32font.c (w32font_text_extents): When DirectWrite is active,
measure test using GDI code before calling w32_dwrite_text_extents.
---
 src/w32dwrite.c | 4 +---
 src/w32font.c   | 6 ++----
 2 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/src/w32dwrite.c b/src/w32dwrite.c
index 10af8545a11..bc379cd7395 100644
--- a/src/w32dwrite.c
+++ b/src/w32dwrite.c
@@ -678,6 +678,7 @@ w32_dwrite_encode_char (struct font *font, int c)
   return FONT_INVALID_CODE;
 }
 
+/* Does not fill in the ascent and descent fields of metrics.  */
 bool
 w32_dwrite_text_extents (struct font *font, const unsigned *code, int nglyphs,
 			 struct font_metrics *metrics)
@@ -694,9 +695,6 @@ w32_dwrite_text_extents (struct font *font, const unsigned *code, int nglyphs,
   if (font_size <= 0.0f)
     font_size = FRAME_LINE_HEIGHT (SELECTED_FRAME ());
 
-  metrics->ascent = font->ascent;
-  metrics->descent = font->descent;
-
   return text_extents_internal (dwrite_font_face, font_size, code, nglyphs,
 				metrics);
 }
diff --git a/src/w32font.c b/src/w32font.c
index f44a7c124c9..7f54d6c68f1 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -444,10 +444,6 @@ w32font_text_extents (struct font *font, const unsigned *code,
 
   memset (metrics, 0, sizeof (struct font_metrics));
 
-  if (w32_use_direct_write (w32_font)
-      && w32_dwrite_text_extents (font, code, nglyphs, metrics))
-    return;
-
   for (i = 0, first = true; i < nglyphs; i++)
     {
       struct w32_metric_cache *char_metric;
@@ -530,6 +526,8 @@ w32font_text_extents (struct font *font, const unsigned *code,
   /* If we got through everything, return.  */
   if (i == nglyphs)
     {
+      if (w32_use_direct_write (w32_font))
+	w32_dwrite_text_extents (font, code, nglyphs, metrics);
       if (dc != NULL)
 	{
 	  /* Restore state and release DC.  */
-- 
2.35.1.windows.2