Skip to content

Commit

Permalink
(cmap) cmap::Subtable::glyph_index and `cmap::Subtable::glyph_varia…
Browse files Browse the repository at this point in the history
…tion_index` accept `u32` instead of `char` now.

Closes #78
  • Loading branch information
RazrFalcon committed Dec 28, 2021
1 parent 933d292 commit 95fbb36
Show file tree
Hide file tree
Showing 12 changed files with 75 additions and 74 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]
### Changed
- (cmap) `cmap::Subtable::glyph_index` and `cmap::Subtable::glyph_variation_index` accept
`u32` instead of `char` now.
- (glyf) ~7% faster outline parsing.

## [0.13.4] - 2021-11-23
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Expand Up @@ -1273,7 +1273,7 @@ impl<'a> Face<'a> {
continue;
}

if let Some(id) = encoding.glyph_index(code_point) {
if let Some(id) = encoding.glyph_index(u32::from(code_point)) {
return Some(id);
}
}
Expand All @@ -1292,7 +1292,7 @@ impl<'a> Face<'a> {
pub fn glyph_variation_index(&self, code_point: char, variation: char) -> Option<GlyphId> {
for subtable in self.tables.cmap?.subtables {
if let cmap::Format::UnicodeVariationSequences(ref table) = subtable.format {
return match table.glyph_index(code_point, variation)? {
return match table.glyph_index(u32::from(code_point), u32::from(variation))? {
cmap::GlyphVariationResult::Found(v) => Some(v),
cmap::GlyphVariationResult::UseDefault => self.glyph_index(code_point),
};
Expand Down
2 changes: 1 addition & 1 deletion src/tables/cmap/format0.rs
Expand Up @@ -21,7 +21,7 @@ impl<'a> Subtable0<'a> {
}

/// Returns a glyph index for a code point.
pub fn glyph_index(&self, code_point: char) -> Option<GlyphId> {
pub fn glyph_index(&self, code_point: u32) -> Option<GlyphId> {
let glyph_id = *self.glyph_ids.get(usize::num_from(code_point))?;
// Make sure that the glyph is not zero, the array always has 256 ids,
// but some codepoints may be mapped to zero.
Expand Down
4 changes: 2 additions & 2 deletions src/tables/cmap/format10.rs
Expand Up @@ -26,8 +26,8 @@ impl<'a> Subtable10<'a> {
}

/// Returns a glyph index for a code point.
pub fn glyph_index(&self, code_point: char) -> Option<GlyphId> {
let idx = u32::from(code_point).checked_sub(self.first_code_point)?;
pub fn glyph_index(&self, code_point: u32) -> Option<GlyphId> {
let idx = code_point.checked_sub(self.first_code_point)?;
self.glyphs.get(idx)
}

Expand Down
4 changes: 1 addition & 3 deletions src/tables/cmap/format12.rs
Expand Up @@ -46,9 +46,7 @@ impl<'a> Subtable12<'a> {
}

/// Returns a glyph index for a code point.
pub fn glyph_index(&self, code_point: char) -> Option<GlyphId> {
let code_point = u32::from(code_point);

pub fn glyph_index(&self, code_point: u32) -> Option<GlyphId> {
let (_, group) = self.groups.binary_search_by(|range| {
use core::cmp::Ordering;

Expand Down
3 changes: 1 addition & 2 deletions src/tables/cmap/format13.rs
Expand Up @@ -27,8 +27,7 @@ impl<'a> Subtable13<'a> {
}

/// Returns a glyph index for a code point.
pub fn glyph_index(&self, code_point: char) -> Option<GlyphId> {
let code_point = u32::from(code_point);
pub fn glyph_index(&self, code_point: u32) -> Option<GlyphId> {
for group in self.groups {
let start_char_code = group.start_char_code;
if code_point >= start_char_code && code_point <= group.end_char_code {
Expand Down
4 changes: 1 addition & 3 deletions src/tables/cmap/format14.rs
Expand Up @@ -105,9 +105,7 @@ impl<'a> Subtable14<'a> {
}

/// Returns a glyph index for a code point.
pub fn glyph_index(&self, code_point: char, variation: char) -> Option<GlyphVariationResult> {
let code_point = u32::from(code_point);
let variation = u32::from(variation);
pub fn glyph_index(&self, code_point: u32, variation: u32) -> Option<GlyphVariationResult> {
let (_, record) = self.records.binary_search_by(|v| v.var_selector.cmp(&variation))?;

if let Some(offset) = record.default_uvs_offset {
Expand Down
6 changes: 4 additions & 2 deletions src/tables/cmap/format2.rs
Expand Up @@ -67,9 +67,11 @@ impl<'a> Subtable2<'a> {
}

/// Returns a glyph index for a code point.
pub fn glyph_index(&self, code_point: char) -> Option<GlyphId> {
///
/// Returns `None` when `code_point` is larger than `u16`.
pub fn glyph_index(&self, code_point: u32) -> Option<GlyphId> {
// This subtable supports code points only in a u16 range.
let code_point = u16::try_from(code_point as u32).ok()?;
let code_point = u16::try_from(code_point).ok()?;

let code_point = code_point;
let high_byte = code_point >> 8;
Expand Down
6 changes: 4 additions & 2 deletions src/tables/cmap/format4.rs
Expand Up @@ -47,9 +47,11 @@ impl<'a> Subtable4<'a> {
}

/// Returns a glyph index for a code point.
pub fn glyph_index(&self, code_point: char) -> Option<GlyphId> {
///
/// Returns `None` when `code_point` is larger than `u16`.
pub fn glyph_index(&self, code_point: u32) -> Option<GlyphId> {
// This subtable supports code points only in a u16 range.
let code_point = u16::try_from(code_point as u32).ok()?;
let code_point = u16::try_from(code_point).ok()?;

// A custom binary search.
let mut start = 0;
Expand Down
10 changes: 5 additions & 5 deletions src/tables/cmap/format6.rs
Expand Up @@ -27,9 +27,11 @@ impl<'a> Subtable6<'a> {
}

/// Returns a glyph index for a code point.
pub fn glyph_index(&self, code_point: char) -> Option<GlyphId> {
///
/// Returns `None` when `code_point` is larger than `u16`.
pub fn glyph_index(&self, code_point: u32) -> Option<GlyphId> {
// This subtable supports code points only in a u16 range.
let code_point = u16::try_from(code_point as u32).ok()?;
let code_point = u16::try_from(code_point).ok()?;
let idx = code_point.checked_sub(self.first_code_point)?;
self.glyphs.get(idx)
}
Expand All @@ -38,9 +40,7 @@ impl<'a> Subtable6<'a> {
pub fn codepoints(&self, mut f: impl FnMut(u32)) {
for i in 0..self.glyphs.len() {
if let Some(code_point) = self.first_code_point.checked_add(i) {
if let Ok(c) = u32::try_from(code_point) {
f(c);
}
f(u32::from(code_point));
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/tables/cmap/mod.rs
Expand Up @@ -94,7 +94,7 @@ impl<'a> Subtable<'a> {
/// - when format is `MixedCoverage`, since it's not supported.
/// - when format is `UnicodeVariationSequences`. Use `glyph_variation_index` instead.
#[inline]
pub fn glyph_index(&self, code_point: char) -> Option<GlyphId> {
pub fn glyph_index(&self, code_point: u32) -> Option<GlyphId> {
match self.format {
Format::ByteEncodingTable(ref subtable) => subtable.glyph_index(code_point),
Format::HighByteMappingThroughTable(ref subtable) => subtable.glyph_index(code_point),
Expand All @@ -115,7 +115,7 @@ impl<'a> Subtable<'a> {
/// - when glyph ID is `0`.
/// - when format is not `UnicodeVariationSequences`.
#[inline]
pub fn glyph_variation_index(&self, code_point: char, variation: char) -> Option<GlyphVariationResult> {
pub fn glyph_variation_index(&self, code_point: u32, variation: u32) -> Option<GlyphVariationResult> {
match self.format {
Format::UnicodeVariationSequences(ref subtable) => {
subtable.glyph_index(code_point, variation)
Expand Down
100 changes: 50 additions & 50 deletions tests/tables/cmap.rs
Expand Up @@ -15,9 +15,9 @@ mod format0 {

let subtable = cmap::Subtable0::parse(&data).unwrap();

assert_eq!(subtable.glyph_index(0 as char), None);
assert_eq!(subtable.glyph_index(0x40 as char), Some(GlyphId(100)));
assert_eq!(subtable.glyph_index(100 as char), None);
assert_eq!(subtable.glyph_index(0), None);
assert_eq!(subtable.glyph_index(0x40), Some(GlyphId(100)));
assert_eq!(subtable.glyph_index(100), None);

let mut vec = vec![];
subtable.codepoints(|c| vec.push(c));
Expand Down Expand Up @@ -85,10 +85,10 @@ mod format2 {
]);

let subtable = cmap::Subtable2::parse(&data).unwrap();
assert_eq!(subtable.glyph_index(39 as char), None);
assert_eq!(subtable.glyph_index(40 as char), Some(GlyphId(100)));
assert_eq!(subtable.glyph_index(41 as char), Some(GlyphId(1000)));
assert_eq!(subtable.glyph_index(42 as char), None);
assert_eq!(subtable.glyph_index(39), None);
assert_eq!(subtable.glyph_index(40), Some(GlyphId(100)));
assert_eq!(subtable.glyph_index(41), Some(GlyphId(1000)));
assert_eq!(subtable.glyph_index(42), None);
}
}

Expand Down Expand Up @@ -121,8 +121,8 @@ mod format4 {
];

let subtable = cmap::Subtable4::parse(data).unwrap();
assert_eq!(subtable.glyph_index(0x41 as char), Some(GlyphId(1)));
assert_eq!(subtable.glyph_index(0x42 as char), None);
assert_eq!(subtable.glyph_index(0x41), Some(GlyphId(1)));
assert_eq!(subtable.glyph_index(0x42), None);
}

#[test]
Expand Down Expand Up @@ -151,17 +151,17 @@ mod format4 {
];

let subtable = cmap::Subtable4::parse(data).unwrap();
assert_eq!(subtable.glyph_index(0x40 as char), None);
assert_eq!(subtable.glyph_index(0x41 as char), Some(GlyphId(1)));
assert_eq!(subtable.glyph_index(0x42 as char), Some(GlyphId(2)));
assert_eq!(subtable.glyph_index(0x43 as char), Some(GlyphId(3)));
assert_eq!(subtable.glyph_index(0x44 as char), Some(GlyphId(4)));
assert_eq!(subtable.glyph_index(0x45 as char), Some(GlyphId(5)));
assert_eq!(subtable.glyph_index(0x46 as char), Some(GlyphId(6)));
assert_eq!(subtable.glyph_index(0x47 as char), Some(GlyphId(7)));
assert_eq!(subtable.glyph_index(0x48 as char), Some(GlyphId(8)));
assert_eq!(subtable.glyph_index(0x49 as char), Some(GlyphId(9)));
assert_eq!(subtable.glyph_index(0x4A as char), None);
assert_eq!(subtable.glyph_index(0x40), None);
assert_eq!(subtable.glyph_index(0x41), Some(GlyphId(1)));
assert_eq!(subtable.glyph_index(0x42), Some(GlyphId(2)));
assert_eq!(subtable.glyph_index(0x43), Some(GlyphId(3)));
assert_eq!(subtable.glyph_index(0x44), Some(GlyphId(4)));
assert_eq!(subtable.glyph_index(0x45), Some(GlyphId(5)));
assert_eq!(subtable.glyph_index(0x46), Some(GlyphId(6)));
assert_eq!(subtable.glyph_index(0x47), Some(GlyphId(7)));
assert_eq!(subtable.glyph_index(0x48), Some(GlyphId(8)));
assert_eq!(subtable.glyph_index(0x49), Some(GlyphId(9)));
assert_eq!(subtable.glyph_index(0x4A), None);
}

#[test]
Expand Down Expand Up @@ -198,17 +198,17 @@ mod format4 {
];

let subtable = cmap::Subtable4::parse(data).unwrap();
assert_eq!(subtable.glyph_index(0x40 as char), None);
assert_eq!(subtable.glyph_index(0x41 as char), Some(GlyphId(1)));
assert_eq!(subtable.glyph_index(0x42 as char), None);
assert_eq!(subtable.glyph_index(0x43 as char), Some(GlyphId(2)));
assert_eq!(subtable.glyph_index(0x44 as char), Some(GlyphId(3)));
assert_eq!(subtable.glyph_index(0x45 as char), Some(GlyphId(4)));
assert_eq!(subtable.glyph_index(0x46 as char), None);
assert_eq!(subtable.glyph_index(0x47 as char), Some(GlyphId(5)));
assert_eq!(subtable.glyph_index(0x48 as char), Some(GlyphId(6)));
assert_eq!(subtable.glyph_index(0x49 as char), Some(GlyphId(7)));
assert_eq!(subtable.glyph_index(0x4A as char), None);
assert_eq!(subtable.glyph_index(0x40), None);
assert_eq!(subtable.glyph_index(0x41), Some(GlyphId(1)));
assert_eq!(subtable.glyph_index(0x42), None);
assert_eq!(subtable.glyph_index(0x43), Some(GlyphId(2)));
assert_eq!(subtable.glyph_index(0x44), Some(GlyphId(3)));
assert_eq!(subtable.glyph_index(0x45), Some(GlyphId(4)));
assert_eq!(subtable.glyph_index(0x46), None);
assert_eq!(subtable.glyph_index(0x47), Some(GlyphId(5)));
assert_eq!(subtable.glyph_index(0x48), Some(GlyphId(6)));
assert_eq!(subtable.glyph_index(0x49), Some(GlyphId(7)));
assert_eq!(subtable.glyph_index(0x4A), None);
}

#[test]
Expand Down Expand Up @@ -243,13 +243,13 @@ mod format4 {
];

let subtable = cmap::Subtable4::parse(data).unwrap();
assert_eq!(subtable.glyph_index(0x40 as char), None);
assert_eq!(subtable.glyph_index(0x41 as char), Some(GlyphId(1)));
assert_eq!(subtable.glyph_index(0x42 as char), Some(GlyphId(10)));
assert_eq!(subtable.glyph_index(0x43 as char), Some(GlyphId(100)));
assert_eq!(subtable.glyph_index(0x44 as char), Some(GlyphId(1000)));
assert_eq!(subtable.glyph_index(0x45 as char), Some(GlyphId(10000)));
assert_eq!(subtable.glyph_index(0x46 as char), None);
assert_eq!(subtable.glyph_index(0x40), None);
assert_eq!(subtable.glyph_index(0x41), Some(GlyphId(1)));
assert_eq!(subtable.glyph_index(0x42), Some(GlyphId(10)));
assert_eq!(subtable.glyph_index(0x43), Some(GlyphId(100)));
assert_eq!(subtable.glyph_index(0x44), Some(GlyphId(1000)));
assert_eq!(subtable.glyph_index(0x45), Some(GlyphId(10000)));
assert_eq!(subtable.glyph_index(0x46), None);
}

#[test]
Expand Down Expand Up @@ -294,13 +294,13 @@ mod format4 {
];

let subtable = cmap::Subtable4::parse(data).unwrap();
assert_eq!(subtable.glyph_index(0x40 as char), None);
assert_eq!(subtable.glyph_index(0x50 as char), Some(GlyphId(1)));
assert_eq!(subtable.glyph_index(std::char::from_u32(0x100).unwrap()), Some(GlyphId(10)));
assert_eq!(subtable.glyph_index(std::char::from_u32(0x150).unwrap()), Some(GlyphId(100)));
assert_eq!(subtable.glyph_index(std::char::from_u32(0x200).unwrap()), Some(GlyphId(1000)));
assert_eq!(subtable.glyph_index(std::char::from_u32(0x250).unwrap()), Some(GlyphId(10000)));
assert_eq!(subtable.glyph_index(std::char::from_u32(0x300).unwrap()), None);
assert_eq!(subtable.glyph_index(0x40), None);
assert_eq!(subtable.glyph_index(0x50), Some(GlyphId(1)));
assert_eq!(subtable.glyph_index(0x100), Some(GlyphId(10)));
assert_eq!(subtable.glyph_index(0x150), Some(GlyphId(100)));
assert_eq!(subtable.glyph_index(0x200), Some(GlyphId(1000)));
assert_eq!(subtable.glyph_index(0x250), Some(GlyphId(10000)));
assert_eq!(subtable.glyph_index(0x300), None);
}

#[test]
Expand Down Expand Up @@ -384,7 +384,7 @@ mod format4 {

let subtable = cmap::Subtable4::parse(data).unwrap();
// Should not loop forever.
assert_eq!(subtable.glyph_index(0x41 as char), None);
assert_eq!(subtable.glyph_index(0x41), None);
}

#[test]
Expand Down Expand Up @@ -413,8 +413,8 @@ mod format4 {
];

let subtable = cmap::Subtable4::parse(data).unwrap();
assert_eq!(subtable.glyph_index(0x41 as char), Some(GlyphId(1)));
assert_eq!(subtable.glyph_index(0x42 as char), None);
assert_eq!(subtable.glyph_index(0x41), Some(GlyphId(1)));
assert_eq!(subtable.glyph_index(0x42), None);
}

#[test]
Expand Down Expand Up @@ -444,7 +444,7 @@ mod format4 {

let subtable = cmap::Subtable4::parse(data).unwrap();
// Format 4 support only u16 codepoints, so we have to bail immediately otherwise.
assert_eq!(subtable.glyph_index(std::char::from_u32(0x1FFFF).unwrap()), None);
assert_eq!(subtable.glyph_index(0x1FFFF), None);
}

#[test]
Expand Down Expand Up @@ -479,7 +479,7 @@ mod format4 {
];

let subtable = cmap::Subtable4::parse(data).unwrap();
assert_eq!(subtable.glyph_index(0x41 as char), None);
assert_eq!(subtable.glyph_index(0x41), None);
}

#[test]
Expand Down

0 comments on commit 95fbb36

Please sign in to comment.