Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CJK vertical metrics suggestion #45

Open
NightFurySL2001 opened this issue Jul 28, 2022 · 16 comments · May be fixed by #135
Open

CJK vertical metrics suggestion #45

NightFurySL2001 opened this issue Jul 28, 2022 · 16 comments · May be fixed by #135
Labels
documentation Improvements or additions to documentation

Comments

@NightFurySL2001
Copy link

According to https://googlefonts.github.io/gf-guide/metrics.html#cjk-vertical-metrics, it is suggested that the OS/2.sTypoAscender is set to 0.88 * font UPM and the OS/2.sTypoDescender is set to -0.12 * font UPM. The table is attached below:

Attrib Value Example using 1000upm font
OS/2.sTypoAscender 0.88 * font upm 880
OS/2.sTypoDescender -0.12 * font upm -120
OS/2.sTypoLineGap 0 0
hhea.ascender Set to look comfortable (~1.16 * upm) 1160
hhea.descender Set to look comfortable (~0.288 * upm) -288
hhea.lineGap 0 0
OS/2.usWinAscent Same as hhea.ascent 1160
OS/2.usWinDescent abs(value) of hhea.descent 288
OS/2.fsSelection bit 7 (Use_Typo_Metrics) Do not set / disabled 0

Our decision to follow the Adobe schema was based on Dr. Ken Lunde’s comments and his release notes on Source Han Sans:

However, these metrics are only used in Japanese fonts. In Korean font (such as IBM Plex KR developed by Sandoll Inc), the ratio used is 0.8:0.2, which some Chinese font foundries use too. Another typical Chinese font foundry used is 0.85:0.15, as this allows more descender space compared to 0.88:0.12. There are some other combination of values which is used for individual creators too.

The referenced issue provided to justify these values (source-foundry/font-line#2) only explicitly mention this (quoted from @kenlunde):

To add to the discussion with regard to the sTypoAscender and sTypoDescender values in the 'OS/2' table, while I cannot speak with any authority to non-CJK fonts, at least for CJK fonts I feel somewhat strongly that these values 1) add up to equal the UPM and 2) correspond to the top and bottom of the ideographic em-box in which CJK glyphs are optically centered. For the other vertical metrics values, I see little or no disagreement.

Thus, I would like to suggest the guide to change the guidelines to allow any ratio for the OS/2 sTypo values as long as:

  • OS/2.sTypoAscender - OS/2.sTypoDescender = UPM (In the sample it is 880 - (-120) = 1000)
  • OS/2.sTypoAscender and OS/2.sTypoDescender reflects the CJK ideographic bounding box only, not any other values.
@RosaWagner
Copy link
Contributor

That is good info, thanks.

@davelab6 @chrissimpkins should we update the vertical metric policy for CJK fonts accordingly?

cc @vv-monsalve @m4rc1e @aaronbell

@NightFurySL2001
Copy link
Author

This would also fix the issue of IBM Plex KR is different from its source file as the original KR font uses 780/-220. (Issue reference)

@yisibl
Copy link

yisibl commented Dec 27, 2022

Why is it recommended to disable Use_Typo_Metrics here?

@NightFurySL2001
Copy link
Author

OS/2.sTypoAscender and OS/2.sTypoDescender are used for CJK bounding box. Setting Use_Typo_Metrics will make the font look shorter (usually).
Source quote:

Else If this is a CJK font:

ideoEmboxBottom = OS/2.sTypoDescender
ideoEmboxTop = OS/2.sTypoAscender
ideoEmboxRight = head.unitsPerEm

nooriro added a commit to nooriro/nooriro.github.io that referenced this issue Apr 4, 2023
Inconsistent line height on Chrome/Firefox for Android
is due to wrong vertical metrics
of the Charter font files from the link below:
https://practicaltypography.com/charter.html

The font files have positive descender values but those values
should be NEGATIVE. (See References [1], [2] and others.)
- `descender`      field in `hhea` table
- `sTypoDescender` field in `OS/2` table

