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

[write-fonts] Use short offsets in gvar where appropriate #639

Merged
merged 2 commits into from
Sep 29, 2023

Conversation

cmyr
Copy link
Member

@cmyr cmyr commented Sep 28, 2023

This was something I skipped in my initial implementation, but should save us a few kb in the common case.

closes #615

.iter()
.fold(0, |acc, val| acc + val.length);

if max_offset / 2 < (u16::MAX as u32) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't consider the padding, does it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, <=?

@cmyr cmyr force-pushed the gvar-short-offsets branch from eb4cfbb to 093d7f6 Compare September 28, 2023 22:18
@behdad
Copy link
Contributor

behdad commented Sep 28, 2023

Thanks. Logic LGTM.


let bytes = sink.into_data().bytes;
let expected_len = 6 * u16::RAW_BYTE_LEN // offsets: n_glyphs + 1
+ 32 * 5; // rounded size of each glyph, * 5 typhs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is "typhs" a typo?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

um yes, that is supposed to say 'glyphs', i imagine..

This was something I skipped in my initial implementation, but should
save us a few kb in the common case.
@cmyr cmyr force-pushed the gvar-short-offsets branch from 093d7f6 to 916fbcf Compare September 29, 2023 16:09
@@ -934,4 +969,120 @@ mod tests {
Some(PackedPointNumbers::Some(vec![1, 3]))
);
}

fn make_39_bytes_of_variation_data() -> Vec<GlyphDeltas> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does it matter that it's 39 bytes?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

guess because it's % 2 != 0 so must be 2-byte aligned

tupl_map.insert(&variations.variations[1].peak_tuple, 2);

let built = variations.clone().build(&tupl_map);
// we need an odd number for this to make sense
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

explain why


#[test]
fn use_long_offsets_when_necessary() {
// 2**16 * 2 / (31 + 1 padding) (bytes per tuple) = 4096 so this just overflows
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest you test the most possible short offsets as well, for example loop over N_GLYPHS 4099, 4100 and confirm that their respective flags are SHORT_OFFSETS, LONG_OFFSETS with the expected sizes

.map(|off| off.unwrap().get())
.collect::<Vec<_>>(),
vec![0u32, 31, 62, 93, 124, 155]
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The majority of prefer_short_offsets and use_long_offsets_when_necessary is duplicative noise; if you diff them they differ only in a few key values. Make a helper, e.g. assert_gvar(num glyphs, expected flags, expected offset type, expected first values)

That will make testing the maximum number of short offsets as it's own test trivial too.

@@ -254,11 +262,15 @@ impl GlyphVariations {
.map(|tup| tup.build(shared_tuple_map, shared_points.as_ref()))
.unzip();

GlyphVariationData {
let mut this = GlyphVariationData {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the name "this" is perhaps suboptimal to readers with a C++ or Java background.

///
/// we compute this once up front because we need to know it in a bunch
/// of different places
length: u32,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usize seems the more natural type, I suppose you eventually want to assign it somewhere u32. Perhaps note why it's u32 here?

}
// then write the actual data
for glyph in self.data {
if !glyph.is_empty() {
glyph.write_into(writer);
if !self.long_offsets && glyph.length % 2 != 0 {
writer.pad_to_2byte_aligned();
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You dont' need && glyph.length % 2 here as pad_to_2byte_aligned will happily nop if htat's true?

Copy link
Collaborator

@rsheeter rsheeter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM once comments addressed

cmyr added a commit that referenced this pull request Sep 29, 2023
- Reuse test code
- more testing of the short/long boundary condition
- clarify some comments
- Reuse test code
- more testing of the short/long boundary condition
- clarify some comments
@cmyr cmyr force-pushed the gvar-short-offsets branch from 716f724 to 306c78d Compare September 29, 2023 18:41
@cmyr cmyr merged commit d4e07eb into main Sep 29, 2023
9 checks passed
@cmyr cmyr deleted the gvar-short-offsets branch September 29, 2023 19:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

gvar: use short offsets when appropriate
4 participants