Skip to content

Commit

Permalink
Add FontHeader::checksum
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanUkhov committed Feb 5, 2024
1 parent 1d50ea8 commit 67e6292
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 19 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "truetype"
version = "0.46.0"
version = "0.47.0"
edition = "2021"
license = "Apache-2.0/MIT"
authors = [
Expand Down
20 changes: 20 additions & 0 deletions src/tables/font_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//! [1]: https://learn.microsoft.com/en-us/typography/opentype/spec/head

use crate::number::q32;
use crate::Result;

table! {
@write
Expand Down Expand Up @@ -52,3 +53,22 @@ flags! {
0b1111_1111_1000_0000 => is_invalid,
}
}

impl FontHeader {
/// Compute the checksum.
pub fn checksum<T: crate::tape::Read>(&self, tape: &mut T) -> Result<u32> {
const MAGIC: u32 = 0xB1B0AFBA;
let mut data = vec![];
tape.read_to_end(&mut data)?;
if data.len() % 4 != 0 {
raise!("found a malformed layout");
}
let sum = data
.chunks_exact(4)
.map(TryInto::try_into)
.map(std::result::Result::unwrap)
.map(u32::from_be_bytes)
.fold(0u32, |sum, value| sum.wrapping_add(value));
Ok(MAGIC.wrapping_sub(sum))
}
}
3 changes: 1 addition & 2 deletions src/tables/names/encoding/unicode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ pub fn decode_utf16(data: &[u8]) -> Option<String> {
let data = data
.chunks_exact(2)
.map(TryInto::try_into)
.map(std::result::Result::ok)
.map(Option::unwrap)
.map(std::result::Result::unwrap)
.map(u16::from_be_bytes)
.collect::<Vec<_>>();
String::from_utf16(&data).ok()
Expand Down
28 changes: 14 additions & 14 deletions src/tables/offsets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,18 @@ impl Record {
let count = ((self.size + 4 - 1) & !(4 - 1)) / 4;
let excess = 4 * count - self.size;
debug_assert!(excess < 4);
tape.stay(|tape| {
tape.jump(self.offset as u64)?;
let mut total: u32 = 0;
for i in 0..count {
let mut value: u32 = tape.take()?;
if i + 1 == count {
value &= !((1u32 << (8 * excess)) - 1);
}
if !head || i != 2 {
total = total.wrapping_add(value);
}
tape.jump(self.offset as u64)?;
let mut total: u32 = 0;
for i in 0..count {
let mut value: u32 = tape.take()?;
if i + 1 == count {
value &= !((1u32 << (8 * excess)) - 1);
}
Ok(total)
})
if !head || i != 2 {
total = total.wrapping_add(value);
}
}
Ok(total)
}
}

Expand All @@ -90,6 +88,8 @@ mod tests {
use super::Record;
use crate::Tag;

macro_rules! ok(($result:expr) => ($result.unwrap()));

#[test]
fn record_checksum() {
macro_rules! checksum(
Expand All @@ -102,7 +102,7 @@ mod tests {
offset: 0,
checksum: $checksum,
};
table.checksum == table.checksum(&mut reader).unwrap()
table.checksum == ok!(table.checksum(&mut reader))
})
);
assert!(!checksum!(
Expand Down
2 changes: 1 addition & 1 deletion src/tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,6 @@ mod tests {
#[test]
fn read() {
let mut tape = Cursor::new(b"true".to_vec());
assert_eq!(Tag::read(&mut tape).unwrap(), Tag(*b"true"));
assert_eq!(ok!(Tag::read(&mut tape)), Tag(*b"true"));
}
}
15 changes: 14 additions & 1 deletion tests/font_header.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
#[macro_use]
mod support;

use std::fs::File;

use truetype::tables::FontHeader;
use truetype::value::Read;
use truetype::tape::Read as TapeRead;
use truetype::value::Read as ValueRead;

#[test]
fn checksum() {
let path = support::Fixture::SourceSerif.path();
let mut file = ok!(File::open(path));
ok!(file.jump(support::Fixture::SourceSerif.offset("head")));
let table = ok!(FontHeader::read(&mut file));
ok!(file.jump(0));
assert_eq!(ok!(table.checksum(&mut file)), 0);
}

#[test]
fn read() {
Expand Down

0 comments on commit 67e6292

Please sign in to comment.