Table   Field Name      Field Value         Should Be
-----   -------------   -----------------   ---------
head    unitsPerEm      1000
hhea    ascender        980
        descender       236                 -236
        lineGap         0
OS/2    sTypoAscender   760
        sTypoDescender  240                 -240
        sTypoLineGap    216
        usWinAscent     980
        usWinDescent    236
        fsSelection     00000000 01000000

So I've made a program which fixes those values (and checksums)
in Charter otf/ttf file to resolve the line height issue.

References:
[1] https://glyphsapp.com/learn/vertical-metrics
    via https://stackoverflow.com/questions/2854028/mac-vs-windows-browser-font-height-rendering-issue
[2] https://googlefonts.github.io/gf-guide/metrics.html
    via googlefonts/googlefonts.github.io#45
    and source-foundry/font-line#2
[3] 1. https://learn.microsoft.com/en-us/typography/opentype/spec/otff
    2. https://learn.microsoft.com/en-us/typography/opentype/spec/head
    3. https://learn.microsoft.com/en-us/typography/opentype/spec/hhea
    4. https://learn.microsoft.com/en-us/typography/opentype/spec/os2

Terminal output of program:

nooriro@xps:/mnt/c/Users/nooriro/CLionProjects/untitled6/cmake-build-release-wsl$ ./untitled6 Charter-Regular.otf
sfntVersion: 4F54544F  numTables: 000B
 - tableTag: 43464620 (CFF )  checksum: EA4DC1AF  offset: 00000BB8  length: 000082A3
 - tableTag: 44534947 (DSIG)  checksum: 00000001  offset: 00009734  length: 00000008
 - tableTag: 47504F53 (GPOS)  checksum: E82FF7B3  offset: 000091F0  length: 00000542
 - tableTag: 4F532F32 (OS/2)  checksum: 8B297EE1  offset: 00000120  length: 00000060
 - tableTag: 636D6170 (cmap)  checksum: 52F054E4  offset: 0000088C  length: 0000030C
 - tableTag: 68656164 (head)  checksum: 1B64CC47  offset: 000000BC  length: 00000036
 - tableTag: 68686561 (hhea)  checksum: 07DC05FC  offset: 000000F4  length: 00000024
 - tableTag: 686D7478 (hmtx)  checksum: ED592734  offset: 00008E5C  length: 00000394
 - tableTag: 6D617870 (maxp)  checksum: 00E55000  offset: 00000118  length: 00000006
 - tableTag: 6E616D65 (name)  checksum: 619A5B30  offset: 00000180  length: 0000070B
 - tableTag: 706F7374 (post)  checksum: FF6E003A  offset: 00000B98  length: 00000020
offset 000000FA: 'descender'      field in 'hhea' table: 00EC (236) --> FF14 (-236) (modified)
offset 00000166: 'sTypoDescender' field in 'OS/2' table: 00F0 (240) --> FF10 (-240) (modified)
offset 00000070: checksum for 'hhea' table: 07DC05FC --> 07DD0424 (modified)
offset 00000040: checksum for 'OS/2' table: 8B297EE1 --> 8B2A7D01 (modified)
offset 00000060: checksum for 'head' table: 1B64CC47 --> 1B64CC47 (not modified)
offset 000000C4: 'checksumAdjustment' field in 'head' table: 14F57F8B --> 14F186FB (modified)

