stb_truetype.h: Support Font Variations
I figure this is probably goes along with adding support for hinting. However there is some fonts where a lot of data is missing because of the lack of support for Font Variations. The two major variations for this are as follows:
Variation 1: Apple Advanced Typography (AAT) - This is Apple's Variation on TrueType Fonts, and has a slightly different signature than OpenType. This is still a good reference since a lot of the behavior is the same in this, and OpenType. The only difference may be the table name is changed.
Variation 2: OpenType Version 1.8.2 or newer - This includes most of the tables used by Apple, and adds a few mores. Also, Collections for OpenType use the OTC file extension.
To help with implementation, I have a list of the tables that need implementing to add this feature, and you can find the list in the table below...
| Table Name | Description | AAT Support | OpenType Support |
|---|---|---|---|
| avar | Axis Variations Table | Y | Y |
| cvar | Control Value Variations table. | Y | Y |
| fvar | Font Variation Table | Y | Y |
| gvar | Glyph Variation Table | Y | Y |
| name | Name Table | Y | Y |
| HVAR | Horizontal Metrics Variations | N | Y |
| MVAR | Metrics Variations Table | N | Y |
| VVAR | Vertical Metrics Variations | N | Y |
| ttcf | TrueType Collections Table | N | Y |
Also, Since there is a need for fonts to test to make sure this works, you can find the fonts in the following list. In general these fonts have have two downloadable versions where one version includes the Font Variations, and the other version has the fonts variations as separate font files.
- Adobe Fonts: Note: This font set is currently the best option to test this functionality for users who are not using Chinese/Japanese/Korean (aka CJK).
- Adobe Source Code Pro - https://github.com/adobe-fonts/source-code-pro
- Adobe Source Sans Pro - https://github.com/adobe-fonts/source-sans-pro
- Adobe Source Serif Pro - https://github.com/adobe-fonts/source-serif-pro
- Google's Noto Fonts - This has a lot of fonts, and variations. I recommend just looking at the "Super OTC" version since this is most likely going to be the font which can generate problems since a single font can contain 30+ fonts in this case.
- Noto Sans CJK
- Noto Sans Mono CJK- This font is merged as a sub-font of the Noto Sans CJK Super OTC Font.
- Noto Serif CJK
I am unlikely to tackle this problem anytime soon. as variation support looks non-trivial.
(But FWIW stb_truetype already supports the 'ttcf' table with "stbtt_GetFontOffsetForIndex()", and has some (possibly useless) support for the 'name' table.)
After seeing that this is probably a non-trivial change, I went ahead and saw what changes would be required to see how Implementing support for this feature request would work. For the most part this feature request entails fixing the remaining features found in OpenType Version 1.7, and then going about implementing features found in OpenType version 1.8.x.
Stage 1: add some of the missing features found OpenType Version 1.7...
- [ ] Implement support for the F2DOT14 format.
- [ ] Fix the Glyph Data Table (glyf) implementation. This table also contains information on Font Scaling and uses the F2DOT14 format to store this information.
- [ ] Implement Support for Vertical Font Metrics.
- [ ] Optional Implement Baseline Table (BASE) Support. This table is used to help with text flow when fonts of various sizes, and styles are mixed together.
- [ ] Optional: Implement Vertical Origin Table(VORG)
- [ ] Optional Implement support for the Glyph Positioning Table (GPOS).
Stage 2: Actually Implement Font Variations.
- [ ] Add Functionality to retrieve strings from the Naming Table (name). This is important since this table contains not only the font name, but the name of the font variations.
- [ ] Implement functions to query, and select font variations.
- [ ] Required: Font Variations Table (fvar) table. - This is required by all of the following tables.
- [ ] Required: Style Attributes Table ('STAT') - This the various Named axis.
- [ ] Fix Kerning Support for Variable Fonts. This is mostly improving on the Glyph Position Table.
- [ ] Implement Font Variations for TrueType Outlines
- [ ] Implement Glyph Variations Table ('gvar') - This modifies the Glyph data outlined by 'glyf' Table.
- [ ] CVT Variations Table ('cvar') - This modifies the Control Value Table data.
- [ ] Implement Various Font-Axis Table Support
- [ ] Axis Variations Table (avar) - This controls how the Glyphs are interpolated.
- [ ] Font Weight Axis ('wght')
- [ ] Font Width Axis ('wdth')
- [ ] Italic axis. ('ital')
- [ ] Optical size Axis ('opsz')
- [ ] Slant Axis ('slnt')
- [ ] Implement Custom Axis Names - In general these are linked to the previous axis values.
- [ ] Implement Font Metric Modifications
- [ ] Per-Font variation Font Metrics: Metrics Variations Table (MVAR)
- [ ] Horizontal Font Metrics Modifications: Horizontal Metrics Variations Table(HVAR)
- [ ] Vertical Font Metrics Modifications: Vertical Metrics Variations Table(VVAR) - This requires the Vertical Font metric support.
- [ ] Optional: Implement support for Compact Font Format (CFF) Version 2 (the CFF2 table)
Note: Currently very few fonts exist using the CFF2 table, and the best example I can find is the Adobe Variable Font Prototype
When multi styles mixed in a single font file, How can I choose a style?
It has not been supported , Right?
(I see your comments "Optional Implement Baseline Table (BASE) Support. This table is used to help with text flow when fonts of various sizes, and styles are mixed together.")
Please help me~ thanks~
Note: Currently very few fonts exist using the CFF2 table, and the best example I can find is the [Adobe Variable Font Prototype]
The system fonts on Android 15 now use CFF2. Or at least the one my app loads seems to (/system/fonts/NotoSansCJK-Regular.ttc).
Here's what TTX has to say about the first font in that collection:
C:\Users\andy>ttx -y 0 -l c:\tmp\NotoSansCJK-Regular.ttc
Listing table info for "c:\tmp\NotoSansCJK-Regular.ttc":
tag checksum length offset
---- ---------- -------- --------
BASE 0x6C1B8E98 278 29739416
CFF2 0xA4D5711E 29217242 420
GDEF 0x8002BFBB 144 29739696
GPOS 0x32E1C03E 78320 29739840
GSUB 0x8F893223 172968 29818160
HVAR 0x78307A25 131120 29991128
OS/2 0x92EC0EE3 96 29479892
STAT 0x8B096E6B 116 30122248
VORG 0x91052902 988 30122364
VVAR 0xAE9C8E20 59450 30123352
avar 0x3AC93334 30 30182888
cmap 0xBA0B23CA 257183 29479988
fvar 0x93AA699B 84 30182804
gasp 0x00000010 8 29739408
head 0x25B78687 54 29217664
hhea 0x0C1B084F 36 29479856
hmtx 0x2BEA5830 262134 29217720
maxp 0xFFFF5000 6 412
name 0xCA16F7FE 2195 29737180
post 0xFF860032 32 29739376
prep 0x68068C85 7 29737172
vhea 0x0CBB1587 36 30444308
vmtx 0x9D93F118 261386 30182920
BTW, thanks for making stb_truetype.h.
Yes, because /system/fonts/NotoSansCJK-Regular.ttc became CFF2 under Android 15 and 16, OpenGL apps can only use NotoSerifCJK-Regular.ttc for Chinese or increase the size of their app by 20 megabyte.