patch 9.1.2129: MS-Windows: font size calculation slightly wrong, causing line 
gaps

Commit: 
https://github.com/vim/vim/commit/b46594eefb575dd473aa075efdb585412e742f66
Author: Yasuhiro Matsumoto <[email protected]>
Date:   Wed Feb 4 15:26:22 2026 +0000

    patch 9.1.2129: MS-Windows: font size calculation slightly wrong, causing 
line gaps
    
    Problem:  MS-Windows: font size calculation slightly wrong, causing
              vertical line gaps (Maxim Kim, after v9.1.2127)
    Solution: Update font size calculation when using DirectX
              (Yasuhiro Matsumoto).
    
    Use pre-calculated font ascent from font metrics instead of fixed
    formula (h * 0.83) to calculate text baseline. This prevents vertical
    text shift when font fallback occurs with CJK characters.
    
    closes: #19318
    
    Signed-off-by: Yasuhiro Matsumoto <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt
index 52d086a87..e0ac515ab 100644
--- a/runtime/doc/version9.txt
+++ b/runtime/doc/version9.txt
@@ -52461,4 +52461,10 @@ Problem:  heap UAF if autocommands from reloading a 
file changed outside
           of Vim wipe its buffer.
 Solution: Validate the bufref after buf_reload (Sean Dewar).
 
+Patch 9.1.2129
+Problem:  MS-Windows: font size calculation slightly wrong, causing
+         vertical line gaps (Maxim Kim, after v9.1.2127)
+Solution: Update font size calculation when using DirectX
+         (Yasuhiro Matsumoto).
+
  vim:tw=78:ts=8:noet:ft=help:norl:fdm=manual:nofoldenable
diff --git a/src/gui_dwrite.cpp b/src/gui_dwrite.cpp
index 5d4cb6c3a..39a39938b 100644
--- a/src/gui_dwrite.cpp
+++ b/src/gui_dwrite.cpp
@@ -206,7 +206,8 @@ public:
        IDWriteTextFormat* pTextFormat;
        DWRITE_FONT_WEIGHT fontWeight;
        DWRITE_FONT_STYLE  fontStyle;
-       Item() : hFont(NULL), pTextFormat(NULL) {}
+       FLOAT              fontAscent;
+       Item() : hFont(NULL), pTextFormat(NULL), fontAscent(0.0f) {}
     };
 
 private:
@@ -323,7 +324,7 @@ struct DWriteContext {
     void DiscardDeviceResources();
 
     HRESULT CreateTextFormatFromLOGFONT(const LOGFONTW &logFont,
-           IDWriteTextFormat **ppTextFormat);
+           IDWriteTextFormat **ppTextFormat, FLOAT *pFontAscent);
 
     HRESULT SetFontByLOGFONT(const LOGFONTW &logFont);
 