nooriro@xps:/mnt/c/Users/nooriro/CLionProjects/untitled6/cmake-build-release-wsl$ ./untitled6 Charter-Italic.otf
sfntVersion: 4F54544F  numTables: 000B
 - tableTag: 43464620 (CFF )  checksum: 5340C605  offset: 00000BD8  length: 000084CE
 - tableTag: 44534947 (DSIG)  checksum: 00000001  offset: 000099B4  length: 00000008
 - tableTag: 47504F53 (GPOS)  checksum: F28802D2  offset: 0000943C  length: 00000578
 - tableTag: 4F532F32 (OS/2)  checksum: 8C2D7E6C  offset: 00000120  length: 00000060
 - tableTag: 636D6170 (cmap)  checksum: 52F054E4  offset: 000008AC  length: 0000030C
 - tableTag: 68656164 (head)  checksum: 1B13CC53  offset: 000000BC  length: 00000036
 - tableTag: 68686561 (hhea)  checksum: 06C709A1  offset: 000000F4  length: 00000024
 - tableTag: 686D7478 (hmtx)  checksum: E26B1300  offset: 000090A8  length: 00000394
 - tableTag: 6D617870 (maxp)  checksum: 00E55000  offset: 00000118  length: 00000006
 - tableTag: 6E616D65 (name)  checksum: 8CCC2E70  offset: 00000180  length: 0000072C
 - tableTag: 706F7374 (post)  checksum: FF79003A  offset: 00000BB8  length: 00000020
offset 000000FA: 'descender'      field in 'hhea' table: 00EC (236) --> FF14 (-236) (modified)
offset 00000166: 'sTypoDescender' field in 'OS/2' table: 00F0 (240) --> FF10 (-240) (modified)
offset 00000070: checksum for 'hhea' table: 06C709A1 --> 06C807C9 (modified)
offset 00000040: checksum for 'OS/2' table: 8C2D7E6C --> 8C2E7C8C (modified)
offset 00000060: checksum for 'head' table: 1B13CC53 --> 1B13CC53 (not modified)
offset 000000C4: 'checksumAdjustment' field in 'head' table: EE85D217 --> EE81D987 (modified)

nooriro@xps:/mnt/c/Users/nooriro/CLionProjects/untitled6/cmake-build-release-wsl$ ./untitled6 Charter-Bold.otf
sfntVersion: 4F54544F  numTables: 000B
 - tableTag: 43464620 (CFF )  checksum: D5E91E98  offset: 00000BC0  length: 00008365
 - tableTag: 44534947 (DSIG)  checksum: 00000001  offset: 00009984  length: 00000008
 - tableTag: 47504F53 (GPOS)  checksum: 1CF31346  offset: 000092BC  length: 000006C8
 - tableTag: 4F532F32 (OS/2)  checksum: 8D5981F5  offset: 00000120  length: 00000060
 - tableTag: 636D6170 (cmap)  checksum: 52F054E4  offset: 00000894  length: 0000030C
 - tableTag: 68656164 (head)  checksum: 1BA6CC3D  offset: 000000BC  length: 00000036
 - tableTag: 68686561 (hhea)  checksum: 081D0634  offset: 000000F4  length: 00000024
 - tableTag: 686D7478 (hmtx)  checksum: FF6324F0  offset: 00008F28  length: 00000394
 - tableTag: 6D617870 (maxp)  checksum: 00E55000  offset: 00000118  length: 00000006
 - tableTag: 6E616D65 (name)  checksum: 3D47C34B  offset: 00000180  length: 00000714
 - tableTag: 706F7374 (post)  checksum: FF950054  offset: 00000BA0  length: 00000020
offset 000000FA: 'descender'      field in 'hhea' table: 00EC (236) --> FF14 (-236) (modified)
offset 00000166: 'sTypoDescender' field in 'OS/2' table: 00F0 (240) --> FF10 (-240) (modified)
offset 00000070: checksum for 'hhea' table: 081D0634 --> 081E045C (modified)
offset 00000040: checksum for 'OS/2' table: 8D5981F5 --> 8D5A8015 (modified)
offset 00000060: checksum for 'head' table: 1BA6CC3D --> 1BA6CC3D (not modified)
offset 000000C4: 'checksumAdjustment' field in 'head' table: F315B5DC --> F311BD4C (modified)

