Skip to content

[css-fonts-4] Extend font-language-override to override OpenType "script" as well #3178

@faceless2

Description

@faceless2

Selecting features from an OpenType font requires the correct language and script to be set, and where the language in the font GSUB table doesn't match the language in the source document, we have "font-language-override" to force it. But there are two issues:

  • There is no facility to choose the default language from the OpenType tables, i.e. to turn off language-specific selection altogether.
  • There is no such facility for OpenType "script" tags. We've found a case where it's required.

Why we need to override OpenType script

The PrinceXML sample document at http://css4.pub/2015/malthus/essay.html references the OpenType font "Adobe Caslon Pro", then turns on oldstyle numbers with what is effectively font-variant: oldstyle-nums discretionary-ligatures;. The document later contains a table cell containing just digits, <td>789</td>.

The problem: Adobe Caslon defines just one script/language combination: the "latn" script with the default language. Digits have the Unicode script [1] "Common", not "Latin", so there should be no matching script/langauge combination, and oldstyle numbers substitution should not occur.

That's clearly not the intention of the document author. The OpenType spec suggests flexibility on which script to choose when "Common" glyphs are mixed in with another script such as "Latin", which is fine if they're in the middle of a paragraph. However where they're in an isolated HTML element, determining which other script they might reasonably be is guesswork. Prince guesses right, but it's better to allow it to be specified explicitly, as we do for languages.

Current syntax

normal | <string>
  • normal uses the language from the source document
  • <string> is defined as a "single three-letter case-sensitive String" [2] which will match the OpenType language tag (OpenType language tags are always uppercase, the full list is at https://docs.microsoft.com/en-us/typography/opentype/spec/languagetags).
  • There is no way to not use any language specific matching in the font.

Possible proposed syntax

Two options. Either add a font-script-override feature, or change font-language-override to:

normal | none | <string> [ normal | none | <string>]?
  • none can be used to select not to use any language or script specific matching
  • The second <string> would be a "two, three or four letter cases-sensitive String" which will match the OpenType script tag - which are always lower case. The full list is at https://docs.microsoft.com/en-us/typography/opentype/spec/scripttags
  • If the second parameter is missing, it evaluates to normal
  • If both parameters are idents, then the first applies to the language and the second to the script
  • If both parameters are strings, there is no ambiguity because the OpenType language is always uppercase, script is always lowercase

Some examples:

font-language-override: normal;  /* no overriding */
font-language-override: none;  /* override language to opentype default */
font-language-override: "URD";  /* override language to Urdu*/
font-language-override: "latn";  /* override script to Latin */
font-language-override: "KUY" "lao";  /* override language to Kuy, script to Lao */
font-language-override: "lao" "KUY";  /* same */
font-language-override: normal none; /* override script to Common */
font-language-override: none normal; /* override language to opentype default */

In the PrinceXML example described above, we could easily work around the lack of the recommended "default" script entry in the font by doing

body {
    font-variant: oldstyle-nums discretionary-ligatures;
    font-language-override: "latn";
}

[1] https://unicode.org/reports/tr24/
[2] This should read "uppercase or digits" and not neccesarily three letters: #1104

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions