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

Legacy kern table #1183

Open
simoncozens opened this issue Oct 10, 2024 · 8 comments
Open

Legacy kern table #1183

simoncozens opened this issue Oct 10, 2024 · 8 comments
Labels
enhancement New feature or request good first issue Good for newcomers

Comments

@simoncozens
Copy link
Contributor

fontations doesn't currently read or write the kern table. However, support for this table is needed for kerning in Microsoft Powerpoint. It is also the subject of a fontbakery check.

@rsheeter
Copy link
Collaborator

Do you mean Powerpoint only supports kern?! That's amazing.

@simoncozens
Copy link
Contributor Author

Exactly.

@LucasHimself
Copy link

PowerPoint also supports GPOS kerning, but not on all platforms :-)

@khaledhosny
Copy link

Do you mean Powerpoint only supports kern?! That's amazing.

Unless it is a variable font:
https://forum.glyphsapp.com/t/ppt-microsoft-opentype-and-gpos-kerning-work-with-vf/31467

@rsheeter
Copy link
Collaborator

I immediately wonder if adding a single axis with min = default = max would suffice to make it think it's a variable font

@khaledhosny
Copy link

I’d start with an empty (or minimum valid) fvar table.

@simoncozens
Copy link
Contributor Author

Incidentally I did try implementing this and I am not sure that it is a "good first issue". :-) KernSubtableFormat0 is OK, but KernSubtableFormat2 is followed by a two-dimensional array of data where the number of rows and columns are not directly encoded.

OTOH, it's not clear that KernSubtableFormat2 is needed, as Windows only supports format 0, and FontTools does not know of it either. FontTools also mentions a "new" Apple-specific format kern table (not subtable) with version 1.0 and completely different structures.

If we are happy with just version 0 tables (ignoring Apple) and also ignoring KernSubtableFormat2, the below should do:

/// The [kern (Kerning)](https://docs.microsoft.com/en-us/typography/opentype/spec/kern) table
#[tag = "kern"]
table Kern {
    /// Table version number — set to 0.
    #[compile(0)]
    version: u16,
    /// Number of subtables in the kerning table
    #[compile(array_len($subtables))]
    num_tables: u16,
    #[count($num_tables)]
    subtables: [KernSubtable],
}

/// The different kern subtable formats.
format u16 KernSubtable {
    Format0(Kern0),
    // Nope.
    // Format2(Kern2),
}

/// [kern Format 0](https://docs.microsoft.com/en-us/typography/opentype/spec/kern#format-0)
table Kern0 {
    /// Format number is set to 0.
    #[format = 0]
    format: u16,
    /// The length of the subtable, in bytes (including this header).
    length: u16,
    /// What type of information is contained in this table.
    coverage: KernCoverage,
    /// This gives the number of kerning pairs in the table.
    num_pairs: u16,
    /// The largest power of two less than or equal to the value of num_pairs, multiplied by the
    /// size in bytes of an entry in the table.
    search_range: u16,
    /// This is calculated as log2 of the largest power of two less than or equal to the value of num_pairs.
    /// This value indicates how many iterations of the search loop will have to be made.
    /// (For example, in a list of eight items, there would have to be three iterations of the loop).
    entry_selector: u16,
    /// The value of num_pairs minus the largest power of two less than or equal to num_pairs,
    /// and then multiplied by the size in bytes of an entry in the table.
    range_shift: u16,
    /// Kern pairs
    #[count($num_pairs)]
    kerning_pairs: [KernPair],
}

table KernPair {
    /// The glyph index for the left-hand glyph in the kerning pair.
    left: u16,
    /// The glyph index for the right-hand glyph in the kerning pair.
    right: u16,
    /// The kerning value for the above pair, in font design units.
    /// If this value is greater than zero, the characters will be moved apart.
    /// If this value is less than zero, the character will be moved closer together.
    value: FWORD,
}

@cmyr
Copy link
Member

cmyr commented Oct 18, 2024

If format 0 is what we need to generate I think that's a good starting point, and we can revisit when the need arises? I'll take a look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

5 participants