nooriro@xps:/mnt/c/Users/nooriro/CLionProjects/untitled6/cmake-build-release-wsl$ ./untitled6 Charter-Bold-Italic.otf
sfntVersion: 4F54544F  numTables: 000B
 - tableTag: 43464620 (CFF )  checksum: FAC135F0  offset: 00000C10  length: 000085AA
 - tableTag: 44534947 (DSIG)  checksum: 00000001  offset: 00009C5C  length: 00000008
 - tableTag: 47504F53 (GPOS)  checksum: 145323A8  offset: 00009550  length: 0000070C
 - tableTag: 4F532F32 (OS/2)  checksum: 8D5E81C9  offset: 00000120  length: 00000060
 - tableTag: 636D6170 (cmap)  checksum: 52F054E4  offset: 000008E4  length: 0000030C
 - tableTag: 68656164 (head)  checksum: 1B7DCC40  offset: 000000BC  length: 00000036
 - tableTag: 68686561 (hhea)  checksum: 07300A0A  offset: 000000F4  length: 00000024
 - tableTag: 686D7478 (hmtx)  checksum: FA0F1322  offset: 000091BC  length: 00000394
 - tableTag: 6D617870 (maxp)  checksum: 00E55000  offset: 00000118  length: 00000006
 - tableTag: 6E616D65 (name)  checksum: 41042CB9  offset: 00000180  length: 00000762
 - tableTag: 706F7374 (post)  checksum: FFA00054  offset: 00000BF0  length: 00000020
offset 000000FA: 'descender'      field in 'hhea' table: 00EC (236) --> FF14 (-236) (modified)
offset 00000166: 'sTypoDescender' field in 'OS/2' table: 00F0 (240) --> FF10 (-240) (modified)
offset 00000070: checksum for 'hhea' table: 07300A0A --> 07310832 (modified)
offset 00000040: checksum for 'OS/2' table: 8D5E81C9 --> 8D5F7FE9 (modified)
offset 00000060: checksum for 'head' table: 1B7DCC40 --> 1B7DCC40 (not modified)
offset 000000C4: 'checksumAdjustment' field in 'head' table: BFE0A407 --> BFDCAB77 (modified)

nooriro@xps:/mnt/c/Users/nooriro/CLionProjects/untitled6/cmake-build-release-wsl$ ./untitled6 Charter-Regular.ttf
sfntVersion: 00010000  numTables: 0010
 - tableTag: 44534947 (DSIG)  checksum: 00000001  offset: 000088EC  length: 00000008
 - tableTag: 47504F53 (GPOS)  checksum: E82FF7B3  offset: 0000010C  length: 00000542
 - tableTag: 4F532F32 (OS/2)  checksum: 8B297EE1  offset: 00000650  length: 00000060
 - tableTag: 636D6170 (cmap)  checksum: 52F054E4  offset: 000006B0  length: 0000030C
 - tableTag: 63767420 (cvt )  checksum: 04D710EF  offset: 000079E0  length: 0000004A
 - tableTag: 6670676D (fpgm)  checksum: 622EFD7C  offset: 00007A2C  length: 00000E0C
 - tableTag: 67617370 (gasp)  checksum: 00000010  offset: 000079D8  length: 00000008
 - tableTag: 676C7966 (glyf)  checksum: 6CB82482  offset: 000009BC  length: 000060F0
 - tableTag: 68656164 (head)  checksum: 1B68CC48  offset: 00006AAC  length: 00000036
 - tableTag: 68686561 (hhea)  checksum: 07DC05FC  offset: 00006AE4  length: 00000024
 - tableTag: 686D7478 (hmtx)  checksum: ED592734  offset: 00006B08  length: 00000394
 - tableTag: 6C6F6361 (loca)  checksum: FFCC1806  offset: 00006E9C  length: 000001CC
 - tableTag: 6D617870 (maxp)  checksum: 019E0E83  offset: 00007068  length: 00000020
 - tableTag: 6E616D65 (name)  checksum: E53144D9  offset: 00007088  length: 00000762
 - tableTag: 706F7374 (post)  checksum: 373135EF  offset: 000077EC  length: 000001EC
 - tableTag: 70726570 (prep)  checksum: D4BDD644  offset: 00008838  length: 000000B2