@@ -759,7 +760,7 @@ DWriteContext::DiscardDeviceResources()
 
     HRESULT
 DWriteContext::CreateTextFormatFromLOGFONT(const LOGFONTW &logFont,
-       IDWriteTextFormat **ppTextFormat)
+       IDWriteTextFormat **ppTextFormat, FLOAT *pFontAscent)
 {
     // Most of this function is copied from: 
https://github.com/Microsoft/Windows-classic-samples/blob/master/Samples/Win7Samples/multimedia/DirectWrite/RenderTest/TextHelpers.cpp
     HRESULT hr = S_OK;
@@ -769,6 +770,7 @@ DWriteContext::CreateTextFormatFromLOGFONT(const LOGFONTW 
&logFont,
     IDWriteFontFamily *fontFamily = NULL;
     IDWriteLocalizedStrings *localizedFamilyNames = NULL;
     float fontSize = 0;
+    DWRITE_FONT_METRICS fontMetrics = {};
 
     if (SUCCEEDED(hr))
     {
@@ -804,7 +806,6 @@ DWriteContext::CreateTextFormatFromLOGFONT(const LOGFONTW 
&logFont,
        // Use lfHeight of the LOGFONT as font size.
        fontSize = float(logFont.lfHeight);
 
-       DWRITE_FONT_METRICS fontMetrics;
        font->GetMetrics(&fontMetrics);
 
        // Convert lfHeight to DirectWrite font size
@@ -818,7 +819,7 @@ DWriteContext::CreateTextFormatFromLOGFONT(const LOGFONTW 
&logFont,
            // Positive lfHeight represents the font's cell height (ascent + 
descent)
            // Convert to em height
            fontSize = fontSize * float(fontMetrics.designUnitsPerEm)
-               / float(fontMetrics.ascent + fontMetrics.descent);
+               / float(fontMetrics.ascent + fontMetrics.descent + 
fontMetrics.lineGap);
        }
     }
 
@@ -861,7 +862,12 @@ DWriteContext::CreateTextFormatFromLOGFONT(const LOGFONTW 
&logFont,
     SafeRelease(&font);
 
     if (SUCCEEDED(hr))
+    {
        *ppTextFormat = pTextFormat;
+       if (pFontAscent != NULL && fontMetrics.designUnitsPerEm != 0)
+           *pFontAscent = fontSize * float(fontMetrics.ascent)
+               / float(fontMetrics.designUnitsPerEm);
+    }
     else
        SafeRelease(&pTextFormat);
 
@@ -873,8 +879,9 @@ DWriteContext::SetFontByLOGFONT(const LOGFONTW &logFont)
 {
     HRESULT hr = S_OK;
     IDWriteTextFormat *pTextFormat = NULL;
+    FLOAT fontAscent = 0.0f;
 
-    hr = CreateTextFormatFromLOGFONT(logFont, &pTextFormat);
+    hr = CreateTextFormatFromLOGFONT(logFont, &pTextFormat, &fontAscent);
 
     if (SUCCEEDED(hr))
     {
@@ -883,6 +890,7 @@ DWriteContext::SetFontByLOGFONT(const LOGFONTW &logFont)
        mFontWeight = static_cast<DWRITE_FONT_WEIGHT>(logFont.lfWeight);
        mFontStyle = logFont.lfItalic ? DWRITE_FONT_STYLE_ITALIC
            : DWRITE_FONT_STYLE_NORMAL;
+       mFontAscent = fontAscent;
     }
 
     return hr;
@@ -901,6 +909,7 @@ DWriteContext::SetFont(HFONT hFont)
            mTextFormat = item.pTextFormat;
            mFontWeight = item.fontWeight;
            mFontStyle = item.fontStyle;
+           mFontAscent = item.fontAscent;
            mFallbackDC = false;
        }
        else
@@ -919,6 +928,7 @@ DWriteContext::SetFont(HFONT hFont)
        item.pTextFormat = mTextFormat;
        item.fontWeight = mFontWeight;
        item.fontStyle = mFontStyle;
+       item.fontAscent = mFontAscent;
        mFallbackDC = false;
     }
     else
@@ -1070,13 +1080,13 @@ DWriteContext::DrawText(const WCHAR *text, int len,
        textLayout->SetFontWeight(mFontWeight, textRange);
        textLayout->SetFontStyle(mFontStyle, textRange);
 
-       // Calculate baseline using a fixed formula based on cell geometry.
+       // Calculate baseline using font ascent from font metrics.
        // Do NOT use GetLineMetrics() because it returns different values
        // depending on text content (e.g., when CJK characters trigger
        // font fallback, the metrics change).
-       // Use the same baseline calculation for all text to prevent
+       // Use the pre-calculated font ascent for all text to prevent
        // vertical shifts during redraw.
-       FLOAT baselineY = floorf(FLOAT(y) + FLOAT(h) * 0.83f + 0.5f);
+       FLOAT baselineY = FLOAT(y) + mFontAscent;
 
        TextRenderer renderer(this);
        TextRendererContext context = { color, FLOAT(cellWidth), lpDx, len,
diff --git a/src/version.c b/src/version.c
index c4b596038..1315fb2cb 100644
--- a/src/version.c
+++ b/src/version.c
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2129,
 /**/
     2128,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1vnf3v-00Co7g-HJ%40256bit.org.

Raspunde prin e-mail lui