Skip to content

Commit b825bfd

Browse files
Diekenrailwaycat
authored andcommitted
prefer sTypoAscender, sTypoDescender and sTypoLineGap from OS/2 table
Doom Emacs sets size of all fonts in a fontset to same pixel size, Emacs vterm mixes western font and CJK font in same window, so the line heights of western font and CJK font must be same, or vterm may render top lines out of screen due to wrongly estimated total rows. If `:minspace t` is set on font: font height = pixel size * (Ascent + Descent) / Em Size If `:minspace t` is not set on font: font height = pixel size * (Ascent + Descent + Line Gap) / Em Size Line height = max(ascent) + max(descent), this means ascent and descent of other fonts can't be larger than the default font, you may need to adjust `face-font-rescale-alist` to scale down other fonts. As numbers below show, Emacs should prefer Typo Ascender/Descender/LineGap from OS/2 table to get close font height for western font and CJK font. ~~~~~~ Western font ~~~~~~ Menlo Regular, Hack Regular: Em Size: 2048 Win Ascent: 1901 Win Descent: 483 HHead Ascent: 1901 HHead Descent: -483 HHead Line Gap: 0 Typo Ascent: 1556 Typo Descent: -492 Typo Line Gap: 410 (HHead Ascent - HHead Descent) / Em Size = 1.164 (Typo Ascent - Typo Descent) / Em Size = 1.0 (Typo Ascent - Typo Descent + Typo Line Gap) / Em Size = 1.2 Monaco: Em Size: 2048 Win Ascent: 2504 Win Descent: 862 HHead Ascent: 2048 HHead Descent: -512 HHead Line Gap: 171 Typo Ascent: 2048 Typo Descent: -512 Typo Line Gap: 171 HHead metrics same with Typo metrics. ~~~~~~ CJK font ~~~~~~ Alibaba PuHuiTi 3.0 55 Regular: Em Size: 1000 Win Ascent: 1060 Win Descent: 340 HHead Ascent: 1060 HHead Ascent: -340 HHead Line Gap: 0 Typo Ascent: 850 Typo Ascent: -150 Typo Line Gap: 200 (HHead Ascent - HHead Descent) / Em Size = 1.4 (Typo Ascent - Typo Descent) / Em Size = 1.0 (Typo Ascent - Typo Descent + Typo Line Gap) / Em Size = 1.2 MiSans Regular: Em Size: 1000 Win Ascent: 1044 Win Descent: 282 HHead Ascent: 1044 HHead Descent: -282 HHead Line Gap: 0 Typo Ascent: 890 Typo Descent: -110 Typo Line Gap: 326 (HHead Ascent - HHead Descent) / Em Size = 1.326 (Typo Ascent - Typo Descent) / Em Size = 1.0 (Typo Ascent - Typo Descent + Typo Line Gap) / Em Size = 1.326 Reference: https://learn.microsoft.com/en-us/typography/opentype/spec/os2 Signed-off-by: Yubao Liu <yubao.liu@gmail.com>
1 parent 7abbd0c commit b825bfd

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

Formula/emacs-mac.rb

+5
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ class EmacsMac < Formula
3333
end
3434
end
3535

36+
patch do
37+
url "#{HOMEBREW_LIBRARY}/Taps/railwaycat/homebrew-emacsmacport/patches/prefer-typo-ascender-descender-linegap.diff", using: CopyDownloadStrategy
38+
sha256 "318395d3869d3479da4593360bcb11a5df08b494b995287074d0d744ec562c17"
39+
end
40+
3641
option "without-modules", "Build without dynamic modules support"
3742
option "with-ctags", "Don't remove the ctags executable that emacs provides"
3843
option "with-no-title-bars",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
diff --git a/src/macfont.m b/src/macfont.m
2+
index 91ff2f0..fc522f7 100644
3+
--- a/src/macfont.m
4+
+++ b/src/macfont.m
5+
@@ -2563,6 +2563,12 @@ So we use CTFontDescriptorCreateMatchingFontDescriptor (no
6+
unblock_input ();
7+
}
8+
9+
+static short
10+
+read_short_from_os2_table(const UInt8* p)
11+
+{
12+
+ return (p[0] << 8) | p[1];
13+
+}
14+
+
15+
static Lisp_Object
16+
macfont_open (struct frame * f, Lisp_Object entity, int pixel_size)
17+
{
18+
@@ -2711,6 +2717,36 @@ So we use CTFontDescriptorCreateMatchingFontDescriptor (no
19+
}
20+
CFRelease (family_name);
21+
}
22+
+
23+
+ // https://github.com/WebKit/WebKit/blob/4e349ca/Source/WebCore/platform/graphics/coretext/FontCoreText.cpp#L166
24+
+ CFDataRef os2Table = CTFontCopyTable (macfont, kCTFontTableOS2, kCTFontTableOptionNoOptions);
25+
+ if (os2Table)
26+
+ {
27+
+ // For the structure of the OS/2 table, see
28+
+ // https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6OS2.html
29+
+ const CFIndex fsSelectionOffset = 16 * 2 + 10 + 4 * 4 + 4 * 1;
30+
+ const CFIndex sTypoAscenderOffset = fsSelectionOffset + 3 * 2;
31+
+ const CFIndex sTypoDescenderOffset = sTypoAscenderOffset + 2;
32+
+ const CFIndex sTypoLineGapOffset = sTypoDescenderOffset + 2;
33+
+ if (CFDataGetLength (os2Table) >= sTypoLineGapOffset + 2)
34+
+ {
35+
+ const UInt8* os2Data = CFDataGetBytePtr (os2Table);
36+
+ // We test the use typo bit on the least significant byte of fsSelection.
37+
+ //const UInt8 useTypoMetricsMask = 1 << 7;
38+
+ //if (*(os2Data + fsSelectionOffset + 1) & useTypoMetricsMask)
39+
+ // -- XXX: often fonts don't set USE_TYPO_METRICS bit, so just ignore it
40+
+ {
41+
+ CGFloat unitsPerEm = (CGFloat) CTFontGetUnitsPerEm (macfont);
42+
+ short sTypoAscender = read_short_from_os2_table (os2Data + sTypoAscenderOffset);
43+
+ short sTypoDescender = read_short_from_os2_table (os2Data + sTypoDescenderOffset);
44+
+ short sTypoLineGap = read_short_from_os2_table (os2Data + sTypoLineGapOffset);
45+
+ ascent = font->pixel_size * sTypoAscender / unitsPerEm;
46+
+ descent = - font->pixel_size * sTypoDescender / unitsPerEm;
47+
+ leading = font->pixel_size * sTypoLineGap / unitsPerEm;
48+
+ }
49+
+ }
50+
+ CFRelease(os2Table);
51+
+ }
52+
}
53+
font->ascent = ascent + 0.5f;
54+
val = assq_no_quit (QCminspace, AREF (entity, FONT_EXTRA_INDEX));

0 commit comments

Comments
 (0)