offset 00006AEA: 'descender'      field in 'hhea' table: 00EC (236) --> FF14 (-236) (modified)
offset 00000696: 'sTypoDescender' field in 'OS/2' table: 00F0 (240) --> FF10 (-240) (modified)
offset 000000A0: checksum for 'hhea' table: 07DC05FC --> 07DD0424 (modified)
offset 00000030: checksum for 'OS/2' table: 8B297EE1 --> 8B2A7D01 (modified)
offset 00000090: checksum for 'head' table: 1B68CC48 --> 1B68CC48 (not modified)
offset 00006AB4: 'checksumAdjustment' field in 'head' table: 3DCC5A00 --> 3DC86170 (modified)

nooriro@xps:/mnt/c/Users/nooriro/CLionProjects/untitled6/cmake-build-release-wsl$ ./untitled6 Charter-Italic.ttf
sfntVersion: 00010000  numTables: 0010
 - tableTag: 44534947 (DSIG)  checksum: 00000001  offset: 00009084  length: 00000008
 - tableTag: 47504F53 (GPOS)  checksum: F28802D2  offset: 0000010C  length: 00000578
 - tableTag: 4F532F32 (OS/2)  checksum: 8C2D7E6C  offset: 00000684  length: 00000060
 - tableTag: 636D6170 (cmap)  checksum: 52F054E4  offset: 000006E4  length: 0000030C
 - tableTag: 63767420 (cvt )  checksum: 04CF10D9  offset: 00008178  length: 0000004A
 - tableTag: 6670676D (fpgm)  checksum: 622EFD7C  offset: 000081C4  length: 00000E0C
 - tableTag: 67617370 (gasp)  checksum: 00000010  offset: 00008170  length: 00000008
 - tableTag: 676C7966 (glyf)  checksum: ADA4911C  offset: 000009F0  length: 00006846
 - tableTag: 68656164 (head)  checksum: 1B17CC54  offset: 00007238  length: 00000036
 - tableTag: 68686561 (hhea)  checksum: 06C709A1  offset: 00007270  length: 00000024
 - tableTag: 686D7478 (hmtx)  checksum: E26B1300  offset: 00007294  length: 00000394
 - tableTag: 6C6F6361 (loca)  checksum: CD3CE745  offset: 00007628  length: 000001CC
 - tableTag: 6D617870 (maxp)  checksum: 019E0E87  offset: 000077F4  length: 00000020
 - tableTag: 6E616D65 (name)  checksum: E8A738C7  offset: 00007814  length: 0000076E
 - tableTag: 706F7374 (post)  checksum: 373C35EF  offset: 00007F84  length: 000001EC
 - tableTag: 70726570 (prep)  checksum: AABDD644  offset: 00008FD0  length: 000000B2
offset 00007276: 'descender'      field in 'hhea' table: 00EC (236) --> FF14 (-236) (modified)
offset 000006CA: 'sTypoDescender' field in 'OS/2' table: 00F0 (240) --> FF10 (-240) (modified)
offset 000000A0: checksum for 'hhea' table: 06C709A1 --> 06C807C9 (modified)
offset 00000030: checksum for 'OS/2' table: 8C2D7E6C --> 8C2E7C8C (modified)
offset 00000090: checksum for 'head' table: 1B17CC54 --> 1B17CC54 (not modified)
offset 00007240: 'checksumAdjustment' field in 'head' table: 700FA33C --> 700BAAAC (modified)

