Description
Consider this (real) situation: a library has a number of functions - one which fixes problems with the name
table; one which fixes problems with the fvar
table instances; one which fixes problems with the STAT
table. In Python, these would have signatures like:
fix_name(font: TTFont) # Modifies TTFont
fix_fvar(font: TTFont)
fix_stat(font: TTFont)
How would we port this to Rust? Sounds easy enough, but these tables have dependencies on each other - altering the fvar
table may require adding new name
table entries or deleting some, and similarly for STAT. If we had a "writeable FontRef
", this would be doable:
fix_name(font: &mut write_fonts::FontRef);
fix_fvar(font: &mut write_fonts::FontRef);
fix_stat(font: &mut write_fonts::FontRef);
The closest we have to that is a FontBuilder
, but if we have a FontBuilder
object, we can't get at the name
table any more; there's no way to .get()
a table from inside it. So instead right now, we are forced to do this:
fix_name(font: FontRef) -> Result<Vec<u8>, Error> {
let mut new_font = FontBuilder::new();
let name: Name = font.name()?.to_owned_table();
do_stuff(&mut name);
new_font.add_table(&name_table)?;
Ok(new_font.copy_missing_tables(font).build())
}
And now, if I want to fix the name and the fear and the STAT, I have to decompile, modify, copy, compile several times over. Urgh. The alternative is to return modified Name
, Stat
, etc. structs, but that doesn't really help - if you want to modify multiple things at once, you have to also take these modified structs as (individual!) inputs to your function instead of a FontRef
, and that's also nasty for the user. What we want is a bag of write_fonts::table
structs that we can compile when we've done modifying them - that would give us a writable FontRef
, the write_fonts
equivalent of a read_fonts::FontRef
.
The reason we can't have this right now is that add_table
compiles the table, and build
just builds the offset table and the table directory. If we could instead stick write_fonts::table::Name
, write_fonts::table::Fvar
, etc. structs into the FontBuilder
- and if build()
did all the compilation at the end - then it would be much easier to get those table structs out again and re-modify them.
Activity