`script::SCRIPT_MATH` seems to not pick up the `math` script tag in the font
MRE (at least as minimal as I could get) in rust:
rustybuzz v0.20.1
use rustybuzz::{Face, Feature, UnicodeBuffer, ttf_parser};
use std::fs::File;
use std::io::BufReader;
use std::io::Read;
fn main() {
let f = File::open("NewCMMath-Book.otf").unwrap();
let mut reader = BufReader::new(f);
let mut buffer = Vec::new();
reader.read_to_end(&mut buffer).unwrap();
let ttf_face = ttf_parser::Face::parse(buffer.as_slice(), 0).unwrap();
let c = '𝑖';
let id = ttf_face.glyph_index(c).unwrap().0;
let rusty_face = Face::from_face(ttf_face);
let features = [Feature::new(ttf_parser::Tag::from_bytes(b"ssty"), 1, ..)];
// With script set to "Zmth"
let mut buffer = UnicodeBuffer::new();
buffer.add(c, 0);
buffer.set_script(rustybuzz::script::SCRIPT_MATH);
let buffer = rustybuzz::shape(&rusty_face, &features, buffer);
let new_id = buffer.glyph_infos()[0].glyph_id as u16;
assert_eq!(new_id, id);
// With script set to "math"
let mut buffer = buffer.clear();
buffer.add(c, 0);
buffer.set_script(
rustybuzz::Script::from_iso15924_tag(ttf_parser::Tag::from_bytes(b"math")).unwrap(),
);
let buffer = rustybuzz::shape(&rusty_face, &features, buffer);
let new_id = buffer.glyph_infos()[0].glyph_id as u16;
assert_ne!(new_id, id);
}
Here's what happens with harfbuzz:
hb-shape (HarfBuzz) 10.2.0
$ hb-shape --trace --script=Zmth --features=ssty NewCMMath-Book.otf "𝑖"
trace: start table GSUB script tag 'math' buffer: [u1D456=0]
trace: start lookup 7 feature 'ssty' buffer: [u1D456=0]
trace: replacing glyph at 0 (alternate substitution) buffer: [u1D456=0]
trace: replaced glyph at 0 (alternate substitution) buffer: [u1D456.st=0]
trace: end lookup 7 feature 'ssty' buffer: [u1D456.st=0]
trace: end table GSUB script tag 'math' buffer: [u1D456.st=0]
trace: start table GPOS script tag 'math' buffer: [u1D456.st=0+404]
trace: start lookup 0 feature 'kern' buffer: [u1D456.st=0+404]
trace: skipped lookup 0 feature 'kern' because no glyph matches buffer: [u1D456.st=0+404]
trace: end lookup 0 feature 'kern' buffer: [u1D456.st=0+404]
trace: start lookup 1 feature 'kern' buffer: [u1D456.st=0+404]
trace: skipped lookup 1 feature 'kern' because no glyph matches buffer: [u1D456.st=0+404]
trace: end lookup 1 feature 'kern' buffer: [u1D456.st=0+404]
trace: end table GPOS script tag 'math' buffer: [u1D456.st=0+404]
[u1D456.st=0+404]
$ hb-shape --trace --script=math --features=ssty NewCMMath-Book.otf "𝑖"
trace: start table GSUB script tag 'math' buffer: [u1D456=0]
trace: start lookup 7 feature 'ssty' buffer: [u1D456=0]
trace: replacing glyph at 0 (alternate substitution) buffer: [u1D456=0]
trace: replaced glyph at 0 (alternate substitution) buffer: [u1D456.st=0]
trace: end lookup 7 feature 'ssty' buffer: [u1D456.st=0]
trace: end table GSUB script tag 'math' buffer: [u1D456.st=0]
trace: start table GPOS script tag 'math' buffer: [u1D456.st=0+404]
trace: start lookup 0 feature 'kern' buffer: [u1D456.st=0+404]
trace: skipped lookup 0 feature 'kern' because no glyph matches buffer: [u1D456.st=0+404]
trace: end lookup 0 feature 'kern' buffer: [u1D456.st=0+404]
trace: start lookup 1 feature 'kern' buffer: [u1D456.st=0+404]
trace: skipped lookup 1 feature 'kern' because no glyph matches buffer: [u1D456.st=0+404]
trace: end lookup 1 feature 'kern' buffer: [u1D456.st=0+404]
trace: end table GPOS script tag 'math' buffer: [u1D456.st=0+404]
[u1D456.st=0+404]
$ hb-shape --version
hb-shape (HarfBuzz) 10.2.0
Available shapers: graphite2,ot,fallback
Thanks for the MRE, how urgent is it (i.e. is it necessary for the PR to lang)? If it's critical I can try to find some time to debug it.
Not very urgent, everything appears to work just fine using the "math" script tag so it shouldn't block the PR.
old_tag_from_script() implementation is different between rustybuzz and harfbuzz:
hb_ot_old_tag_from_script (hb_script_t script)
{
/* This seems to be accurate as of end of 2012. */
switch ((hb_tag_t) script)
{
case HB_SCRIPT_INVALID: return HB_OT_TAG_DEFAULT_SCRIPT;
case HB_SCRIPT_MATH: return HB_OT_TAG_MATH_SCRIPT;
/* KATAKANA and HIRAGANA both map to 'kana' */
case HB_SCRIPT_HIRAGANA: return HB_TAG('k','a','n','a');
/* Spaces at the end are preserved, unlike ISO 15924 */
case HB_SCRIPT_LAO: return HB_TAG('l','a','o',' ');
case HB_SCRIPT_YI: return HB_TAG('y','i',' ',' ');
/* Unicode-5.0 additions */
case HB_SCRIPT_NKO: return HB_TAG('n','k','o',' ');
/* Unicode-5.1 additions */
case HB_SCRIPT_VAI: return HB_TAG('v','a','i',' ');
}
/* Else, just change first char to lowercase and return */
return ((hb_tag_t) script) | 0x20000000u;
}
Rustybuzz is not handling INVALID or MATH scripts:
fn old_tag_from_script(script: Script) -> hb_tag_t {
// This seems to be accurate as of end of 2012.
match script {
// Katakana and Hiragana both map to 'kana'.
script::HIRAGANA => hb_tag_t::from_bytes(b"kana"),
// Spaces at the end are preserved, unlike ISO 15924.
script::LAO => hb_tag_t::from_bytes(b"lao "),
script::YI => hb_tag_t::from_bytes(b"yi "),
// Unicode-5.0 additions.
script::NKO => hb_tag_t::from_bytes(b"nko "),
// Unicode-5.1 additions.
script::VAI => hb_tag_t::from_bytes(b"vai "),
// Else, just change first char to lowercase and return.
_ => hb_tag_t(script.tag().as_u32() | 0x20000000),
}
}
Probably it is missing this commit from HarfBuzz? https://github.com/harfbuzz/harfbuzz/commit/1bc4bad7a59e9d4d79d8faeb9e695df19aa494da
74b4fcdc4c09a9420aee5b54f77e556133bd0142 seems to have missed the conversion from HB_SCRIPT_MATH to HB_OT_TAG_MATH_SCRIPT.
74b4fcd seems to have missed the conversion from
HB_SCRIPT_MATHtoHB_OT_TAG_MATH_SCRIPT.
We should also fix in harfRuzz.
I tried applying https://github.com/harfbuzz/harfruzz/pull/58 but needs porting.