nooriro@xps:/mnt/c/Users/nooriro/CLionProjects/untitled6/cmake-build-release-wsl$ ./untitled6 Charter-Bold.ttf
sfntVersion: 00010000  numTables: 0010
 - tableTag: 44534947 (DSIG)  checksum: 00000001  offset: 00008A2C  length: 00000008
 - tableTag: 47504F53 (GPOS)  checksum: 1CF31346  offset: 0000010C  length: 000006C8
 - tableTag: 4F532F32 (OS/2)  checksum: 8D5981F5  offset: 000007D4  length: 00000060
 - tableTag: 636D6170 (cmap)  checksum: 52F054E4  offset: 00000834  length: 0000030C
 - tableTag: 63767420 (cvt )  checksum: 051E1134  offset: 00007B20  length: 0000004A
 - tableTag: 6670676D (fpgm)  checksum: 622EFD7C  offset: 00007B6C  length: 00000E0C
 - tableTag: 67617370 (gasp)  checksum: 00000010  offset: 00007B18  length: 00000008
 - tableTag: 676C7966 (glyf)  checksum: 72F17DAD  offset: 00000B40  length: 000060B6
 - tableTag: 68656164 (head)  checksum: 1BAACC3E  offset: 00006BF8  length: 00000036
 - tableTag: 68686561 (hhea)  checksum: 081D0634  offset: 00006C30  length: 00000024
 - tableTag: 686D7478 (hmtx)  checksum: FF6324F0  offset: 00006C54  length: 00000394
 - tableTag: 6C6F6361 (loca)  checksum: FEA216EB  offset: 00006FE8  length: 000001CC
 - tableTag: 6D617870 (maxp)  checksum: 019E0E83  offset: 000071B4  length: 00000020
 - tableTag: 6E616D65 (name)  checksum: C22FA494  offset: 000071D4  length: 00000756
 - tableTag: 706F7374 (post)  checksum: 37583609  offset: 0000792C  length: 000001EC
 - tableTag: 70726570 (prep)  checksum: D4BDD644  offset: 00008978  length: 000000B2
offset 00006C36: 'descender'      field in 'hhea' table: 00EC (236) --> FF14 (-236) (modified)
offset 0000081A: 'sTypoDescender' field in 'OS/2' table: 00F0 (240) --> FF10 (-240) (modified)
offset 000000A0: checksum for 'hhea' table: 081D0634 --> 081E045C (modified)
offset 00000030: checksum for 'OS/2' table: 8D5981F5 --> 8D5A8015 (modified)
offset 00000090: checksum for 'head' table: 1BAACC3E --> 1BAACC3E (not modified)
offset 00006C00: 'checksumAdjustment' field in 'head' table: E5D49B76 --> E5D0A2E6 (modified)

nooriro@xps:/mnt/c/Users/nooriro/CLionProjects/untitled6/cmake-build-release-wsl$ ./untitled6 Charter-Bold-Italic.ttf
sfntVersion: 00010000  numTables: 0010
 - tableTag: 44534947 (DSIG)  checksum: 00000001  offset: 00009268  length: 00000008
 - tableTag: 47504F53 (GPOS)  checksum: 145323A8  offset: 0000010C  length: 0000070C
 - tableTag: 4F532F32 (OS/2)  checksum: 8D5E81C9  offset: 00000818  length: 00000060
 - tableTag: 636D6170 (cmap)  checksum: 52F054E4  offset: 00000878  length: 0000030C
 - tableTag: 63767420 (cvt )  checksum: 051A1127  offset: 0000835C  length: 0000004A
 - tableTag: 6670676D (fpgm)  checksum: 622EFD7C  offset: 000083A8  length: 00000E0C
 - tableTag: 67617370 (gasp)  checksum: 00000010  offset: 00008354  length: 00000008
 - tableTag: 676C7966 (glyf)  checksum: D1D1DDF2  offset: 00000B84  length: 00006864
 - tableTag: 68656164 (head)  checksum: 1B81CC40  offset: 000073E8  length: 00000036
 - tableTag: 68686561 (hhea)  checksum: 07300A0A  offset: 00007420  length: 00000024
 - tableTag: 686D7478 (hmtx)  checksum: FA0F1322  offset: 00007444  length: 00000394
 - tableTag: 6C6F6361 (loca)  checksum: C41ADE38  offset: 000077D8  length: 000001CC
 - tableTag: 6D617870 (maxp)  checksum: 019E0E86  offset: 000079A4  length: 00000020
 - tableTag: 6E616D65 (name)  checksum: 75795E75  offset: 000079C4  length: 000007A4
 - tableTag: 706F7374 (post)  checksum: 37633609  offset: 00008168  length: 000001EC
 - tableTag: 70726570 (prep)  checksum: AABDD644  offset: 000091B4  length: 000000B2
offset 00007426: 'descender'      field in 'hhea' table: 00EC (236) --> FF14 (-236) (modified)
offset 0000085E: 'sTypoDescender' field in 'OS/2' table: 00F0 (240) --> FF10 (-240) (modified)
offset 000000A0: checksum for 'hhea' table: 07300A0A --> 07310832 (modified)
offset 00000030: checksum for 'OS/2' table: 8D5E81C9 --> 8D5F7FE9 (modified)
offset 00000090: checksum for 'head' table: 1B81CC40 --> 1B81CC40 (not modified)
offset 000073F0: 'checksumAdjustment' field in 'head' table: A88A6A10 --> A8867180 (modified)
@NightFurySL2001
Copy link
Author

Any updates on changing the guidelines?

@vv-monsalve
Copy link
Contributor

@aaronbell, this proposal requires CJK's expertise, could you please help us to review it?

@aaronbell
Copy link

The suggestion seems reasonable to me. Ken's method of 880 / -120 works well for standard CJK use, but I can see other ratios being employed depending on the requirements of the specific project. As long as the CJK bounding box aligns with the UPM, things should be alright.

@vv-monsalve
Copy link
Contributor

Thanks @aaronbell. This would require a consensus before making the change here. Would you like to bring the subject to the next meeting as part of your current job in the CJK fonts?

@vv-monsalve vv-monsalve added the documentation Improvements or additions to documentation label Oct 9, 2024
@NightFurySL2001
Copy link
Author

NightFurySL2001 commented Oct 9, 2024

Quick notes:

  1. hhea.descender should be negative, so (~0.288 * upm) should change to (~-0.288 * upm) with negative value. It seems that this can be easily confused (see nooriro/nooriro.github.io@2787e25). I have updated this in Update CJK vertical metrics #135 .
  2. Fontbakery check should be updated to disable typoascender_exceeds_Agrave when cjk_vertical_metrics is triggered. Errors could be raised with current setting (see Have reviewed the output with fontbakery? line/seed#4).

Checking that the typoAscender exceeds the yMax of the /Agrave.

Check ID: FontBakeryCheck:com.arrowtype.fonts/check/typoascender_exceeds_Agrave

🔥 FAIL OS/2.sTypoAscender value should be greater than 1008, but got 880 instead

@307587
Copy link

307587 commented Dec 8, 2024

hi, coming from my issue above, may i suggest: add a 'short height variant' for the CJK family, like how 新一細明體 (2nd example font in the issue) is the 'short height variant' of 一點明體.

@NightFurySL2001
Copy link
Author

NightFurySL2001 commented Dec 8, 2024

This issue discuss how to set vertical metrics in digital fonts for all kinds of usage, not only for using in Microsoft Word.

新一細明體 is a metric compatible version of 新細明體 (PMingLiU on Windows) based on the core font 一點明體. The issue that comes with the 'short height variant' is that extra tall characters (eg pinyin ǕǙẾỀ) might get clipped off if they are outside of the ascender/descender range, especially on mobile UI where users cannot adjust the line height.

Quote from Source Han/Noto CJK Readme file:

The 'OS/2' Table

The OS/2.sTypoLineGap value has been set to 0 (zero) units, and is also reflected in the hhea.LineGap and vhea.lineGap values. The OS/2.usWinAscent and OS/2.usWinDescent values have been calculated by removing excessively tall and other vertical-only glyphs—for U+2E3A, U+2E3B, U+302A through U+302D, U+3031, and U+3032—from the equation, and have been harmonized across all seven weights. These same harmonized settings are also reflected in the hhea.Ascender and hhea.Descender values. This is for the benefit of applications that use these values for determining default leading. These and other 'OS/2' table settings are intended to provide consistent cross-platform line spacing (aka vertical metrics).

@NightFurySL2001
Copy link
Author

After reviewing the discussion on source-foundry/font-line#2 , I do wonder where does the value of 1.16 and 0.288 comes from for the hhea table. These two values seem to be based only on Source Han Sans.

For reference, in Source Han Sans/Noto Sans CJK (after removing extra-tall characters like U+2E3A, U+2E3B, U+302A through U+302D, U+3031, and U+3032):

  • Highest point in Ǜ @ Heavy weight, y=1160
  • Next 10 highest characters: ẪỄỖẴẲẮẰǙǗ
  • Lowest point in ◌〪 (vertical bar, U+302A) @ Heavy weight, y=-320
  • Next lowest point that is not combining character: (U+FFE8 Halfwidth Forms Light Vertical) @ Heavy weight, y=-288
  • Next 10 lowest characters: ¦|¸ÇçẠạẬậẶ

Maybe the suggestion can be changed to allow more flexibility for the hhea values based on the highest and lowest glyph.

@aaronbell
Copy link

@NightFurySL2001

The winAscent and winDescent are clipping metrics, so to avoid circumstances where parts of glyphs get cut off in applications like Word, they need to be set to the font's yMax and yMin. However, doing so, as has been pointed out, can result in circumstances where the gap between lines of text is undesirably large. And while most applications allow one to increase line gaps, they don't often allow one to decrease line gaps.

For Latin fonts, the solution was to introduce the useTypoMetrics flag which tells software to use the metrics set in sTypo and can be set more "typographically" to ensure proper line spacing regardless of clipping. Of course there's still the question of what's right for a given font's purpose (as in, should it be set to prioritize taller languages like Vietnamese or shorter ones). hhea will follow whichever metric is given priority—winMetrics if the useTypoMetrics flag is not set, and sTypo if it is set.

This leads me to wonder if introducing that flag to CJK fonts makes sense. Older fonts, like MingLiU, had tight vertical spacing (winMetrics: 820/204 -> 1024 unit height) and creates a rather dense look on the page:

Image

Taking LXGW WenKai TC as an example, following the established GF guidance looks a bit loose (1448 unit height):

Image

If we turned on useTypoMetrics and it instead used the sTypo metric values, we get a rendering more similar to MingLiu (at a 1000 unit height), which may be tighter than is desireable.

Image

So one option is to increase the dimensions outward, say a 15% increase (1150 unit height)
Image

This 15% increase is arbitrary, btw, and can be adjusted as necessary.

The net effect of this change, though, is that the sTypo values will no longer 1:1 align with the ideographic bounding box. But I am not sure if that alignment was providing much value in the first place when useTypoMetrics is not set.

@NightFurySL2001
Copy link
Author

NightFurySL2001 commented Dec 12, 2024

It seems the sTypo metrics are the one used to calculate the ideographic box when missing baseline information, which is why it was required to match the ideographic box.

https://learn.microsoft.com/en-us/typography/opentype/spec/baselinetags#ideoembox

The OS/2.sTypoDescender and OS/2.sTypoAscender fields in a CJK font may specify metrics different from the HorizAxis.ideo and HorizAxis.idtp values in the BASE table. However, CJK font developers should be aware that some applications might not read the BASE table at all but simply use the OS/2.sTypoDescender and OS/2.sTypoAscender fields to describe the bottom and top edges of the ideographic em-box. If developers want their fonts to work correctly with such applications, they should ensure that any ideographic em-box values in the BASE table of their CJK fonts describe the same bottom and top edges as the OS/2.sTypoDescender and OS/2.sTypoAscender fields.

@aaronbell
Copy link

Hmmm, interesting. My understanding was that there are few, if any, applications (maybe Adobe is the only one) that support any kind of baseline alignment. I'll look into it more.

@NightFurySL2001
Copy link
Author

I think for now we can update the metrics information with the PR I had sent in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants