From 642af903a22eaba89e49c97385a1ab8dda8a4148 Mon Sep 17 00:00:00 2001 From: Yevhenii Reizner Date: Wed, 28 Sep 2022 11:15:32 +0300 Subject: [PATCH] Reformat code. --- benches/methods_perf.rs | 33 +-- benches/methods_perf_x1000.rs | 3 +- examples/font-info.rs | 22 +- examples/font2svg.rs | 22 +- src/aat.rs | 70 ++--- src/ggg/chained_context.rs | 9 +- src/ggg/context.rs | 2 +- src/ggg/feature_variations.rs | 26 +- src/ggg/layout_table.rs | 78 ++++-- src/ggg/lookup.rs | 11 +- src/ggg/mod.rs | 42 +-- src/lib.rs | 427 +++++++++++++++++++---------- src/parser.rs | 69 +++-- src/tables/ankr.rs | 6 +- src/tables/avar.rs | 4 +- src/tables/cbdt.rs | 4 +- src/tables/cblc.rs | 21 +- src/tables/cff/cff1.rs | 197 +++++++------ src/tables/cff/cff2.rs | 116 ++++---- src/tables/cff/charset.rs | 42 +-- src/tables/cff/charstring.rs | 24 +- src/tables/cff/dict.rs | 46 +++- src/tables/cff/encoding.rs | 23 +- src/tables/cff/index.rs | 38 ++- src/tables/cff/mod.rs | 39 +-- src/tables/cmap/format0.rs | 2 +- src/tables/cmap/format10.rs | 5 +- src/tables/cmap/format12.rs | 6 +- src/tables/cmap/format13.rs | 2 +- src/tables/cmap/format14.rs | 13 +- src/tables/cmap/format2.rs | 7 +- src/tables/cmap/format4.rs | 3 +- src/tables/cmap/format6.rs | 5 +- src/tables/cmap/mod.rs | 48 ++-- src/tables/feat.rs | 22 +- src/tables/fvar.rs | 5 +- src/tables/gdef.rs | 28 +- src/tables/glyf.rs | 104 +++---- src/tables/gpos.rs | 172 +++++++----- src/tables/gsub.rs | 12 +- src/tables/gvar.rs | 502 +++++++++++++++++++++++++--------- src/tables/head.rs | 12 +- src/tables/hhea.rs | 2 +- src/tables/hmtx.rs | 6 +- src/tables/hvar.rs | 13 +- src/tables/kern.rs | 38 +-- src/tables/kerx.rs | 47 ++-- src/tables/loca.rs | 16 +- src/tables/math.rs | 97 ++++--- src/tables/maxp.rs | 4 +- src/tables/mod.rs | 45 ++- src/tables/morx.rs | 27 +- src/tables/mvar.rs | 7 +- src/tables/name.rs | 82 +++--- src/tables/os2.rs | 48 ++-- src/tables/post.rs | 31 ++- src/tables/sbix.rs | 13 +- src/tables/svg.rs | 16 +- src/tables/trak.rs | 5 +- src/tables/vhea.rs | 2 +- src/tables/vorg.rs | 11 +- src/var_store.rs | 19 +- tests/tables/main.rs | 97 ++++--- 63 files changed, 1779 insertions(+), 1169 deletions(-) diff --git a/benches/methods_perf.rs b/benches/methods_perf.rs index 2780597f..2d1fab46 100644 --- a/benches/methods_perf.rs +++ b/benches/methods_perf.rs @@ -24,50 +24,38 @@ fn from_data_otf_cff2(bencher: &mut bencher::Bencher) { fn outline_glyph_8_from_glyf(bencher: &mut bencher::Bencher) { let font_data = std::fs::read("fonts/SourceSansPro-Regular.ttf").unwrap(); let face = ttf::Face::parse(&font_data, 0).unwrap(); - bencher.iter(|| { - face.outline_glyph(ttf::GlyphId(8), &mut Builder(0)) - }) + bencher.iter(|| face.outline_glyph(ttf::GlyphId(8), &mut Builder(0))) } fn outline_glyph_276_from_glyf(bencher: &mut bencher::Bencher) { let font_data = std::fs::read("fonts/SourceSansPro-Regular.ttf").unwrap(); let face = ttf::Face::parse(&font_data, 0).unwrap(); let mut b = Builder(0); - bencher.iter(|| { - face.outline_glyph(ttf::GlyphId(276), &mut b) - }) + bencher.iter(|| face.outline_glyph(ttf::GlyphId(276), &mut b)) } fn outline_glyph_8_from_cff(bencher: &mut bencher::Bencher) { let font_data = std::fs::read("fonts/SourceSansPro-Regular.otf").unwrap(); let face = ttf::Face::parse(&font_data, 0).unwrap(); - bencher.iter(|| { - face.outline_glyph(ttf::GlyphId(8), &mut Builder(0)) - }) + bencher.iter(|| face.outline_glyph(ttf::GlyphId(8), &mut Builder(0))) } fn outline_glyph_276_from_cff(bencher: &mut bencher::Bencher) { let font_data = std::fs::read("fonts/SourceSansPro-Regular.otf").unwrap(); let face = ttf::Face::parse(&font_data, 0).unwrap(); - bencher.iter(|| { - face.outline_glyph(ttf::GlyphId(276), &mut Builder(0)) - }) + bencher.iter(|| face.outline_glyph(ttf::GlyphId(276), &mut Builder(0))) } fn outline_glyph_8_from_cff2(bencher: &mut bencher::Bencher) { let font_data = std::fs::read("fonts/SourceSansVariable-Roman.otf").unwrap(); let face = ttf::Face::parse(&font_data, 0).unwrap(); - bencher.iter(|| { - face.outline_glyph(ttf::GlyphId(8), &mut Builder(0)) - }) + bencher.iter(|| face.outline_glyph(ttf::GlyphId(8), &mut Builder(0))) } fn outline_glyph_276_from_cff2(bencher: &mut bencher::Bencher) { let font_data = std::fs::read("fonts/SourceSansVariable-Roman.otf").unwrap(); let face = ttf::Face::parse(&font_data, 0).unwrap(); - bencher.iter(|| { - face.outline_glyph(ttf::GlyphId(276), &mut Builder(0)) - }) + bencher.iter(|| face.outline_glyph(ttf::GlyphId(276), &mut Builder(0))) } fn family_name(bencher: &mut bencher::Bencher) { @@ -75,8 +63,10 @@ fn family_name(bencher: &mut bencher::Bencher) { let face = ttf::Face::parse(&font_data, 0).unwrap(); bencher.iter(|| { bencher::black_box( - face.names().into_iter().find(|name| name.name_id == ttf::name_id::FULL_NAME) - .and_then(|name| name.to_string()) + face.names() + .into_iter() + .find(|name| name.name_id == ttf::name_id::FULL_NAME) + .and_then(|name| name.to_string()), ); }) } @@ -154,7 +144,8 @@ impl ttf_parser::OutlineBuilder for Builder { } } -bencher::benchmark_group!(perf, +bencher::benchmark_group!( + perf, from_data_ttf, from_data_otf_cff, from_data_otf_cff2, diff --git a/benches/methods_perf_x1000.rs b/benches/methods_perf_x1000.rs index 8490d881..c898b7de 100644 --- a/benches/methods_perf_x1000.rs +++ b/benches/methods_perf_x1000.rs @@ -90,7 +90,8 @@ fn glyph_hor_side_bearing(bencher: &mut bencher::Bencher) { }) } -bencher::benchmark_group!(perf, +bencher::benchmark_group!( + perf, units_per_em, width, ascender, diff --git a/examples/font-info.rs b/examples/font-info.rs index 7fd8fe48..7f974c07 100644 --- a/examples/font-info.rs +++ b/examples/font-info.rs @@ -14,14 +14,18 @@ fn main() { Err(e) => { eprint!("Error: {}.", e); std::process::exit(1); - }, + } }; - let family_name = face.names().into_iter() + let family_name = face + .names() + .into_iter() .find(|name| name.name_id == ttf_parser::name_id::FULL_NAME && name.is_unicode()) .and_then(|name| name.to_string()); - let post_script_name = face.names().into_iter() + let post_script_name = face + .names() + .into_iter() .find(|name| name.name_id == ttf_parser::name_id::POST_SCRIPT_NAME && name.is_unicode()) .and_then(|name| name.to_string()); @@ -46,7 +50,8 @@ fn main() { println!("Superscript: {:?}", face.superscript_metrics()); println!("Variable: {:?}", face.is_variable()); - #[cfg(feature = "opentype-layout")] { + #[cfg(feature = "opentype-layout")] + { if let Some(ref table) = face.tables().gpos { print_opentype_layout("positioning", table); } @@ -56,12 +61,15 @@ fn main() { } } - #[cfg(feature = "variable-fonts")] { + #[cfg(feature = "variable-fonts")] + { if face.is_variable() { println!("Variation axes:"); for axis in face.variation_axes() { - println!(" {} {}..{}, default {}", - axis.tag, axis.min_value, axis.max_value, axis.def_value); + println!( + " {} {}..{}, default {}", + axis.tag, axis.min_value, axis.max_value, axis.def_value + ); } } } diff --git a/examples/font2svg.rs b/examples/font2svg.rs index 19635ff6..83185604 100644 --- a/examples/font2svg.rs +++ b/examples/font2svg.rs @@ -1,5 +1,5 @@ -use std::path::PathBuf; use std::io::Write; +use std::path::PathBuf; use ttf_parser as ttf; @@ -13,7 +13,8 @@ Usage: "; struct Args { - #[allow(dead_code)] variations: Vec, + #[allow(dead_code)] + variations: Vec, ttf_path: PathBuf, svg_path: PathBuf, } @@ -81,7 +82,8 @@ fn process(args: Args) -> Result<(), Box> { #[allow(unused_mut)] let mut face = ttf::Face::parse(&font_data, 0)?; if face.is_variable() { - #[cfg(feature = "variable-fonts")] { + #[cfg(feature = "variable-fonts")] + { for variation in args.variations { face.set_variation(variation.axis, variation.value) .ok_or("failed to create variation coordinates")?; @@ -104,7 +106,13 @@ fn process(args: Args) -> Result<(), Box> { svg.write_attribute("xmlns:xlink", "http://www.w3.org/1999/xlink"); svg.write_attribute_fmt( "viewBox", - format_args!("{} {} {} {}", 0, 0, cell_size * COLUMNS as f64, cell_size * rows as f64), + format_args!( + "{} {} {} {}", + 0, + 0, + cell_size * COLUMNS as f64, + cell_size * rows as f64 + ), ); draw_grid(face.number_of_glyphs(), cell_size, &mut svg); @@ -179,11 +187,7 @@ fn process(args: Args) -> Result<(), Box> { Ok(()) } -fn draw_grid( - n_glyphs: u16, - cell_size: f64, - svg: &mut xmlwriter::XmlWriter, -) { +fn draw_grid(n_glyphs: u16, cell_size: f64, svg: &mut xmlwriter::XmlWriter) { let columns = COLUMNS; let rows = (n_glyphs as f64 / columns as f64).ceil() as u32; diff --git a/src/aat.rs b/src/aat.rs index ebe8d95b..123f0e2f 100644 --- a/src/aat.rs +++ b/src/aat.rs @@ -6,8 +6,8 @@ related types. use core::num::NonZeroU16; +use crate::parser::{FromData, LazyArray16, NumFrom, Offset, Offset16, Offset32, Stream}; use crate::GlyphId; -use crate::parser::{Stream, FromData, LazyArray16, Offset, Offset16, Offset32, NumFrom}; /// Predefined states. pub mod state { @@ -188,9 +188,9 @@ impl<'a> StateTable<'a> { class = class::OUT_OF_BOUNDS as u8; } - let entry_idx = self.state_array.get( - usize::from(state) * usize::from(self.number_of_classes) + usize::from(class) - )?; + let entry_idx = self + .state_array + .get(usize::from(state) * usize::from(self.number_of_classes) + usize::from(class))?; Stream::read_at(self.entry_table, usize::from(*entry_idx) * StateEntry::SIZE) } @@ -218,7 +218,6 @@ impl core::fmt::Debug for StateTable<'_> { } } - /// An [Extended State Table]( /// https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6Tables.html). /// @@ -283,7 +282,10 @@ impl<'a, T: FromData> ExtendedStateTable<'a, T> { usize::from(state) * usize::num_from(self.number_of_classes) + usize::from(class); let entry_idx: u16 = Stream::read_at(self.state_array, state_idx * u16::SIZE)?; - Stream::read_at(self.entry_table, usize::from(entry_idx) * GenericStateEntry::::SIZE) + Stream::read_at( + self.entry_table, + usize::from(entry_idx) * GenericStateEntry::::SIZE, + ) } } @@ -293,7 +295,6 @@ impl core::fmt::Debug for ExtendedStateTable<'_, T> { } } - /// A [lookup table]( /// https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6Tables.html). /// @@ -326,7 +327,6 @@ impl core::fmt::Debug for Lookup<'_> { } } - #[derive(Clone)] enum LookupInner<'a> { Format1(LazyArray16<'a, u16>), @@ -335,7 +335,7 @@ enum LookupInner<'a> { Format6(BinarySearchTable<'a, LookupSingle>), Format8 { first_glyph: u16, - values: LazyArray16<'a, u16> + values: LazyArray16<'a, u16>, }, Format10 { value_size: u16, @@ -370,28 +370,30 @@ impl<'a> LookupInner<'a> { let first_glyph = s.read::()?; let glyph_count = s.read::()?; let values = s.read_array16::(glyph_count)?; - Some(Self::Format8 { first_glyph, values }) + Some(Self::Format8 { + first_glyph, + values, + }) } 10 => { let value_size = s.read::()?; let first_glyph = s.read::()?; let glyph_count = s.read::()?; - Some(Self::Format10 { value_size, first_glyph, glyph_count, data: s.tail()? }) - } - _ => { - None + Some(Self::Format10 { + value_size, + first_glyph, + glyph_count, + data: s.tail()?, + }) } + _ => None, } } fn value(&self, glyph_id: GlyphId) -> Option { match self { - Self::Format1(values) => { - values.get(glyph_id.0) - } - Self::Format2(ref bsearch) => { - bsearch.get(glyph_id).map(|v| v.value) - } + Self::Format1(values) => values.get(glyph_id.0), + Self::Format2(ref bsearch) => bsearch.get(glyph_id).map(|v| v.value), Self::Format4(ref bsearch, data) => { // In format 4, LookupSegment contains an offset to a list of u16 values. // One value for each glyph in the LookupSegment range. @@ -400,21 +402,30 @@ impl<'a> LookupInner<'a> { let offset = usize::from(segment.value) + u16::SIZE * usize::from(index); Stream::read_at::(data, offset) } - Self::Format6(ref bsearch) => { - bsearch.get(glyph_id).map(|v| v.value) - } - Self::Format8 { first_glyph, values } => { + Self::Format6(ref bsearch) => bsearch.get(glyph_id).map(|v| v.value), + Self::Format8 { + first_glyph, + values, + } => { let idx = glyph_id.0.checked_sub(*first_glyph)?; values.get(idx) } - Self::Format10 { value_size, first_glyph, glyph_count, data } => { + Self::Format10 { + value_size, + first_glyph, + glyph_count, + data, + } => { let idx = glyph_id.0.checked_sub(*first_glyph)?; let mut s = Stream::new(data); match value_size { 1 => s.read_array16::(*glyph_count)?.get(idx).map(u16::from), 2 => s.read_array16::(*glyph_count)?.get(idx), // TODO: we should return u32 here, but this is not supported yet - 4 => s.read_array16::(*glyph_count)?.get(idx).map(|n| n as u16), + 4 => s + .read_array16::(*glyph_count)? + .get(idx) + .map(|n| n as u16), _ => None, // 8 is also supported } } @@ -468,9 +479,9 @@ impl<'a, T: BinarySearchValue + core::fmt::Debug> BinarySearchTable<'a, T> { let mid = (min + max) / 2; let v = self.values.get(mid as u16)?; match v.contains(key) { - core::cmp::Ordering::Less => max = mid - 1, + core::cmp::Ordering::Less => max = mid - 1, core::cmp::Ordering::Greater => min = mid + 1, - core::cmp::Ordering::Equal => return Some(v), + core::cmp::Ordering::Equal => return Some(v), } } @@ -478,13 +489,11 @@ impl<'a, T: BinarySearchValue + core::fmt::Debug> BinarySearchTable<'a, T> { } } - trait BinarySearchValue: FromData { fn is_termination(&self) -> bool; fn contains(&self, glyph_id: GlyphId) -> core::cmp::Ordering; } - #[derive(Clone, Copy, Debug)] struct LookupSegment { last_glyph: u16, @@ -524,7 +533,6 @@ impl BinarySearchValue for LookupSegment { } } - #[derive(Clone, Copy, Debug)] struct LookupSingle { glyph: u16, diff --git a/src/ggg/chained_context.rs b/src/ggg/chained_context.rs index 1d2eb2c1..8cf6f10f 100644 --- a/src/ggg/chained_context.rs +++ b/src/ggg/chained_context.rs @@ -1,5 +1,5 @@ -use crate::parser::{FromSlice, LazyArray16, LazyOffsetArray16, Stream}; use super::{ClassDefinition, Coverage, SequenceLookupRecord}; +use crate::parser::{FromSlice, LazyArray16, LazyOffsetArray16, Stream}; /// A [Chained Contextual Lookup Subtable]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#chseqctxt1). @@ -125,6 +125,11 @@ impl<'a> FromSlice<'a> for ChainedSequenceRule<'a> { let lookahead = s.read_array16(lookahead_count)?; let lookup_count = s.read::()?; let lookups = s.read_array16(lookup_count)?; - Some(Self { backtrack, input, lookahead, lookups }) + Some(Self { + backtrack, + input, + lookahead, + lookups, + }) } } diff --git a/src/ggg/context.rs b/src/ggg/context.rs index 10d99d0b..7d5d6a6d 100644 --- a/src/ggg/context.rs +++ b/src/ggg/context.rs @@ -1,5 +1,5 @@ -use crate::parser::{FromData, FromSlice, LazyArray16, LazyOffsetArray16, Stream}; use super::{ClassDefinition, Coverage, LookupIndex}; +use crate::parser::{FromData, FromSlice, LazyArray16, LazyOffsetArray16, Stream}; /// A [Contextual Lookup Subtable]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#seqctxt1). diff --git a/src/ggg/feature_variations.rs b/src/ggg/feature_variations.rs index ea0c25b5..c959e47f 100644 --- a/src/ggg/feature_variations.rs +++ b/src/ggg/feature_variations.rs @@ -1,7 +1,7 @@ -use crate::{NormalizedCoordinate, Tag}; +use super::{Feature, FeatureIndex, RecordListItem, VariationIndex}; use crate::parser::{FromData, LazyArray16, LazyArray32}; use crate::parser::{Offset, Offset32, Stream}; -use super::{Feature, FeatureIndex, VariationIndex, RecordListItem}; +use crate::{NormalizedCoordinate, Tag}; /// A [Feature Variations Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#featurevariations-table). #[derive(Clone, Copy, Debug)] @@ -84,7 +84,8 @@ impl<'a> ConditionSet<'a> { fn evaluate(&self, coords: &[NormalizedCoordinate]) -> bool { self.conditions.into_iter().all(|offset| { - self.data.get(offset.to_usize()..) + self.data + .get(offset.to_usize()..) .and_then(Condition::parse) .map_or(false, |c| c.evaluate(coords)) }) @@ -97,7 +98,7 @@ enum Condition { axis_index: u16, filter_range_min: i16, filter_range_max: i16, - } + }, } impl Condition { @@ -109,15 +110,26 @@ impl Condition { let axis_index = s.read::()?; let filter_range_min = s.read::()?; let filter_range_max = s.read::()?; - Some(Self::Format1 { axis_index, filter_range_min, filter_range_max }) + Some(Self::Format1 { + axis_index, + filter_range_min, + filter_range_max, + }) } _ => None, } } fn evaluate(&self, coords: &[NormalizedCoordinate]) -> bool { - let Self::Format1 { axis_index, filter_range_min, filter_range_max } = *self; - let coord = coords.get(usize::from(axis_index)).map(|c| c.get()).unwrap_or(0); + let Self::Format1 { + axis_index, + filter_range_min, + filter_range_max, + } = *self; + let coord = coords + .get(usize::from(axis_index)) + .map(|c| c.get()) + .unwrap_or(0); filter_range_min <= coord && coord <= filter_range_max } } diff --git a/src/ggg/layout_table.rs b/src/ggg/layout_table.rs index dd88fac5..1eb6a072 100644 --- a/src/ggg/layout_table.rs +++ b/src/ggg/layout_table.rs @@ -1,11 +1,13 @@ // Suppresses `minor_version` variable warning. #![allow(unused_variables)] +#[cfg(feature = "variable-fonts")] +use super::FeatureVariations; use super::LookupList; +#[cfg(feature = "variable-fonts")] +use crate::parser::Offset32; use crate::parser::{FromData, LazyArray16, Offset, Offset16, Stream}; use crate::Tag; -#[cfg(feature = "variable-fonts")] use super::FeatureVariations; -#[cfg(feature = "variable-fonts")] use crate::parser::Offset32; /// A [Layout Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#table-organization). #[derive(Clone, Copy, Debug)] @@ -36,22 +38,35 @@ impl<'a> LayoutTable<'a> { let features = FeatureList::parse(s.read_at_offset16(data)?)?; let lookups = LookupList::parse(s.read_at_offset16(data)?)?; - #[cfg(feature = "variable-fonts")] { + #[cfg(feature = "variable-fonts")] + { let mut variations_offset = None; if minor_version >= 1 { variations_offset = s.read::>()?; } let variations = match variations_offset { - Some(offset) => data.get(offset.to_usize()..).and_then(FeatureVariations::parse), + Some(offset) => data + .get(offset.to_usize()..) + .and_then(FeatureVariations::parse), None => None, }; - Some(Self { scripts, features, lookups, variations }) + Some(Self { + scripts, + features, + lookups, + variations, + }) } - #[cfg(not(feature = "variable-fonts"))] { - Some(Self { scripts, features, lookups }) + #[cfg(not(feature = "variable-fonts"))] + { + Some(Self { + scripts, + features, + lookups, + }) } } } @@ -88,7 +103,11 @@ impl<'a, T: RecordListItem<'a>> RecordList<'a, T> { let mut s = Stream::new(data); let count = s.read::()?; let records = s.read_array16(count)?; - Some(Self { data, records, data_type: core::marker::PhantomData }) + Some(Self { + data, + records, + data_type: core::marker::PhantomData, + }) } /// Returns a number of items in the RecordList. @@ -104,18 +123,27 @@ impl<'a, T: RecordListItem<'a>> RecordList<'a, T> { /// Returns RecordList value by index. pub fn get(&self, index: u16) -> Option { let record = self.records.get(index)?; - self.data.get(record.offset.to_usize()..).and_then(|data| T::parse(record.tag, data)) + self.data + .get(record.offset.to_usize()..) + .and_then(|data| T::parse(record.tag, data)) } /// Returns RecordList value by [`Tag`]. pub fn find(&self, tag: Tag) -> Option { - let record = self.records.binary_search_by(|record| record.tag.cmp(&tag)).map(|p| p.1)?; - self.data.get(record.offset.to_usize()..).and_then(|data| T::parse(record.tag, data)) + let record = self + .records + .binary_search_by(|record| record.tag.cmp(&tag)) + .map(|p| p.1)?; + self.data + .get(record.offset.to_usize()..) + .and_then(|data| T::parse(record.tag, data)) } /// Returns RecordList value index by [`Tag`]. pub fn index(&self, tag: Tag) -> Option { - self.records.binary_search_by(|record| record.tag.cmp(&tag)).map(|p| p.0) + self.records + .binary_search_by(|record| record.tag.cmp(&tag)) + .map(|p| p.0) } } @@ -159,7 +187,6 @@ pub type LanguageSystemList<'a> = RecordList<'a, LanguageSystem<'a>>; /// A list of [`Feature`] records. pub type FeatureList<'a> = RecordList<'a, Feature<'a>>; - #[derive(Clone, Copy, Debug)] struct TagRecord { tag: Tag, @@ -195,15 +222,17 @@ impl<'a> RecordListItem<'a> for Script<'a> { let mut s = Stream::new(data); let mut default_language = None; if let Some(offset) = s.read::>()? { - default_language = LanguageSystem::parse( - Tag::from_bytes(b"dflt"), - data.get(offset.to_usize()..)? - ); + default_language = + LanguageSystem::parse(Tag::from_bytes(b"dflt"), data.get(offset.to_usize()..)?); } let mut languages = RecordList::parse(s.tail()?)?; // Offsets are relative to this table. languages.data = data; - Some(Self { tag, default_language, languages }) + Some(Self { + tag, + default_language, + languages, + }) } } @@ -215,7 +244,7 @@ pub struct LanguageSystem<'a> { /// Index of a feature required for this language system. pub required_feature: Option, /// Array of indices into the FeatureList, in arbitrary order. - pub feature_indices: LazyArray16<'a, FeatureIndex> + pub feature_indices: LazyArray16<'a, FeatureIndex>, } impl<'a> RecordListItem<'a> for LanguageSystem<'a> { @@ -228,7 +257,11 @@ impl<'a> RecordListItem<'a> for LanguageSystem<'a> { }; let count = s.read::()?; let feature_indices = s.read_array16(count)?; - Some(Self { tag, required_feature, feature_indices }) + Some(Self { + tag, + required_feature, + feature_indices, + }) } } @@ -246,6 +279,9 @@ impl<'a> RecordListItem<'a> for Feature<'a> { let _params_offset = s.read::()?; // Unsupported. let count = s.read::()?; let lookup_indices = s.read_array16(count)?; - Some(Self { tag, lookup_indices }) + Some(Self { + tag, + lookup_indices, + }) } } diff --git a/src/ggg/lookup.rs b/src/ggg/lookup.rs index 057cc8af..7d7fc679 100644 --- a/src/ggg/lookup.rs +++ b/src/ggg/lookup.rs @@ -1,4 +1,6 @@ -use crate::parser::{FromData, FromSlice, LazyArray16, LazyOffsetArray16, Offset, Offset16, Offset32, Stream}; +use crate::parser::{ + FromData, FromSlice, LazyArray16, LazyOffsetArray16, Offset, Offset16, Offset32, Stream, +}; /// A list of [`Lookup`] values. pub type LookupList<'a> = LazyOffsetArray16<'a, Lookup<'a>>; @@ -29,7 +31,11 @@ impl<'a> FromSlice<'a> for Lookup<'a> { Some(Self { flags, - subtables: LookupSubtables { kind, data, offsets }, + subtables: LookupSubtables { + kind, + data, + offsets, + }, mark_filtering_set, }) } @@ -115,6 +121,7 @@ impl<'a, T: LookupSubtable<'a>> Iterator for LookupSubtablesIter<'a, T> { #[derive(Clone, Copy, Debug)] pub struct LookupFlags(pub u16); +#[rustfmt::skip] #[allow(missing_docs)] impl LookupFlags { #[inline] pub fn right_to_left(self) -> bool { self.0 & 0x0001 != 0 } diff --git a/src/ggg/mod.rs b/src/ggg/mod.rs index 934d90d6..1793e1de 100644 --- a/src/ggg/mod.rs +++ b/src/ggg/mod.rs @@ -5,20 +5,22 @@ // A heavily modified port of https://github.com/RazrFalcon/rustybuzz implementation // originally written by https://github.com/laurmaedje +use crate::parser::{FromData, FromSlice, LazyArray16, Stream}; use crate::GlyphId; -use crate::parser::{Stream, FromData, FromSlice, LazyArray16}; -mod context; mod chained_context; -mod lookup; +mod context; +#[cfg(feature = "variable-fonts")] +mod feature_variations; mod layout_table; -#[cfg(feature = "variable-fonts")] mod feature_variations; +mod lookup; -pub use context::*; pub use chained_context::*; -pub use lookup::*; +pub use context::*; +#[cfg(feature = "variable-fonts")] +pub use feature_variations::*; pub use layout_table::*; -#[cfg(feature = "variable-fonts")] pub use feature_variations::*; +pub use lookup::*; /// A record that describes a range of glyph IDs. #[derive(Clone, Copy, Debug)] @@ -42,7 +44,8 @@ impl LazyArray16<'_, RangeRecord> { } else { core::cmp::Ordering::Less } - }).map(|p| p.1) + }) + .map(|p| p.1) } } @@ -60,7 +63,6 @@ impl FromData for RangeRecord { } } - /// A [Coverage Table]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#coverage-table). #[allow(missing_docs)] @@ -104,9 +106,7 @@ impl<'a> Coverage<'a> { /// Returns the coverage index of the glyph or `None` if it is not covered. pub fn get(&self, glyph: GlyphId) -> Option { match self { - Self::Format1 { glyphs } => { - glyphs.binary_search(&glyph).map(|p| p.0) - } + Self::Format1 { glyphs } => glyphs.binary_search(&glyph).map(|p| p.0), Self::Format2 { records } => { let record = records.range(glyph)?; let offset = glyph.0 - record.start.0; @@ -144,12 +144,12 @@ impl<'a> ClassDefinition<'a> { let count = s.read::()?; let classes = s.read_array16(count)?; Some(Self::Format1 { start, classes }) - }, + } 2 => { let count = s.read::()?; let records = s.read_array16(count)?; Some(Self::Format2 { records }) - }, + } _ => None, } } @@ -157,12 +157,12 @@ impl<'a> ClassDefinition<'a> { /// Returns the glyph class of the glyph (zero if it is not defined). pub fn get(&self, glyph: GlyphId) -> Class { match self { - Self::Format1 { start, classes } => { - glyph.0.checked_sub(start.0).and_then(|index| classes.get(index)) - } - Self::Format2 { records } => { - records.range(glyph).map(|record| record.value) - } - }.unwrap_or(0) + Self::Format1 { start, classes } => glyph + .0 + .checked_sub(start.0) + .and_then(|index| classes.get(index)), + Self::Format2 { records } => records.range(glyph).map(|record| record.value), + } + .unwrap_or(0) } } diff --git a/src/lib.rs b/src/lib.rs index fa61f3b8..408ce2ce 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -52,26 +52,35 @@ macro_rules! try_opt_or { }; } +#[cfg(feature = "apple-layout")] +mod aat; +#[cfg(feature = "opentype-layout")] +mod ggg; mod parser; mod tables; -#[cfg(feature = "apple-layout")] mod aat; -#[cfg(feature = "opentype-layout")] mod ggg; -#[cfg(feature = "variable-fonts")] mod var_store; +#[cfg(feature = "variable-fonts")] +mod var_store; -use parser::{Stream, NumFrom, TryNumFrom, Offset32, Offset}; -pub use parser::{FromData, LazyArray16, LazyArrayIter16, LazyArray32, LazyArrayIter32, Fixed}; use head::IndexToLocationFormat; +pub use parser::{Fixed, FromData, LazyArray16, LazyArray32, LazyArrayIter16, LazyArrayIter32}; +use parser::{NumFrom, Offset, Offset32, Stream, TryNumFrom}; -#[cfg(feature = "variable-fonts")] pub use fvar::VariationAxis; +#[cfg(feature = "variable-fonts")] +pub use fvar::VariationAxis; pub use name::{name_id, PlatformId}; -pub use os2::{Weight, Width, ScriptMetrics, Style}; +pub use os2::{ScriptMetrics, Style, Weight, Width}; pub use tables::CFFError; -pub use tables::{cmap, kern, sbix, maxp, hmtx, name, os2, loca, svg, vorg, post, head, hhea, glyf}; -pub use tables::{cff1 as cff, vhea, cbdt, cblc}; -#[cfg(feature = "opentype-layout")] pub use tables::{gdef, gpos, gsub, math}; -#[cfg(feature = "apple-layout")] pub use tables::{ankr, feat, kerx, morx, trak}; -#[cfg(feature = "variable-fonts")] pub use tables::{cff2, avar, fvar, gvar, hvar, mvar}; +#[cfg(feature = "apple-layout")] +pub use tables::{ankr, feat, kerx, morx, trak}; +#[cfg(feature = "variable-fonts")] +pub use tables::{avar, cff2, fvar, gvar, hvar, mvar}; +pub use tables::{cbdt, cblc, cff1 as cff, vhea}; +pub use tables::{ + cmap, glyf, head, hhea, hmtx, kern, loca, maxp, name, os2, post, sbix, svg, vorg, +}; +#[cfg(feature = "opentype-layout")] +pub use tables::{gdef, gpos, gsub, math}; #[cfg(feature = "opentype-layout")] pub mod opentype_layout { @@ -90,7 +99,6 @@ pub mod apple_layout { pub use crate::aat::*; } - /// A type-safe wrapper for glyph ID. #[repr(transparent)] #[derive(Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Default, Debug, Hash)] @@ -105,7 +113,6 @@ impl FromData for GlyphId { } } - /// A TrueType font magic. /// /// https://docs.microsoft.com/en-us/typography/opentype/spec/otff#organization-of-an-opentype-font @@ -130,7 +137,6 @@ impl FromData for Magic { } } - /// A variation coordinate in a normalized coordinate system. /// /// Basically any number in a -1.0..1.0 range. @@ -169,7 +175,6 @@ impl NormalizedCoordinate { } } - /// A font variation value. /// /// # Example @@ -187,7 +192,6 @@ pub struct Variation { pub value: f32, } - /// A 4-byte tag. #[repr(transparent)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -203,8 +207,10 @@ impl Tag { /// ``` #[inline] pub const fn from_bytes(bytes: &[u8; 4]) -> Self { - Tag(((bytes[0] as u32) << 24) | ((bytes[1] as u32) << 16) | - ((bytes[2] as u32) << 8) | (bytes[3] as u32)) + Tag(((bytes[0] as u32) << 24) + | ((bytes[1] as u32) << 16) + | ((bytes[2] as u32) << 8) + | (bytes[3] as u32)) } /// Creates a `Tag` from bytes. @@ -295,7 +301,6 @@ impl FromData for Tag { } } - /// A line metrics. /// /// Used for underline and strikeout. @@ -309,7 +314,6 @@ pub struct LineMetrics { pub thickness: i16, } - /// A rectangle. /// /// Doesn't guarantee that `x_min` <= `x_max` and/or `y_min` <= `y_max`. @@ -337,7 +341,6 @@ impl Rect { } } - #[derive(Clone, Copy, Debug)] pub(crate) struct BBox { x_min: f32, @@ -359,10 +362,10 @@ impl BBox { #[inline] fn is_default(&self) -> bool { - self.x_min == core::f32::MAX && - self.y_min == core::f32::MAX && - self.x_max == core::f32::MIN && - self.y_max == core::f32::MIN + self.x_min == core::f32::MAX + && self.y_min == core::f32::MAX + && self.x_max == core::f32::MIN + && self.y_max == core::f32::MIN } #[inline] @@ -384,7 +387,6 @@ impl BBox { } } - /// A trait for glyph outline construction. pub trait OutlineBuilder { /// Appends a MoveTo segment. @@ -407,7 +409,6 @@ pub trait OutlineBuilder { fn close(&mut self); } - struct DummyOutline; impl OutlineBuilder for DummyOutline { fn move_to(&mut self, _: f32, _: f32) {} @@ -417,7 +418,6 @@ impl OutlineBuilder for DummyOutline { fn close(&mut self) {} } - /// A glyph raster image format. #[allow(missing_docs)] #[derive(Clone, Copy, PartialEq, Debug)] @@ -425,7 +425,6 @@ pub enum RasterImageFormat { PNG, } - /// A glyph's raster image. /// /// Note, that glyph metrics are in pixels and not in font units. @@ -457,7 +456,6 @@ pub struct RasterGlyphImage<'a> { pub data: &'a [u8], } - /// A raw table record. #[derive(Clone, Copy, Debug)] #[allow(missing_docs)] @@ -484,7 +482,6 @@ impl FromData for TableRecord { } } - #[cfg(feature = "variable-fonts")] const MAX_VAR_COORDS: usize = 32; @@ -509,7 +506,6 @@ impl VarCoords { } } - /// A list of font face parsing errors. #[derive(Clone, Copy, PartialEq, Debug)] pub enum FaceParsingError { @@ -550,7 +546,6 @@ impl core::fmt::Display for FaceParsingError { #[cfg(feature = "std")] impl std::error::Error for FaceParsingError {} - /// A raw font face. /// /// You are probably looking for [`Face`]. This is a low-level type. @@ -575,7 +570,7 @@ impl<'a> RawFace<'a> { /// Set to 0 if unsure. /// /// While we do reuse [`FaceParsingError`], `No*Table` errors will not be throws. - #[deprecated(since="0.16.0", note="use `parse` instead")] + #[deprecated(since = "0.16.0", note = "use `parse` instead")] pub fn from_slice(data: &'a [u8], index: u32) -> Result { Self::parse(data, index) } @@ -597,15 +592,21 @@ impl<'a> RawFace<'a> { if magic == Magic::FontCollection { s.skip::(); // version let number_of_faces = s.read::().ok_or(FaceParsingError::MalformedFont)?; - let offsets = s.read_array32::(number_of_faces) + let offsets = s + .read_array32::(number_of_faces) .ok_or(FaceParsingError::MalformedFont)?; - let face_offset = offsets.get(index).ok_or(FaceParsingError::FaceIndexOutOfBounds)?; + let face_offset = offsets + .get(index) + .ok_or(FaceParsingError::FaceIndexOutOfBounds)?; // Face offset is from the start of the font data, // so we have to adjust it to the current parser offset. - let face_offset = face_offset.to_usize().checked_sub(s.offset()) + let face_offset = face_offset + .to_usize() + .checked_sub(s.offset()) + .ok_or(FaceParsingError::MalformedFont)?; + s.advance_checked(face_offset) .ok_or(FaceParsingError::MalformedFont)?; - s.advance_checked(face_offset).ok_or(FaceParsingError::MalformedFont)?; // Read **face** magic. // Each face in a font collection also starts with a magic. @@ -618,7 +619,8 @@ impl<'a> RawFace<'a> { let num_tables = s.read::().ok_or(FaceParsingError::MalformedFont)?; s.advance(6); // searchRange (u16) + entrySelector (u16) + rangeShift (u16) - let table_records = s.read_array16::(num_tables) + let table_records = s + .read_array16::(num_tables) .ok_or(FaceParsingError::MalformedFont)?; Ok(RawFace { @@ -629,7 +631,9 @@ impl<'a> RawFace<'a> { /// Returns the raw data of a selected table. pub fn table(&self, tag: Tag) -> Option<&'a [u8]> { - let (_, table) = self.table_records.binary_search_by(|record| record.tag.cmp(&tag))?; + let (_, table) = self + .table_records + .binary_search_by(|record| record.tag.cmp(&tag))?; let offset = usize::num_from(table.offset); let length = usize::num_from(table.length); let end = offset.checked_add(length)?; @@ -643,7 +647,6 @@ impl core::fmt::Debug for RawFace<'_> { } } - /// A list of all supported tables as raw data. /// /// This type should be used in tandem with @@ -662,39 +665,55 @@ pub struct RawFaceTables<'a> { pub cbdt: Option<&'a [u8]>, pub cblc: Option<&'a [u8]>, - pub cff: Option<&'a [u8]>, + pub cff: Option<&'a [u8]>, pub cmap: Option<&'a [u8]>, pub glyf: Option<&'a [u8]>, pub hmtx: Option<&'a [u8]>, pub kern: Option<&'a [u8]>, pub loca: Option<&'a [u8]>, pub name: Option<&'a [u8]>, - pub os2: Option<&'a [u8]>, + pub os2: Option<&'a [u8]>, pub post: Option<&'a [u8]>, pub sbix: Option<&'a [u8]>, - pub svg: Option<&'a [u8]>, + pub svg: Option<&'a [u8]>, pub vhea: Option<&'a [u8]>, pub vmtx: Option<&'a [u8]>, pub vorg: Option<&'a [u8]>, - #[cfg(feature = "opentype-layout")] pub gdef: Option<&'a [u8]>, - #[cfg(feature = "opentype-layout")] pub gpos: Option<&'a [u8]>, - #[cfg(feature = "opentype-layout")] pub gsub: Option<&'a [u8]>, - #[cfg(feature = "opentype-layout")] pub math: Option<&'a [u8]>, - - #[cfg(feature = "apple-layout")] pub ankr: Option<&'a [u8]>, - #[cfg(feature = "apple-layout")] pub feat: Option<&'a [u8]>, - #[cfg(feature = "apple-layout")] pub kerx: Option<&'a [u8]>, - #[cfg(feature = "apple-layout")] pub morx: Option<&'a [u8]>, - #[cfg(feature = "apple-layout")] pub trak: Option<&'a [u8]>, - - #[cfg(feature = "variable-fonts")] pub avar: Option<&'a [u8]>, - #[cfg(feature = "variable-fonts")] pub cff2: Option<&'a [u8]>, - #[cfg(feature = "variable-fonts")] pub fvar: Option<&'a [u8]>, - #[cfg(feature = "variable-fonts")] pub gvar: Option<&'a [u8]>, - #[cfg(feature = "variable-fonts")] pub hvar: Option<&'a [u8]>, - #[cfg(feature = "variable-fonts")] pub mvar: Option<&'a [u8]>, - #[cfg(feature = "variable-fonts")] pub vvar: Option<&'a [u8]>, + #[cfg(feature = "opentype-layout")] + pub gdef: Option<&'a [u8]>, + #[cfg(feature = "opentype-layout")] + pub gpos: Option<&'a [u8]>, + #[cfg(feature = "opentype-layout")] + pub gsub: Option<&'a [u8]>, + #[cfg(feature = "opentype-layout")] + pub math: Option<&'a [u8]>, + + #[cfg(feature = "apple-layout")] + pub ankr: Option<&'a [u8]>, + #[cfg(feature = "apple-layout")] + pub feat: Option<&'a [u8]>, + #[cfg(feature = "apple-layout")] + pub kerx: Option<&'a [u8]>, + #[cfg(feature = "apple-layout")] + pub morx: Option<&'a [u8]>, + #[cfg(feature = "apple-layout")] + pub trak: Option<&'a [u8]>, + + #[cfg(feature = "variable-fonts")] + pub avar: Option<&'a [u8]>, + #[cfg(feature = "variable-fonts")] + pub cff2: Option<&'a [u8]>, + #[cfg(feature = "variable-fonts")] + pub fvar: Option<&'a [u8]>, + #[cfg(feature = "variable-fonts")] + pub gvar: Option<&'a [u8]>, + #[cfg(feature = "variable-fonts")] + pub hvar: Option<&'a [u8]>, + #[cfg(feature = "variable-fonts")] + pub mvar: Option<&'a [u8]>, + #[cfg(feature = "variable-fonts")] + pub vvar: Option<&'a [u8]>, } /// Parsed face tables. @@ -714,38 +733,54 @@ pub struct FaceTables<'a> { pub maxp: maxp::Table, pub cbdt: Option>, - pub cff: Option>, + pub cff: Option>, pub cmap: Option>, pub glyf: Option>, pub hmtx: Option>, pub kern: Option>, pub name: Option>, - pub os2: Option>, + pub os2: Option>, pub post: Option>, pub sbix: Option>, - pub svg: Option>, + pub svg: Option>, pub vhea: Option, pub vmtx: Option>, pub vorg: Option>, - #[cfg(feature = "opentype-layout")] pub gdef: Option>, - #[cfg(feature = "opentype-layout")] pub gpos: Option>, - #[cfg(feature = "opentype-layout")] pub gsub: Option>, - #[cfg(feature = "opentype-layout")] pub math: Option>, - - #[cfg(feature = "apple-layout")] pub ankr: Option>, - #[cfg(feature = "apple-layout")] pub feat: Option>, - #[cfg(feature = "apple-layout")] pub kerx: Option>, - #[cfg(feature = "apple-layout")] pub morx: Option>, - #[cfg(feature = "apple-layout")] pub trak: Option>, - - #[cfg(feature = "variable-fonts")] pub avar: Option>, - #[cfg(feature = "variable-fonts")] pub cff2: Option>, - #[cfg(feature = "variable-fonts")] pub fvar: Option>, - #[cfg(feature = "variable-fonts")] pub gvar: Option>, - #[cfg(feature = "variable-fonts")] pub hvar: Option>, - #[cfg(feature = "variable-fonts")] pub mvar: Option>, - #[cfg(feature = "variable-fonts")] pub vvar: Option>, + #[cfg(feature = "opentype-layout")] + pub gdef: Option>, + #[cfg(feature = "opentype-layout")] + pub gpos: Option>, + #[cfg(feature = "opentype-layout")] + pub gsub: Option>, + #[cfg(feature = "opentype-layout")] + pub math: Option>, + + #[cfg(feature = "apple-layout")] + pub ankr: Option>, + #[cfg(feature = "apple-layout")] + pub feat: Option>, + #[cfg(feature = "apple-layout")] + pub kerx: Option>, + #[cfg(feature = "apple-layout")] + pub morx: Option>, + #[cfg(feature = "apple-layout")] + pub trak: Option>, + + #[cfg(feature = "variable-fonts")] + pub avar: Option>, + #[cfg(feature = "variable-fonts")] + pub cff2: Option>, + #[cfg(feature = "variable-fonts")] + pub fvar: Option>, + #[cfg(feature = "variable-fonts")] + pub gvar: Option>, + #[cfg(feature = "variable-fonts")] + pub hvar: Option>, + #[cfg(feature = "variable-fonts")] + pub mvar: Option>, + #[cfg(feature = "variable-fonts")] + pub vvar: Option>, } /// A font face. @@ -767,7 +802,8 @@ pub struct FaceTables<'a> { pub struct Face<'a> { raw_face: RawFace<'a>, tables: FaceTables<'a>, // Parsed tables. - #[cfg(feature = "variable-fonts")] coordinates: VarCoords, + #[cfg(feature = "variable-fonts")] + coordinates: VarCoords, } impl<'a> Face<'a> { @@ -783,7 +819,7 @@ impl<'a> Face<'a> { /// Required tables: `head`, `hhea` and `maxp`. /// /// If an optional table has invalid data it will be skipped. - #[deprecated(since="0.16.0", note="use `parse` instead")] + #[deprecated(since = "0.16.0", note = "use `parse` instead")] pub fn from_slice(data: &'a [u8], index: u32) -> Result { Self::parse(data, index) } @@ -807,11 +843,13 @@ impl<'a> Face<'a> { #[allow(unused_mut)] let mut face = Face { raw_face, - #[cfg(feature = "variable-fonts")] coordinates: VarCoords::default(), + #[cfg(feature = "variable-fonts")] + coordinates: VarCoords::default(), tables: Self::parse_tables(raw_tables)?, }; - #[cfg(feature = "variable-fonts")] { + #[cfg(feature = "variable-fonts")] + { if let Some(ref fvar) = face.tables.fvar { face.coordinates.len = fvar.axes.len().min(MAX_VAR_COORDS as u16) as u8; } @@ -898,11 +936,13 @@ impl<'a> Face<'a> { data: &[], table_records: LazyArray16::default(), }, - #[cfg(feature = "variable-fonts")] coordinates: VarCoords::default(), + #[cfg(feature = "variable-fonts")] + coordinates: VarCoords::default(), tables: Self::parse_tables(raw_tables)?, }; - #[cfg(feature = "variable-fonts")] { + #[cfg(feature = "variable-fonts")] + { if let Some(ref fvar) = face.tables.fvar { face.coordinates.len = fvar.axes.len().min(MAX_VAR_COORDS as u16) as u8; } @@ -916,30 +956,34 @@ impl<'a> Face<'a> { let hhea = hhea::Table::parse(raw_tables.hhea).ok_or(FaceParsingError::NoHheaTable)?; let maxp = maxp::Table::parse(raw_tables.maxp).ok_or(FaceParsingError::NoMaxpTable)?; - let hmtx = raw_tables.hmtx.and_then(|data| + let hmtx = raw_tables.hmtx.and_then(|data| { hmtx::Table::parse(hhea.number_of_metrics, maxp.number_of_glyphs, data) - ); + }); let vhea = raw_tables.vhea.and_then(vhea::Table::parse); let vmtx = if let Some(vhea) = vhea { - raw_tables.vmtx.and_then(|data| + raw_tables.vmtx.and_then(|data| { hmtx::Table::parse(vhea.number_of_metrics, maxp.number_of_glyphs, data) - ) + }) } else { None }; - let loca = raw_tables.loca.and_then(|data| + let loca = raw_tables.loca.and_then(|data| { loca::Table::parse(maxp.number_of_glyphs, head.index_to_location_format, data) - ); + }); let glyf = if let Some(loca) = loca { - raw_tables.glyf.and_then(|data| glyf::Table::parse(loca, data)) + raw_tables + .glyf + .and_then(|data| glyf::Table::parse(loca, data)) } else { None }; let cbdt = if let Some(cblc) = raw_tables.cblc.and_then(cblc::Table::parse) { - raw_tables.cbdt.and_then(|data| cbdt::Table::parse(cblc, data)) + raw_tables + .cbdt + .and_then(|data| cbdt::Table::parse(cblc, data)) } else { None }; @@ -950,41 +994,66 @@ impl<'a> Face<'a> { maxp, cbdt, - cff: raw_tables.cff.and_then(cff::Table::parse), + cff: raw_tables.cff.and_then(cff::Table::parse), cmap: raw_tables.cmap.and_then(cmap::Table::parse), glyf, hmtx, kern: raw_tables.kern.and_then(kern::Table::parse), name: raw_tables.name.and_then(name::Table::parse), - os2: raw_tables.os2.and_then(os2::Table::parse), + os2: raw_tables.os2.and_then(os2::Table::parse), post: raw_tables.post.and_then(post::Table::parse), - sbix: raw_tables.sbix.and_then(|data| sbix::Table::parse(maxp.number_of_glyphs, data)), - svg: raw_tables.svg.and_then(svg::Table::parse), + sbix: raw_tables + .sbix + .and_then(|data| sbix::Table::parse(maxp.number_of_glyphs, data)), + svg: raw_tables.svg.and_then(svg::Table::parse), vhea: raw_tables.vhea.and_then(vhea::Table::parse), vmtx, vorg: raw_tables.vorg.and_then(vorg::Table::parse), - #[cfg(feature = "opentype-layout")] gdef: raw_tables.gdef.and_then(gdef::Table::parse), - #[cfg(feature = "opentype-layout")] gpos: raw_tables.gpos.and_then(opentype_layout::LayoutTable::parse), - #[cfg(feature = "opentype-layout")] gsub: raw_tables.gsub.and_then(opentype_layout::LayoutTable::parse), - #[cfg(feature = "opentype-layout")] math: raw_tables.math.and_then(math::Table::parse), - - #[cfg(feature = "apple-layout")] ankr: raw_tables.ankr + #[cfg(feature = "opentype-layout")] + gdef: raw_tables.gdef.and_then(gdef::Table::parse), + #[cfg(feature = "opentype-layout")] + gpos: raw_tables + .gpos + .and_then(opentype_layout::LayoutTable::parse), + #[cfg(feature = "opentype-layout")] + gsub: raw_tables + .gsub + .and_then(opentype_layout::LayoutTable::parse), + #[cfg(feature = "opentype-layout")] + math: raw_tables.math.and_then(math::Table::parse), + + #[cfg(feature = "apple-layout")] + ankr: raw_tables + .ankr .and_then(|data| ankr::Table::parse(maxp.number_of_glyphs, data)), - #[cfg(feature = "apple-layout")] feat: raw_tables.feat.and_then(feat::Table::parse), - #[cfg(feature = "apple-layout")] kerx: raw_tables.kerx + #[cfg(feature = "apple-layout")] + feat: raw_tables.feat.and_then(feat::Table::parse), + #[cfg(feature = "apple-layout")] + kerx: raw_tables + .kerx .and_then(|data| kerx::Table::parse(maxp.number_of_glyphs, data)), - #[cfg(feature = "apple-layout")] morx: raw_tables.morx + #[cfg(feature = "apple-layout")] + morx: raw_tables + .morx .and_then(|data| morx::Table::parse(maxp.number_of_glyphs, data)), - #[cfg(feature = "apple-layout")] trak: raw_tables.trak.and_then(trak::Table::parse), - - #[cfg(feature = "variable-fonts")] avar: raw_tables.avar.and_then(avar::Table::parse), - #[cfg(feature = "variable-fonts")] cff2: raw_tables.cff2.and_then(cff2::Table::parse), - #[cfg(feature = "variable-fonts")] fvar: raw_tables.fvar.and_then(fvar::Table::parse), - #[cfg(feature = "variable-fonts")] gvar: raw_tables.gvar.and_then(gvar::Table::parse), - #[cfg(feature = "variable-fonts")] hvar: raw_tables.hvar.and_then(hvar::Table::parse), - #[cfg(feature = "variable-fonts")] mvar: raw_tables.mvar.and_then(mvar::Table::parse), - #[cfg(feature = "variable-fonts")] vvar: raw_tables.vvar.and_then(hvar::Table::parse), + #[cfg(feature = "apple-layout")] + trak: raw_tables.trak.and_then(trak::Table::parse), + + #[cfg(feature = "variable-fonts")] + avar: raw_tables.avar.and_then(avar::Table::parse), + #[cfg(feature = "variable-fonts")] + cff2: raw_tables.cff2.and_then(cff2::Table::parse), + #[cfg(feature = "variable-fonts")] + fvar: raw_tables.fvar.and_then(fvar::Table::parse), + #[cfg(feature = "variable-fonts")] + gvar: raw_tables.gvar.and_then(gvar::Table::parse), + #[cfg(feature = "variable-fonts")] + hvar: raw_tables.hvar.and_then(hvar::Table::parse), + #[cfg(feature = "variable-fonts")] + mvar: raw_tables.mvar.and_then(mvar::Table::parse), + #[cfg(feature = "variable-fonts")] + vvar: raw_tables.vvar.and_then(hvar::Table::parse), }) } @@ -1009,7 +1078,7 @@ impl<'a> Face<'a> { /// Useful if you want to parse the data manually. /// /// Available only for faces created using [`Face::parse()`](struct.Face.html#method.parse). - #[deprecated(since="0.16.0", note="use `self.raw_face().table()` instead")] + #[deprecated(since = "0.16.0", note = "use `self.raw_face().table()` instead")] #[inline] pub fn table_data(&self, tag: Tag) -> Option<&'a [u8]> { self.raw_face.table(tag) @@ -1028,7 +1097,10 @@ impl<'a> Face<'a> { /// Returns `false` when OS/2 table is not present. #[inline] pub fn is_regular(&self) -> bool { - self.tables.os2.map(|s| s.style() == Style::Normal).unwrap_or(false) + self.tables + .os2 + .map(|s| s.style() == Style::Normal) + .unwrap_or(false) } /// Checks that face is marked as *Italic*. @@ -1036,7 +1108,10 @@ impl<'a> Face<'a> { /// Returns `false` when OS/2 table is not present. #[inline] pub fn is_italic(&self) -> bool { - self.tables.os2.map(|s| s.style() == Style::Italic).unwrap_or(false) + self.tables + .os2 + .map(|s| s.style() == Style::Italic) + .unwrap_or(false) } /// Checks that face is marked as *Bold*. @@ -1052,7 +1127,10 @@ impl<'a> Face<'a> { /// Returns `false` when OS/2 table is not present or when its version is < 4. #[inline] pub fn is_oblique(&self) -> bool { - self.tables.os2.map(|s| s.style() == Style::Oblique).unwrap_or(false) + self.tables + .os2 + .map(|s| s.style() == Style::Oblique) + .unwrap_or(false) } /// Returns face style. @@ -1074,12 +1152,14 @@ impl<'a> Face<'a> { /// Simply checks the presence of a `fvar` table. #[inline] pub fn is_variable(&self) -> bool { - #[cfg(feature = "variable-fonts")] { + #[cfg(feature = "variable-fonts")] + { // `fvar::Table::parse` already checked that `axisCount` is non-zero. self.tables.fvar.is_some() } - #[cfg(not(feature = "variable-fonts"))] { + #[cfg(not(feature = "variable-fonts"))] + { false } } @@ -1256,7 +1336,9 @@ impl<'a> Face<'a> { /// This method is affected by variation axes. #[inline] pub fn vertical_ascender(&self) -> Option { - self.tables.vhea.map(|vhea| vhea.ascender) + self.tables + .vhea + .map(|vhea| vhea.ascender) .map(|v| self.apply_metrics_variation(Tag::from_bytes(b"vasc"), v)) } @@ -1265,7 +1347,9 @@ impl<'a> Face<'a> { /// This method is affected by variation axes. #[inline] pub fn vertical_descender(&self) -> Option { - self.tables.vhea.map(|vhea| vhea.descender) + self.tables + .vhea + .map(|vhea| vhea.descender) .map(|v| self.apply_metrics_variation(Tag::from_bytes(b"vdsc"), v)) } @@ -1282,7 +1366,9 @@ impl<'a> Face<'a> { /// This method is affected by variation axes. #[inline] pub fn vertical_line_gap(&self) -> Option { - self.tables.vhea.map(|vhea| vhea.line_gap) + self.tables + .vhea + .map(|vhea| vhea.line_gap) .map(|v| self.apply_metrics_variation(Tag::from_bytes(b"vlgp"), v)) } @@ -1301,7 +1387,9 @@ impl<'a> Face<'a> { /// Returns `None` when OS/2 table is not present or when its version is < 2. #[inline] pub fn x_height(&self) -> Option { - self.tables.os2.and_then(|os_2| os_2.x_height()) + self.tables + .os2 + .and_then(|os_2| os_2.x_height()) .map(|v| self.apply_metrics_variation(Tag::from_bytes(b"xhgt"), v)) } @@ -1312,7 +1400,9 @@ impl<'a> Face<'a> { /// Returns `None` when OS/2 table is not present or when its version is < 2. #[inline] pub fn capital_height(&self) -> Option { - self.tables.os2.and_then(|os_2| os_2.capital_height()) + self.tables + .os2 + .and_then(|os_2| os_2.capital_height()) .map(|v| self.apply_metrics_variation(Tag::from_bytes(b"cpht"), v)) } @@ -1428,11 +1518,20 @@ impl<'a> Face<'a> { #[cfg(feature = "glyph-names")] #[inline] pub fn glyph_index_by_name(&self, name: &str) -> Option { - if let Some(name) = self.tables.post.and_then(|post| post.glyph_index_by_name(name)) { + if let Some(name) = self + .tables + .post + .and_then(|post| post.glyph_index_by_name(name)) + { return Some(name); } - if let Some(name) = self.tables.cff.as_ref().and_then(|cff| cff.glyph_index_by_name(name)) { + if let Some(name) = self + .tables + .cff + .as_ref() + .and_then(|cff| cff.glyph_index_by_name(name)) + { return Some(name); } @@ -1465,7 +1564,8 @@ impl<'a> Face<'a> { /// This method is affected by variation axes. #[inline] pub fn glyph_hor_advance(&self, glyph_id: GlyphId) -> Option { - #[cfg(feature = "variable-fonts")] { + #[cfg(feature = "variable-fonts")] + { let mut advance = self.tables.hmtx?.advance(glyph_id)? as f32; if self.is_variable() { @@ -1481,7 +1581,8 @@ impl<'a> Face<'a> { u16::try_num_from(advance) } - #[cfg(not(feature = "variable-fonts"))] { + #[cfg(not(feature = "variable-fonts"))] + { self.tables.hmtx?.advance(glyph_id) } } @@ -1491,7 +1592,8 @@ impl<'a> Face<'a> { /// This method is affected by variation axes. #[inline] pub fn glyph_ver_advance(&self, glyph_id: GlyphId) -> Option { - #[cfg(feature = "variable-fonts")] { + #[cfg(feature = "variable-fonts")] + { let mut advance = self.tables.vmtx?.advance(glyph_id)? as f32; if self.is_variable() { @@ -1507,7 +1609,8 @@ impl<'a> Face<'a> { u16::try_num_from(advance) } - #[cfg(not(feature = "variable-fonts"))] { + #[cfg(not(feature = "variable-fonts"))] + { self.tables.vmtx?.advance(glyph_id) } } @@ -1517,7 +1620,8 @@ impl<'a> Face<'a> { /// This method is affected by variation axes. #[inline] pub fn glyph_hor_side_bearing(&self, glyph_id: GlyphId) -> Option { - #[cfg(feature = "variable-fonts")] { + #[cfg(feature = "variable-fonts")] + { let mut bearing = self.tables.hmtx?.side_bearing(glyph_id)? as f32; if self.is_variable() { @@ -1533,7 +1637,8 @@ impl<'a> Face<'a> { i16::try_num_from(bearing) } - #[cfg(not(feature = "variable-fonts"))] { + #[cfg(not(feature = "variable-fonts"))] + { self.tables.hmtx?.side_bearing(glyph_id) } } @@ -1543,7 +1648,8 @@ impl<'a> Face<'a> { /// This method is affected by variation axes. #[inline] pub fn glyph_ver_side_bearing(&self, glyph_id: GlyphId) -> Option { - #[cfg(feature = "variable-fonts")] { + #[cfg(feature = "variable-fonts")] + { let mut bearing = self.tables.vmtx?.side_bearing(glyph_id)? as f32; if self.is_variable() { @@ -1559,7 +1665,8 @@ impl<'a> Face<'a> { i16::try_num_from(bearing) } - #[cfg(not(feature = "variable-fonts"))] { + #[cfg(not(feature = "variable-fonts"))] + { self.tables.vmtx?.side_bearing(glyph_id) } } @@ -1582,7 +1689,12 @@ impl<'a> Face<'a> { return Some(name); } - if let Some(name) = self.tables.cff.as_ref().and_then(|cff1| cff1.glyph_name(glyph_id)) { + if let Some(name) = self + .tables + .cff + .as_ref() + .and_then(|cff1| cff1.glyph_name(glyph_id)) + { return Some(name); } @@ -1647,7 +1759,8 @@ impl<'a> Face<'a> { glyph_id: GlyphId, builder: &mut dyn OutlineBuilder, ) -> Option { - #[cfg(feature = "variable-fonts")] { + #[cfg(feature = "variable-fonts")] + { if let Some(ref gvar) = self.tables.gvar { return gvar.outline(self.tables.glyf?, self.coords(), glyph_id, builder); } @@ -1661,7 +1774,8 @@ impl<'a> Face<'a> { return cff.outline(glyph_id, builder).ok(); } - #[cfg(feature = "variable-fonts")] { + #[cfg(feature = "variable-fonts")] + { if let Some(ref cff2) = self.tables.cff2 { return cff2.outline(self.coords(), glyph_id, builder).ok(); } @@ -1719,7 +1833,11 @@ impl<'a> Face<'a> { /// and this method supports only `sbix`, `CBLC`+`CBDT`. /// Font's tables be accesses in this specific order. #[inline] - pub fn glyph_raster_image(&self, glyph_id: GlyphId, pixels_per_em: u16) -> Option { + pub fn glyph_raster_image( + &self, + glyph_id: GlyphId, + pixels_per_em: u16, + ) -> Option { if let Some(table) = self.tables.sbix { if let Some(strike) = table.best_strike(pixels_per_em) { return strike.get(glyph_id); @@ -1771,7 +1889,11 @@ impl<'a> Face<'a> { return None; } - let v = self.variation_axes().into_iter().enumerate().find(|(_, a)| a.tag == axis); + let v = self + .variation_axes() + .into_iter() + .enumerate() + .find(|(_, a)| a.tag == axis); if let Some((idx, a)) = v { if idx >= MAX_VAR_COORDS { return None; @@ -1808,7 +1930,10 @@ impl<'a> Face<'a> { #[cfg(feature = "variable-fonts")] #[inline] fn metrics_var_offset(&self, tag: Tag) -> f32 { - self.tables.mvar.and_then(|table| table.metric_offset(tag, self.coords())).unwrap_or(0.0) + self.tables + .mvar + .and_then(|table| table.metric_offset(tag, self.coords())) + .unwrap_or(0.0) } #[inline] @@ -1817,7 +1942,6 @@ impl<'a> Face<'a> { value } - #[cfg(feature = "variable-fonts")] #[inline] fn apply_metrics_variation_to(&self, tag: Tag, value: &mut i16) { @@ -1832,8 +1956,7 @@ impl<'a> Face<'a> { #[cfg(not(feature = "variable-fonts"))] #[inline] - fn apply_metrics_variation_to(&self, _: Tag, _: &mut i16) { - } + fn apply_metrics_variation_to(&self, _: Tag, _: &mut i16) {} #[cfg(feature = "variable-fonts")] #[inline] @@ -1856,7 +1979,9 @@ impl<'a> Iterator for DefaultTableProvider<'a> { Ok((table.tag, { let offset = usize::num_from(table.offset); let length = usize::num_from(table.length); - let end = offset.checked_add(length).ok_or(FaceParsingError::MalformedFont)?; + let end = offset + .checked_add(length) + .ok_or(FaceParsingError::MalformedFont)?; let range = offset..end; self.data.get(range) })) diff --git a/src/parser.rs b/src/parser.rs index 57f53143..c4eafe9f 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -3,8 +3,8 @@ //! This module should not be used directly, unless you're planning to parse //! some tables manually. -use core::ops::Range; use core::convert::{TryFrom, TryInto}; +use core::ops::Range; /// A trait for parsing raw binary data of fixed size. /// @@ -117,7 +117,6 @@ impl FromData for U24 { } } - /// A 16-bit signed fixed number with the low 14 bits of fraction (2.14). #[derive(Clone, Copy, Debug)] pub struct F2DOT14(pub i16); @@ -139,7 +138,6 @@ impl FromData for F2DOT14 { } } - /// A 32-bit signed fixed-point number (16.16). #[derive(Clone, Copy, Debug)] pub struct Fixed(pub f32); @@ -154,7 +152,6 @@ impl FromData for Fixed { } } - /// A safe u32 to usize casting. /// /// Rust doesn't implement `From for usize`, @@ -189,7 +186,6 @@ impl NumFrom for usize { } } - /// Just like TryFrom, but for numeric types not supported by the Rust's std. pub trait TryNumFrom: Sized { /// Casts between numeric types. @@ -239,7 +235,6 @@ impl TryNumFrom for i32 { } } - /// A slice-like container that converts internal binary data only on access. /// /// Array values are stored in a continuous data chunk. @@ -317,7 +312,8 @@ impl<'a, T: FromData> LazyArray16<'a, T> { /// Performs a binary search by specified `key`. #[inline] pub fn binary_search(&self, key: &T) -> Option<(u16, T)> - where T: Ord + where + T: Ord, { self.binary_search_by(|p| p.cmp(key)) } @@ -325,7 +321,8 @@ impl<'a, T: FromData> LazyArray16<'a, T> { /// Performs a binary search using specified closure. #[inline] pub fn binary_search_by(&self, mut f: F) -> Option<(u16, T)> - where F: FnMut(&T) -> core::cmp::Ordering + where + F: FnMut(&T) -> core::cmp::Ordering, { // Based on Rust std implementation. @@ -350,7 +347,11 @@ impl<'a, T: FromData> LazyArray16<'a, T> { // base is always in [0, size) because base <= mid. let value = self.get(base)?; - if f(&value) == Ordering::Equal { Some((base, value)) } else { None } + if f(&value) == Ordering::Equal { + Some((base, value)) + } else { + None + } } } @@ -373,7 +374,6 @@ impl<'a, T: FromData> IntoIterator for LazyArray16<'a, T> { } } - /// An iterator over `LazyArray16`. #[derive(Clone, Copy)] #[allow(missing_debug_implementations)] @@ -407,7 +407,6 @@ impl<'a, T: FromData> Iterator for LazyArrayIter16<'a, T> { } } - /// A slice-like container that converts internal binary data only on access. /// /// This is a low-level, internal structure that should not be used directly. @@ -458,7 +457,8 @@ impl<'a, T: FromData> LazyArray32<'a, T> { /// Performs a binary search by specified `key`. #[inline] pub fn binary_search(&self, key: &T) -> Option<(u32, T)> - where T: Ord + where + T: Ord, { self.binary_search_by(|p| p.cmp(key)) } @@ -466,7 +466,8 @@ impl<'a, T: FromData> LazyArray32<'a, T> { /// Performs a binary search using specified closure. #[inline] pub fn binary_search_by(&self, mut f: F) -> Option<(u32, T)> - where F: FnMut(&T) -> core::cmp::Ordering + where + F: FnMut(&T) -> core::cmp::Ordering, { // Based on Rust std implementation. @@ -491,7 +492,11 @@ impl<'a, T: FromData> LazyArray32<'a, T> { // base is always in [0, size) because base <= mid. let value = self.get(base)?; - if f(&value) == Ordering::Equal { Some((base, value)) } else { None } + if f(&value) == Ordering::Equal { + Some((base, value)) + } else { + None + } } } @@ -514,7 +519,6 @@ impl<'a, T: FromData> IntoIterator for LazyArray32<'a, T> { } } - /// An iterator over `LazyArray32`. #[derive(Clone, Copy)] #[allow(missing_debug_implementations)] @@ -538,7 +542,6 @@ impl<'a, T: FromData> Iterator for LazyArrayIter32<'a, T> { } } - /// A [`LazyArray16`]-like container, but data is accessed by offsets. /// /// Unlike [`LazyArray16`], internal storage is not continuous. @@ -556,7 +559,11 @@ impl<'a, T: FromSlice<'a>> LazyOffsetArray16<'a, T> { /// Creates a new `LazyOffsetArray16`. #[allow(dead_code)] pub fn new(data: &'a [u8], offsets: LazyArray16<'a, Option>) -> Self { - Self { data, offsets, data_type: core::marker::PhantomData } + Self { + data, + offsets, + data_type: core::marker::PhantomData, + } } /// Parses `LazyOffsetArray16` from raw data. @@ -565,7 +572,11 @@ impl<'a, T: FromSlice<'a>> LazyOffsetArray16<'a, T> { let mut s = Stream::new(data); let count = s.read::()?; let offsets = s.read_array16(count)?; - Some(Self { data, offsets, data_type: core::marker::PhantomData }) + Some(Self { + data, + offsets, + data_type: core::marker::PhantomData, + }) } /// Returns a value at `index`. @@ -634,7 +645,6 @@ impl<'a, T: FromSlice<'a>> Iterator for LazyOffsetArrayIter16<'a, T> { } } - /// A streaming binary parser. #[derive(Clone, Copy, Default, Debug)] pub struct Stream<'a> { @@ -774,17 +784,17 @@ impl<'a> Stream<'a> { } } - /// A common offset methods. pub trait Offset { /// Converts the offset to `usize`. fn to_usize(&self) -> usize; /// Checks that offset is null. - fn is_null(&self) -> bool { self.to_usize() == 0 } + fn is_null(&self) -> bool { + self.to_usize() == 0 + } } - /// A type-safe u16 offset. #[derive(Clone, Copy, Debug)] pub struct Offset16(pub u16); @@ -811,11 +821,14 @@ impl FromData for Option { #[inline] fn parse(data: &[u8]) -> Option { let offset = Offset16::parse(data)?; - if offset.0 != 0 { Some(Some(offset)) } else { Some(None) } + if offset.0 != 0 { + Some(Some(offset)) + } else { + Some(None) + } } } - /// A type-safe u32 offset. #[derive(Clone, Copy, Debug)] pub struct Offset32(pub u32); @@ -836,18 +849,20 @@ impl FromData for Offset32 { } } - impl FromData for Option { const SIZE: usize = Offset32::SIZE; #[inline] fn parse(data: &[u8]) -> Option { let offset = Offset32::parse(data)?; - if offset.0 != 0 { Some(Some(offset)) } else { Some(None) } + if offset.0 != 0 { + Some(Some(offset)) + } else { + Some(None) + } } } - #[inline] pub(crate) fn i16_bound(min: i16, val: i16, max: i16) -> i16 { use core::cmp; diff --git a/src/tables/ankr.rs b/src/tables/ankr.rs index 890623a1..78437b0d 100644 --- a/src/tables/ankr.rs +++ b/src/tables/ankr.rs @@ -3,9 +3,9 @@ use core::num::NonZeroU16; -use crate::GlyphId; -use crate::parser::{Stream, FromData, LazyArray32}; use crate::aat; +use crate::parser::{FromData, LazyArray32, Stream}; +use crate::GlyphId; /// An anchor point. #[allow(missing_docs)] @@ -28,7 +28,6 @@ impl FromData for Point { } } - /// An [Anchor Point Table]( /// https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6ankr.html). #[derive(Clone)] @@ -59,6 +58,7 @@ impl<'a> Table<'a> { } s.skip::(); // reserved + // TODO: we should probably check that offset is larger than the header size (8) let lookup_table = s.read_at_offset32(data)?; let glyphs_data = s.read_at_offset32(data)?; diff --git a/src/tables/avar.rs b/src/tables/avar.rs index 578343a2..b4ba1fc6 100644 --- a/src/tables/avar.rs +++ b/src/tables/avar.rs @@ -3,8 +3,8 @@ use core::convert::TryFrom; +use crate::parser::{FromData, LazyArray16, Stream}; use crate::NormalizedCoordinate; -use crate::parser::{Stream, FromData, LazyArray16}; /// An axis value map. #[derive(Clone, Copy, Debug)] @@ -28,7 +28,6 @@ impl FromData for AxisValueMap { } } - /// A list of segment maps. /// /// Can be empty. @@ -81,7 +80,6 @@ impl<'a> Iterator for SegmentMapsIter<'a> { } } - /// An [Axis Variations Table]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/avar). #[derive(Clone, Copy, Debug)] diff --git a/src/tables/cbdt.rs b/src/tables/cbdt.rs index 2e9d6dea..ed179673 100644 --- a/src/tables/cbdt.rs +++ b/src/tables/cbdt.rs @@ -1,9 +1,9 @@ //! A [Color Bitmap Data Table]( //! https://docs.microsoft.com/en-us/typography/opentype/spec/cbdt) implementation. -use crate::{GlyphId, RasterGlyphImage, RasterImageFormat}; -use crate::parser::{Stream, NumFrom}; use super::cblc::{self, BitmapFormat}; +use crate::parser::{NumFrom, Stream}; +use crate::{GlyphId, RasterGlyphImage, RasterImageFormat}; /// A [Color Bitmap Data Table]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/cbdt). diff --git a/src/tables/cblc.rs b/src/tables/cblc.rs index e485253b..9e507fb2 100644 --- a/src/tables/cblc.rs +++ b/src/tables/cblc.rs @@ -1,8 +1,8 @@ //! A [Color Bitmap Location Table]( //! https://docs.microsoft.com/en-us/typography/opentype/spec/cblc) implementation. +use crate::parser::{FromData, NumFrom, Offset, Offset16, Offset32, Stream}; use crate::GlyphId; -use crate::parser::{Stream, FromData, Offset, Offset16, Offset32, NumFrom}; #[derive(Clone, Copy, PartialEq, Debug)] pub(crate) enum BitmapFormat { @@ -58,7 +58,9 @@ fn select_bitmap_size_table( } // Select a best matching subtable based on `pixels_per_em`. - if (pixels_per_em <= ppem && ppem < max_ppem) || (pixels_per_em > max_ppem && ppem > max_ppem) { + if (pixels_per_em <= ppem && ppem < max_ppem) + || (pixels_per_em > max_ppem && ppem > max_ppem) + { idx = Some(usize::num_from(i)); max_ppem = ppem; } @@ -78,7 +80,6 @@ fn select_bitmap_size_table( }) } - #[derive(Clone, Copy)] struct IndexSubtableInfo { start_glyph_id: GlyphId, @@ -101,14 +102,13 @@ fn select_index_subtable( return Some(IndexSubtableInfo { start_glyph_id, offset, - }) + }); } } None } - #[derive(Clone, Copy)] struct GlyphIdOffsetPair { glyph_id: GlyphId, @@ -143,11 +143,7 @@ impl<'a> Table<'a> { Some(Self { data }) } - pub(crate) fn get( - &self, - glyph_id: GlyphId, - pixels_per_em: u16, - ) -> Option { + pub(crate) fn get(&self, glyph_id: GlyphId, pixels_per_em: u16) -> Option { let mut s = Stream::new(self.data); // The CBLC table version is a bit tricky, so we are ignoring it for now. @@ -204,8 +200,9 @@ impl<'a> Table<'a> { let num_glyphs = s.read::()?; let glyphs = s.read_array32::(num_glyphs)?; let (index, _) = glyphs.binary_search(&glyph_id)?; - image_offset = image_offset - .checked_add(usize::num_from(index).checked_mul(usize::num_from(image_size))?)?; + image_offset = image_offset.checked_add( + usize::num_from(index).checked_mul(usize::num_from(image_size))?, + )?; } _ => return None, // Invalid format. } diff --git a/src/tables/cff/cff1.rs b/src/tables/cff/cff1.rs index fc4d980c..5cf54e0e 100644 --- a/src/tables/cff/cff1.rs +++ b/src/tables/cff/cff1.rs @@ -7,19 +7,20 @@ // https://github.com/opentypejs/opentype.js/blob/master/src/tables/cff.js use core::convert::TryFrom; -use core::ops::Range; use core::num::NonZeroU16; +use core::ops::Range; -use crate::{GlyphId, OutlineBuilder, Rect, BBox, Fixed}; -use crate::parser::{Stream, LazyArray16, NumFrom, TryNumFrom}; -use super::{Builder, IsEven, CFFError, StringId, calc_subroutine_bias, conv_subroutine_index}; use super::argstack::ArgumentsStack; -use super::charset::{Charset, parse_charset}; +use super::charset::{parse_charset, Charset}; use super::charstring::CharStringParser; use super::dict::DictionaryParser; -use super::encoding::{STANDARD_ENCODING, Encoding, parse_encoding}; -use super::index::{Index, parse_index, skip_index}; -#[cfg(feature = "glyph-names")] use super::std_names::STANDARD_NAMES; +use super::encoding::{parse_encoding, Encoding, STANDARD_ENCODING}; +use super::index::{parse_index, skip_index, Index}; +#[cfg(feature = "glyph-names")] +use super::std_names::STANDARD_NAMES; +use super::{calc_subroutine_bias, conv_subroutine_index, Builder, CFFError, IsEven, StringId}; +use crate::parser::{LazyArray16, NumFrom, Stream, TryNumFrom}; +use crate::{BBox, Fixed, GlyphId, OutlineBuilder, Rect}; // Limits according to the Adobe Technical Note #5176, chapter 4 DICT Data. const MAX_OPERANDS_LEN: usize = 48; @@ -32,48 +33,48 @@ const TWO_BYTE_OPERATOR_MARK: u8 = 12; /// Enumerates some operators defined in the Adobe Technical Note #5177. mod operator { - pub const HORIZONTAL_STEM: u8 = 1; - pub const VERTICAL_STEM: u8 = 3; - pub const VERTICAL_MOVE_TO: u8 = 4; - pub const LINE_TO: u8 = 5; - pub const HORIZONTAL_LINE_TO: u8 = 6; - pub const VERTICAL_LINE_TO: u8 = 7; - pub const CURVE_TO: u8 = 8; - pub const CALL_LOCAL_SUBROUTINE: u8 = 10; - pub const RETURN: u8 = 11; - pub const ENDCHAR: u8 = 14; + pub const HORIZONTAL_STEM: u8 = 1; + pub const VERTICAL_STEM: u8 = 3; + pub const VERTICAL_MOVE_TO: u8 = 4; + pub const LINE_TO: u8 = 5; + pub const HORIZONTAL_LINE_TO: u8 = 6; + pub const VERTICAL_LINE_TO: u8 = 7; + pub const CURVE_TO: u8 = 8; + pub const CALL_LOCAL_SUBROUTINE: u8 = 10; + pub const RETURN: u8 = 11; + pub const ENDCHAR: u8 = 14; pub const HORIZONTAL_STEM_HINT_MASK: u8 = 18; - pub const HINT_MASK: u8 = 19; - pub const COUNTER_MASK: u8 = 20; - pub const MOVE_TO: u8 = 21; - pub const HORIZONTAL_MOVE_TO: u8 = 22; - pub const VERTICAL_STEM_HINT_MASK: u8 = 23; - pub const CURVE_LINE: u8 = 24; - pub const LINE_CURVE: u8 = 25; - pub const VV_CURVE_TO: u8 = 26; - pub const HH_CURVE_TO: u8 = 27; - pub const SHORT_INT: u8 = 28; - pub const CALL_GLOBAL_SUBROUTINE: u8 = 29; - pub const VH_CURVE_TO: u8 = 30; - pub const HV_CURVE_TO: u8 = 31; - pub const HFLEX: u8 = 34; - pub const FLEX: u8 = 35; - pub const HFLEX1: u8 = 36; - pub const FLEX1: u8 = 37; - pub const FIXED_16_16: u8 = 255; + pub const HINT_MASK: u8 = 19; + pub const COUNTER_MASK: u8 = 20; + pub const MOVE_TO: u8 = 21; + pub const HORIZONTAL_MOVE_TO: u8 = 22; + pub const VERTICAL_STEM_HINT_MASK: u8 = 23; + pub const CURVE_LINE: u8 = 24; + pub const LINE_CURVE: u8 = 25; + pub const VV_CURVE_TO: u8 = 26; + pub const HH_CURVE_TO: u8 = 27; + pub const SHORT_INT: u8 = 28; + pub const CALL_GLOBAL_SUBROUTINE: u8 = 29; + pub const VH_CURVE_TO: u8 = 30; + pub const HV_CURVE_TO: u8 = 31; + pub const HFLEX: u8 = 34; + pub const FLEX: u8 = 35; + pub const HFLEX1: u8 = 36; + pub const FLEX1: u8 = 37; + pub const FIXED_16_16: u8 = 255; } /// Enumerates some operators defined in the Adobe Technical Note #5176, /// Table 9 Top DICT Operator Entries mod top_dict_operator { - pub const CHARSET_OFFSET: u16 = 15; - pub const ENCODING_OFFSET: u16 = 16; - pub const CHAR_STRINGS_OFFSET: u16 = 17; + pub const CHARSET_OFFSET: u16 = 15; + pub const ENCODING_OFFSET: u16 = 16; + pub const CHAR_STRINGS_OFFSET: u16 = 17; pub const PRIVATE_DICT_SIZE_AND_OFFSET: u16 = 18; - pub const FONT_MATRIX: u16 = 1207; - pub const ROS: u16 = 1230; - pub const FD_ARRAY: u16 = 1236; - pub const FD_SELECT: u16 = 1237; + pub const FONT_MATRIX: u16 = 1207; + pub const ROS: u16 = 1230; + pub const FD_ARRAY: u16 = 1236; + pub const FD_SELECT: u16 = 1237; } /// Enumerates some operators defined in the Adobe Technical Note #5176, @@ -133,7 +134,14 @@ pub struct Matrix { impl Default for Matrix { fn default() -> Self { - Self { sx: 0.001, ky: 0.0, kx: 0.0, sy: 0.001, tx: 0.0, ty: 0.0 } + Self { + sx: 0.001, + ky: 0.0, + kx: 0.0, + sy: 0.001, + tx: 0.0, + ty: 0.0, + } } } @@ -217,7 +225,7 @@ mod tests { 0x0C, // index [1]: 14 0x1D, 0x7F, 0xFF, 0xFF, 0xFF, // length: i32::MAX 0x1D, 0x7F, 0xFF, 0xFF, 0xFF, // offset: i32::MAX - 0x12 // operator: 18 (private) + 0x12, // operator: 18 (private) ]; let top_dict = parse_top_dict(&mut Stream::new(data)).unwrap(); @@ -399,7 +407,6 @@ fn parse_char_string( bbox.to_rect().ok_or(CFFError::BboxOverflow) } - fn _parse_char_string( ctx: &mut CharStringParserContext, char_string: &[u8], @@ -414,10 +421,10 @@ fn _parse_char_string( // Reserved. return Err(CFFError::InvalidOperator); } - operator::HORIZONTAL_STEM | - operator::VERTICAL_STEM | - operator::HORIZONTAL_STEM_HINT_MASK | - operator::VERTICAL_STEM_HINT_MASK => { + operator::HORIZONTAL_STEM + | operator::VERTICAL_STEM + | operator::HORIZONTAL_STEM_HINT_MASK + | operator::VERTICAL_STEM_HINT_MASK => { // y dy {dya dyb}* hstem // x dx {dxa dxb}* vstem // y dy {dya dyb}* hstemhm @@ -471,16 +478,17 @@ fn _parse_char_string( // a local subroutine is actually requested by the glyphs charstring. if ctx.local_subrs.is_none() { if let FontKind::CID(ref cid) = ctx.metadata.kind { - ctx.local_subrs = parse_cid_local_subrs( - ctx.metadata.table_data, ctx.glyph_id, cid - ); + ctx.local_subrs = + parse_cid_local_subrs(ctx.metadata.table_data, ctx.glyph_id, cid); } } if let Some(local_subrs) = ctx.local_subrs { let subroutine_bias = calc_subroutine_bias(local_subrs.len()); let index = conv_subroutine_index(p.stack.pop(), subroutine_bias)?; - let char_string = local_subrs.get(index).ok_or(CFFError::InvalidSubroutineIndex)?; + let char_string = local_subrs + .get(index) + .ok_or(CFFError::InvalidSubroutineIndex)?; _parse_char_string(ctx, char_string, depth + 1, p)?; } else { return Err(CFFError::NoLocalSubroutines); @@ -529,13 +537,19 @@ fn _parse_char_string( return Err(CFFError::NestingLimitReached); } - let base_char_string = ctx.metadata.char_strings.get(u32::from(base_char.0)) + let base_char_string = ctx + .metadata + .char_strings + .get(u32::from(base_char.0)) .ok_or(CFFError::InvalidSeacCode)?; _parse_char_string(ctx, base_char_string, depth + 1, p)?; p.x = dx; p.y = dy; - let accent_char_string = ctx.metadata.char_strings.get(u32::from(accent_char.0)) + let accent_char_string = ctx + .metadata + .char_strings + .get(u32::from(accent_char.0)) .ok_or(CFFError::InvalidSeacCode)?; _parse_char_string(ctx, accent_char_string, depth + 1, p)?; } else if p.stack.len() == 1 && !ctx.width_parsed { @@ -617,7 +631,10 @@ fn _parse_char_string( let subroutine_bias = calc_subroutine_bias(ctx.metadata.global_subrs.len()); let index = conv_subroutine_index(p.stack.pop(), subroutine_bias)?; - let char_string = ctx.metadata.global_subrs.get(index) + let char_string = ctx + .metadata + .global_subrs + .get(index) .ok_or(CFFError::InvalidSubroutineIndex)?; _parse_char_string(ctx, char_string, depth + 1, p)?; @@ -664,7 +681,11 @@ fn seac_code_to_glyph_id(charset: &Charset, n: f32) -> Option { match charset { Charset::ISOAdobe => { // ISO Adobe charset only defines string ids up to 228 (zcaron) - if code <= 228 { Some(GlyphId(sid.0)) } else { None } + if code <= 228 { + Some(GlyphId(sid.0)) + } else { + None + } } Charset::Expert | Charset::ExpertSubset => None, _ => charset.sid_to_gid(sid), @@ -687,22 +708,19 @@ fn parse_char_string_width(data: &[u8]) -> Option { } // Just like `_parse_char_string`, but parses only the first operator. -fn _parse_char_string_width( - char_string: &[u8], - stack: &mut ArgumentsStack, -) -> Option { +fn _parse_char_string_width(char_string: &[u8], stack: &mut ArgumentsStack) -> Option { let mut s = Stream::new(char_string); while !s.at_end() { let op = s.read::()?; match op { - operator::HORIZONTAL_STEM | - operator::VERTICAL_STEM | - operator::HORIZONTAL_STEM_HINT_MASK | - operator::VERTICAL_STEM_HINT_MASK | - operator::HINT_MASK | - operator::COUNTER_MASK | - operator::MOVE_TO | - operator::ENDCHAR => { + operator::HORIZONTAL_STEM + | operator::VERTICAL_STEM + | operator::HORIZONTAL_STEM_HINT_MASK + | operator::VERTICAL_STEM_HINT_MASK + | operator::HINT_MASK + | operator::COUNTER_MASK + | operator::MOVE_TO + | operator::ENDCHAR => { return if stack.len().is_odd() { Some(stack.at(0)) } else { @@ -750,7 +768,6 @@ fn _parse_char_string_width( None } - #[derive(Clone, Copy, Debug)] enum FDSelect<'a> { Format0(LazyArray16<'a, u8>), @@ -819,13 +836,16 @@ fn parse_sid_metadata<'a>( let private_dict = if let Some(range) = top_dict.private_dict_range.clone() { parse_private_dict(data.get(range)?) } else { - return Some(FontKind::SID(metadata)) + return Some(FontKind::SID(metadata)); }; metadata.default_width = private_dict.default_width.unwrap_or(0.0); metadata.nominal_width = private_dict.nominal_width.unwrap_or(0.0); - match (top_dict.private_dict_range, private_dict.local_subroutines_offset) { + match ( + top_dict.private_dict_range, + private_dict.local_subroutines_offset, + ) { (Some(private_dict_range), Some(subroutines_offset)) => { // 'The local subroutines offset is relative to the beginning // of the Private DICT data.' @@ -842,11 +862,14 @@ fn parse_sid_metadata<'a>( } fn parse_cid_metadata(data: &[u8], top_dict: TopDict, number_of_glyphs: u16) -> Option { - let (charset_offset, fd_array_offset, fd_select_offset) = - match (top_dict.charset_offset, top_dict.fd_array_offset, top_dict.fd_select_offset) { - (Some(a), Some(b), Some(c)) => (a, b, c), - _ => return None, // charset, FDArray and FDSelect must be set. - }; + let (charset_offset, fd_array_offset, fd_select_offset) = match ( + top_dict.charset_offset, + top_dict.fd_array_offset, + top_dict.fd_select_offset, + ) { + (Some(a), Some(b), Some(c)) => (a, b, c), + _ => return None, // charset, FDArray and FDSelect must be set. + }; if charset_offset <= charset_id::EXPERT_SUBSET { // 'There are no predefined charsets for CID fonts.' @@ -869,7 +892,6 @@ fn parse_cid_metadata(data: &[u8], top_dict: TopDict, number_of_glyphs: u16) -> Some(FontKind::CID(metadata)) } - /// A [Compact Font Format Table]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/cff). #[derive(Clone, Copy)] @@ -878,7 +900,8 @@ pub struct Table<'a> { // Used to resolve a local subroutine in a CID font. table_data: &'a [u8], - #[allow(dead_code)] strings: Index<'a>, + #[allow(dead_code)] + strings: Index<'a>, global_subrs: Index<'a>, charset: Charset<'a>, number_of_glyphs: NonZeroU16, @@ -929,7 +952,9 @@ impl<'a> Table<'a> { }; // 'The number of glyphs is the value of the count field in the CharStrings INDEX.' - let number_of_glyphs = u16::try_from(char_strings.len()).ok().and_then(NonZeroU16::new)?; + let number_of_glyphs = u16::try_from(char_strings.len()) + .ok() + .and_then(NonZeroU16::new)?; let charset = match top_dict.charset_offset { Some(charset_id::ISO_ADOBE) => Charset::ISOAdobe, @@ -990,7 +1015,10 @@ impl<'a> Table<'a> { glyph_id: GlyphId, builder: &mut dyn OutlineBuilder, ) -> Result { - let data = self.char_strings.get(u32::from(glyph_id.0)).ok_or(CFFError::NoGlyph)?; + let data = self + .char_strings + .get(u32::from(glyph_id.0)) + .ok_or(CFFError::NoGlyph)?; parse_char_string(data, self, glyph_id, builder) } @@ -1040,7 +1068,10 @@ impl<'a> Table<'a> { let sid = if let Some(index) = STANDARD_NAMES.iter().position(|n| *n == name) { StringId(index as u16) } else { - let index = self.strings.into_iter().position(|n| n == name.as_bytes())?; + let index = self + .strings + .into_iter() + .position(|n| n == name.as_bytes())?; StringId((STANDARD_NAMES.len() + index) as u16) }; diff --git a/src/tables/cff/cff2.rs b/src/tables/cff/cff2.rs index a51879d6..2421cfa4 100644 --- a/src/tables/cff/cff2.rs +++ b/src/tables/cff/cff2.rs @@ -6,14 +6,14 @@ use core::convert::TryFrom; use core::ops::Range; -use crate::{GlyphId, OutlineBuilder, Rect, BBox, NormalizedCoordinate}; -use crate::parser::{Stream, NumFrom, TryNumFrom}; -use crate::var_store::*; -use super::{Builder, CFFError, calc_subroutine_bias, conv_subroutine_index}; use super::argstack::ArgumentsStack; use super::charstring::CharStringParser; use super::dict::DictionaryParser; -use super::index::{Index, parse_index}; +use super::index::{parse_index, Index}; +use super::{calc_subroutine_bias, conv_subroutine_index, Builder, CFFError}; +use crate::parser::{NumFrom, Stream, TryNumFrom}; +use crate::var_store::*; +use crate::{BBox, GlyphId, NormalizedCoordinate, OutlineBuilder, Rect}; // https://docs.microsoft.com/en-us/typography/opentype/spec/cff2#7-top-dict-data // 'Operators in DICT may be preceded by up to a maximum of 513 operands.' @@ -27,42 +27,42 @@ const TWO_BYTE_OPERATOR_MARK: u8 = 12; // https://docs.microsoft.com/en-us/typography/opentype/spec/cff2charstr#4-charstring-operators mod operator { - pub const HORIZONTAL_STEM: u8 = 1; - pub const VERTICAL_STEM: u8 = 3; - pub const VERTICAL_MOVE_TO: u8 = 4; - pub const LINE_TO: u8 = 5; - pub const HORIZONTAL_LINE_TO: u8 = 6; - pub const VERTICAL_LINE_TO: u8 = 7; - pub const CURVE_TO: u8 = 8; - pub const CALL_LOCAL_SUBROUTINE: u8 = 10; - pub const VS_INDEX: u8 = 15; - pub const BLEND: u8 = 16; + pub const HORIZONTAL_STEM: u8 = 1; + pub const VERTICAL_STEM: u8 = 3; + pub const VERTICAL_MOVE_TO: u8 = 4; + pub const LINE_TO: u8 = 5; + pub const HORIZONTAL_LINE_TO: u8 = 6; + pub const VERTICAL_LINE_TO: u8 = 7; + pub const CURVE_TO: u8 = 8; + pub const CALL_LOCAL_SUBROUTINE: u8 = 10; + pub const VS_INDEX: u8 = 15; + pub const BLEND: u8 = 16; pub const HORIZONTAL_STEM_HINT_MASK: u8 = 18; - pub const HINT_MASK: u8 = 19; - pub const COUNTER_MASK: u8 = 20; - pub const MOVE_TO: u8 = 21; - pub const HORIZONTAL_MOVE_TO: u8 = 22; - pub const VERTICAL_STEM_HINT_MASK: u8 = 23; - pub const CURVE_LINE: u8 = 24; - pub const LINE_CURVE: u8 = 25; - pub const VV_CURVE_TO: u8 = 26; - pub const HH_CURVE_TO: u8 = 27; - pub const SHORT_INT: u8 = 28; - pub const CALL_GLOBAL_SUBROUTINE: u8 = 29; - pub const VH_CURVE_TO: u8 = 30; - pub const HV_CURVE_TO: u8 = 31; - pub const HFLEX: u8 = 34; - pub const FLEX: u8 = 35; - pub const HFLEX1: u8 = 36; - pub const FLEX1: u8 = 37; - pub const FIXED_16_16: u8 = 255; + pub const HINT_MASK: u8 = 19; + pub const COUNTER_MASK: u8 = 20; + pub const MOVE_TO: u8 = 21; + pub const HORIZONTAL_MOVE_TO: u8 = 22; + pub const VERTICAL_STEM_HINT_MASK: u8 = 23; + pub const CURVE_LINE: u8 = 24; + pub const LINE_CURVE: u8 = 25; + pub const VV_CURVE_TO: u8 = 26; + pub const HH_CURVE_TO: u8 = 27; + pub const SHORT_INT: u8 = 28; + pub const CALL_GLOBAL_SUBROUTINE: u8 = 29; + pub const VH_CURVE_TO: u8 = 30; + pub const HV_CURVE_TO: u8 = 31; + pub const HFLEX: u8 = 34; + pub const FLEX: u8 = 35; + pub const HFLEX1: u8 = 36; + pub const FLEX1: u8 = 37; + pub const FIXED_16_16: u8 = 255; } // https://docs.microsoft.com/en-us/typography/opentype/spec/cff2#table-9-top-dict-operator-entries mod top_dict_operator { - pub const CHAR_STRINGS_OFFSET: u16 = 17; - pub const VARIATION_STORE_OFFSET: u16 = 24; - pub const FONT_DICT_INDEX_OFFSET: u16 = 1236; + pub const CHAR_STRINGS_OFFSET: u16 = 17; + pub const VARIATION_STORE_OFFSET: u16 = 24; + pub const FONT_DICT_INDEX_OFFSET: u16 = 1236; } // https://docs.microsoft.com/en-us/typography/opentype/spec/cff2#table-10-font-dict-operator-entries @@ -149,7 +149,6 @@ fn parse_private_dict(data: &[u8]) -> Option { subroutines_offset } - /// CFF2 allows up to 65535 scalars, but an average font will have 3-5. /// So 64 is more than enough. const SCALARS_MAX: u8 = 64; @@ -197,7 +196,6 @@ impl Scalars { } } - struct CharStringParserContext<'a> { metadata: &'a Table<'a>, coordinates: &'a [NormalizedCoordinate], @@ -211,12 +209,19 @@ impl CharStringParserContext<'_> { fn update_scalars(&mut self, index: u16) -> Result<(), CFFError> { self.scalars.clear(); - let indices = self.metadata.item_variation_store.region_indices(index) + let indices = self + .metadata + .item_variation_store + .region_indices(index) .ok_or(CFFError::InvalidItemVariationDataIndex)?; for index in indices { - let scalar = self.metadata.item_variation_store.regions + let scalar = self + .metadata + .item_variation_store + .regions .evaluate_region(index, self.coordinates); - self.scalars.push(scalar) + self.scalars + .push(scalar) .ok_or(CFFError::BlendRegionsLimitReached)?; } @@ -224,7 +229,6 @@ impl CharStringParserContext<'_> { } } - fn parse_char_string( data: &[u8], metadata: &Table, @@ -288,10 +292,10 @@ fn _parse_char_string( // Reserved. return Err(CFFError::InvalidOperator); } - operator::HORIZONTAL_STEM | - operator::VERTICAL_STEM | - operator::HORIZONTAL_STEM_HINT_MASK | - operator::VERTICAL_STEM_HINT_MASK => { + operator::HORIZONTAL_STEM + | operator::VERTICAL_STEM + | operator::HORIZONTAL_STEM_HINT_MASK + | operator::VERTICAL_STEM_HINT_MASK => { // y dy {dya dyb}* hstem // x dx {dxa dxb}* vstem // y dy {dya dyb}* hstemhm @@ -328,7 +332,10 @@ fn _parse_char_string( let subroutine_bias = calc_subroutine_bias(ctx.metadata.local_subrs.len()); let index = conv_subroutine_index(p.stack.pop(), subroutine_bias)?; - let char_string = ctx.metadata.local_subrs.get(index) + let char_string = ctx + .metadata + .local_subrs + .get(index) .ok_or(CFFError::InvalidSubroutineIndex)?; _parse_char_string(ctx, char_string, depth + 1, p)?; } @@ -428,7 +435,10 @@ fn _parse_char_string( let subroutine_bias = calc_subroutine_bias(ctx.metadata.global_subrs.len()); let index = conv_subroutine_index(p.stack.pop(), subroutine_bias)?; - let char_string = ctx.metadata.global_subrs.get(index) + let char_string = ctx + .metadata + .global_subrs + .get(index) .ok_or(CFFError::InvalidSubroutineIndex)?; _parse_char_string(ctx, char_string, depth + 1, p)?; } @@ -456,7 +466,6 @@ fn _parse_char_string( Ok(()) } - /// A [Compact Font Format 2 Table]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/cff2). #[derive(Clone, Copy, Default)] @@ -516,7 +525,9 @@ impl<'a> Table<'a> { if let Some(subroutines_offset) = parse_private_dict(private_dict_data) { // 'The local subroutines offset is relative to the beginning // of the Private DICT data.' - if let Some(start) = private_dict_range.start.checked_add(subroutines_offset) { + if let Some(start) = + private_dict_range.start.checked_add(subroutines_offset) + { let data = data.get(start..data.len())?; let mut s = Stream::new(data); metadata.local_subrs = parse_index::(&mut s)?; @@ -537,7 +548,10 @@ impl<'a> Table<'a> { glyph_id: GlyphId, builder: &mut dyn OutlineBuilder, ) -> Result { - let data = self.char_strings.get(u32::from(glyph_id.0)).ok_or(CFFError::NoGlyph)?; + let data = self + .char_strings + .get(u32::from(glyph_id.0)) + .ok_or(CFFError::NoGlyph)?; parse_char_string(data, self, coordinates, builder) } } diff --git a/src/tables/cff/charset.rs b/src/tables/cff/charset.rs index 45aeee66..ab53672b 100644 --- a/src/tables/cff/charset.rs +++ b/src/tables/cff/charset.rs @@ -1,8 +1,9 @@ -use crate::GlyphId; -use crate::parser::{Stream, FromData, LazyArray16}; use super::StringId; +use crate::parser::{FromData, LazyArray16, Stream}; +use crate::GlyphId; /// The Expert Encoding conversion as defined in the Adobe Technical Note #5176 Appendix C. +#[rustfmt::skip] #[cfg(feature = "glyph-names")] const EXPERT_ENCODING: &[u16] = &[ 0, 1, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 13, 14, 15, 99, @@ -19,6 +20,7 @@ const EXPERT_ENCODING: &[u16] = &[ ]; /// The Expert Subset Encoding conversion as defined in the Adobe Technical Note #5176 Appendix C. +#[rustfmt::skip] #[cfg(feature = "glyph-names")] const EXPERT_SUBSET_ENCODING: &[u16] = &[ 0, 1, 231, 232, 235, 236, 237, 238, 13, 14, 15, 99, 239, 240, 241, 242, @@ -29,7 +31,6 @@ const EXPERT_SUBSET_ENCODING: &[u16] = &[ 340, 341, 342, 343, 344, 345, 346 ]; - #[derive(Clone, Copy, Debug)] pub(crate) struct Format1Range { first: StringId, @@ -49,7 +50,6 @@ impl FromData for Format1Range { } } - #[derive(Clone, Copy, Debug)] pub(crate) struct Format2Range { first: StringId, @@ -69,7 +69,6 @@ impl FromData for Format2Range { } } - #[derive(Clone, Copy, Debug)] pub(crate) enum Charset<'a> { ISOAdobe, @@ -90,7 +89,10 @@ impl Charset<'_> { Charset::ISOAdobe | Charset::Expert | Charset::ExpertSubset => None, Charset::Format0(ref array) => { // First glyph is omitted, so we have to add 1. - array.into_iter().position(|n| n == sid).map(|n| GlyphId(n as u16 + 1)) + array + .into_iter() + .position(|n| n == sid) + .map(|n| GlyphId(n as u16 + 1)) } Charset::Format1(array) => { let mut glyph_id = GlyphId(1); @@ -98,7 +100,7 @@ impl Charset<'_> { let last = u32::from(range.first.0) + u32::from(range.left); if range.first <= sid && u32::from(sid.0) <= last { glyph_id.0 += sid.0 - range.first.0; - return Some(glyph_id) + return Some(glyph_id); } glyph_id.0 += u16::from(range.left) + 1; @@ -113,7 +115,7 @@ impl Charset<'_> { let last = u32::from(range.first.0) + u32::from(range.left); if sid >= range.first && u32::from(sid.0) <= last { glyph_id.0 += sid.0 - range.first.0; - return Some(glyph_id) + return Some(glyph_id); } glyph_id.0 += range.left + 1; @@ -128,14 +130,20 @@ impl Charset<'_> { pub fn gid_to_sid(&self, gid: GlyphId) -> Option { match self { Charset::ISOAdobe => { - if gid.0 <= 228 { Some(StringId(gid.0)) } else { None } - } - Charset::Expert => { - EXPERT_ENCODING.get(usize::from(gid.0)).cloned().map(StringId) - } - Charset::ExpertSubset => { - EXPERT_SUBSET_ENCODING.get(usize::from(gid.0)).cloned().map(StringId) + if gid.0 <= 228 { + Some(StringId(gid.0)) + } else { + None + } } + Charset::Expert => EXPERT_ENCODING + .get(usize::from(gid.0)) + .cloned() + .map(StringId), + Charset::ExpertSubset => EXPERT_SUBSET_ENCODING + .get(usize::from(gid.0)) + .cloned() + .map(StringId), Charset::Format0(ref array) => { if gid.0 == 0 { Some(StringId(0)) @@ -189,7 +197,9 @@ pub(crate) fn parse_charset<'a>(number_of_glyphs: u16, s: &mut Stream<'a>) -> Op // -1 everywhere, since `.notdef` is omitted. let format = s.read::()?; match format { - 0 => Some(Charset::Format0(s.read_array16::(number_of_glyphs - 1)?)), + 0 => Some(Charset::Format0( + s.read_array16::(number_of_glyphs - 1)?, + )), 1 => { // The number of ranges is not defined, so we have to // read until no glyphs are left. diff --git a/src/tables/cff/charstring.rs b/src/tables/cff/charstring.rs index af65d5db..163c1ec7 100644 --- a/src/tables/cff/charstring.rs +++ b/src/tables/cff/charstring.rs @@ -1,6 +1,6 @@ -use crate::parser::{Stream, Fixed}; use super::argstack::ArgumentsStack; -use super::{Builder, CFFError, IsEven, f32_abs}; +use super::{f32_abs, Builder, CFFError, IsEven}; +use crate::parser::{Fixed, Stream}; pub(crate) struct CharStringParser<'a> { pub stack: ArgumentsStack<'a>, @@ -369,7 +369,10 @@ impl CharStringParser<'_> { let x2 = x1 + self.stack.pop(); let y2 = y1 + self.stack.pop(); self.y = y2 + self.stack.pop(); - self.x = x2 + if self.stack.len() == 1 { self.stack.pop() } else { 0.0 }; + self.x = x2; + if self.stack.len() == 1 { + self.x += self.stack.pop(); + } self.builder.curve_to(x1, y1, x2, y2, self.x, self.y); if self.stack.is_empty() { break; @@ -384,7 +387,10 @@ impl CharStringParser<'_> { let x2 = x1 + self.stack.pop(); let y2 = y1 + self.stack.pop(); self.x = x2 + self.stack.pop(); - self.y = y2 + if self.stack.len() == 1 { self.stack.pop() } else { 0.0 }; + self.y = y2; + if self.stack.len() == 1 { + self.y += self.stack.pop() + } self.builder.curve_to(x1, y1, x2, y2, self.x, self.y); } @@ -416,7 +422,10 @@ impl CharStringParser<'_> { let x2 = x1 + self.stack.pop(); let y2 = y1 + self.stack.pop(); self.x = x2 + self.stack.pop(); - self.y = y2 + if self.stack.len() == 1 { self.stack.pop() } else { 0.0 }; + self.y = y2; + if self.stack.len() == 1 { + self.y += self.stack.pop(); + } self.builder.curve_to(x1, y1, x2, y2, self.x, self.y); if self.stack.is_empty() { break; @@ -431,7 +440,10 @@ impl CharStringParser<'_> { let x2 = x1 + self.stack.pop(); let y2 = y1 + self.stack.pop(); self.y = y2 + self.stack.pop(); - self.x = x2 + if self.stack.len() == 1 { self.stack.pop() } else { 0.0 }; + self.x = x2; + if self.stack.len() == 1 { + self.x += self.stack.pop(); + } self.builder.curve_to(x1, y1, x2, y2, self.x, self.y); } diff --git a/src/tables/cff/dict.rs b/src/tables/cff/dict.rs index 3f776b6d..59782b50 100644 --- a/src/tables/cff/dict.rs +++ b/src/tables/cff/dict.rs @@ -13,10 +13,11 @@ pub struct Operator(pub u16); impl Operator { #[inline] - pub fn get(self) -> u16 { self.0 } + pub fn get(self) -> u16 { + self.0 + } } - pub struct DictionaryParser<'a> { data: &'a [u8], // The current offset. @@ -147,10 +148,10 @@ impl<'a> DictionaryParser<'a> { pub fn is_dict_one_byte_op(b: u8) -> bool { match b { 0..=27 => true, - 28..=30 => false, // numbers - 31 => true, // Reserved + 28..=30 => false, // numbers + 31 => true, // Reserved 32..=254 => false, // numbers - 255 => true, // Reserved + 255 => true, // Reserved } } @@ -165,9 +166,7 @@ pub fn parse_number(b0: u8, s: &mut Stream) -> Option { let n = s.read::()?; Some(f64::from(n)) } - 30 => { - parse_float(s) - } + 30 => parse_float(s), 32..=246 => { let n = i32::from(b0) - 139; Some(f64::from(n)) @@ -277,18 +276,35 @@ pub fn skip_number(b0: u8, s: &mut Stream) -> Option<()> { Some(()) } - #[cfg(test)] mod tests { use super::*; #[test] fn parse_dict_number() { - assert_eq!(parse_number(0xFA, &mut Stream::new(&[0x7C])).unwrap(), 1000.0); - assert_eq!(parse_number(0xFE, &mut Stream::new(&[0x7C])).unwrap(), -1000.0); - assert_eq!(parse_number(0x1C, &mut Stream::new(&[0x27, 0x10])).unwrap(), 10000.0); - assert_eq!(parse_number(0x1C, &mut Stream::new(&[0xD8, 0xF0])).unwrap(), -10000.0); - assert_eq!(parse_number(0x1D, &mut Stream::new(&[0x00, 0x01, 0x86, 0xA0])).unwrap(), 100000.0); - assert_eq!(parse_number(0x1D, &mut Stream::new(&[0xFF, 0xFE, 0x79, 0x60])).unwrap(), -100000.0); + assert_eq!( + parse_number(0xFA, &mut Stream::new(&[0x7C])).unwrap(), + 1000.0 + ); + assert_eq!( + parse_number(0xFE, &mut Stream::new(&[0x7C])).unwrap(), + -1000.0 + ); + assert_eq!( + parse_number(0x1C, &mut Stream::new(&[0x27, 0x10])).unwrap(), + 10000.0 + ); + assert_eq!( + parse_number(0x1C, &mut Stream::new(&[0xD8, 0xF0])).unwrap(), + -10000.0 + ); + assert_eq!( + parse_number(0x1D, &mut Stream::new(&[0x00, 0x01, 0x86, 0xA0])).unwrap(), + 100000.0 + ); + assert_eq!( + parse_number(0x1D, &mut Stream::new(&[0xFF, 0xFE, 0x79, 0x60])).unwrap(), + -100000.0 + ); } } diff --git a/src/tables/cff/encoding.rs b/src/tables/cff/encoding.rs index 2b43fb25..00aa528d 100644 --- a/src/tables/cff/encoding.rs +++ b/src/tables/cff/encoding.rs @@ -1,9 +1,10 @@ -use crate::parser::{Stream, FromData, LazyArray16}; -use crate::GlyphId; use super::charset::Charset; use super::StringId; +use crate::parser::{FromData, LazyArray16, Stream}; +use crate::GlyphId; /// The Standard Encoding as defined in the Adobe Technical Note #5176 Appendix B. +#[rustfmt::skip] pub const STANDARD_ENCODING: [u8; 256] = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -23,7 +24,6 @@ pub const STANDARD_ENCODING: [u8; 256] = [ 0, 144, 0, 0, 0, 145, 0, 0, 146, 147, 148, 149, 0, 0, 0, 0, ]; - #[derive(Clone, Copy, Debug)] pub(crate) struct Format1Range { first: u8, @@ -43,7 +43,6 @@ impl FromData for Format1Range { } } - #[derive(Clone, Copy, Debug)] pub(crate) struct Supplement { code: u8, @@ -63,7 +62,6 @@ impl FromData for Supplement { } } - #[derive(Clone, Copy, Default, Debug)] pub(crate) struct Encoding<'a> { kind: EncodingKind<'a>, @@ -122,7 +120,11 @@ impl Encoding<'_> { } EncodingKind::Format0(ref table) => { // +1 because .notdef is implicit. - table.into_iter().position(|c| c == code).map(|i| (i + 1) as u16).map(GlyphId) + table + .into_iter() + .position(|c| c == code) + .map(|i| (i + 1) as u16) + .map(GlyphId) } EncodingKind::Format1(ref table) => { // Starts from 1 because .notdef is implicit. @@ -154,7 +156,9 @@ pub(crate) fn parse_encoding<'a>(s: &mut Stream<'a>) -> Option> { let kind = match format { // TODO: read_array8? 0 => s.read_array16::(count).map(EncodingKind::Format0)?, - 1 => s.read_array16::(count).map(EncodingKind::Format1)?, + 1 => s + .read_array16::(count) + .map(EncodingKind::Format1)?, _ => return None, }; @@ -165,8 +169,5 @@ pub(crate) fn parse_encoding<'a>(s: &mut Stream<'a>) -> Option> { LazyArray16::default() }; - Some(Encoding { - kind, - supplemental, - }) + Some(Encoding { kind, supplemental }) } diff --git a/src/tables/cff/index.rs b/src/tables/cff/index.rs index 26a9677c..d712b0ba 100644 --- a/src/tables/cff/index.rs +++ b/src/tables/cff/index.rs @@ -1,18 +1,21 @@ -use crate::parser::{Stream, U24, NumFrom, FromData}; +use crate::parser::{FromData, NumFrom, Stream, U24}; pub trait IndexSize: FromData { fn to_u32(self) -> u32; } impl IndexSize for u16 { - fn to_u32(self) -> u32 { u32::from(self) } + fn to_u32(self) -> u32 { + u32::from(self) + } } impl IndexSize for u32 { - fn to_u32(self) -> u32 { self } + fn to_u32(self) -> u32 { + self + } } - #[inline] pub fn parse_index<'a, T: IndexSize>(s: &mut Stream<'a>) -> Option> { let count = s.read::()?; @@ -38,9 +41,7 @@ fn parse_index_impl<'a>(count: u32, s: &mut Stream<'a>) -> Option> { let data = s.read_bytes(usize::num_from(last_offset))?; Some(Index { data, offsets }) } - None => { - Some(Index::default()) - } + None => Some(Index::default()), } } @@ -70,7 +71,6 @@ fn skip_index_impl(count: u32, s: &mut Stream) -> Option<()> { Some(()) } - #[derive(Clone, Copy, Debug)] pub struct VarOffsets<'a> { pub data: &'a [u8], @@ -117,7 +117,6 @@ impl<'a> VarOffsets<'a> { } } - #[derive(Clone, Copy, Debug)] pub struct Index<'a> { pub data: &'a [u8], @@ -129,7 +128,10 @@ impl<'a> Default for Index<'a> { fn default() -> Self { Index { data: b"", - offsets: VarOffsets { data: b"", offset_size: OffsetSize::Size1 }, + offsets: VarOffsets { + data: b"", + offset_size: OffsetSize::Size1, + }, } } } @@ -182,7 +184,6 @@ impl<'a> Iterator for IndexIter<'a> { } } - #[derive(Clone, Copy, PartialEq, Debug)] pub enum OffsetSize { Size1 = 1, @@ -192,8 +193,14 @@ pub enum OffsetSize { } impl OffsetSize { - #[inline] pub fn to_u32(self) -> u32 { self as u32 } - #[inline] pub fn to_usize(self) -> usize { self as usize } + #[inline] + pub fn to_u32(self) -> u32 { + self as u32 + } + #[inline] + pub fn to_usize(self) -> usize { + self as usize + } } impl FromData for OffsetSize { @@ -220,7 +227,10 @@ mod tests { assert_eq!(core::mem::size_of::(), 1); assert_eq!(Stream::new(&[0x00]).read::(), None); - assert_eq!(Stream::new(&[0x01]).read::(), Some(OffsetSize::Size1)); + assert_eq!( + Stream::new(&[0x01]).read::(), + Some(OffsetSize::Size1) + ); assert_eq!(Stream::new(&[0x05]).read::(), None); } } diff --git a/src/tables/cff/mod.rs b/src/tables/cff/mod.rs index 15f1ceeb..8d8828ee 100644 --- a/src/tables/cff/mod.rs +++ b/src/tables/cff/mod.rs @@ -1,18 +1,19 @@ -pub mod cff1; -#[cfg(feature = "variable-fonts")] pub mod cff2; mod argstack; +pub mod cff1; +#[cfg(feature = "variable-fonts")] +pub mod cff2; mod charset; mod charstring; mod dict; mod encoding; mod index; -#[cfg(feature = "glyph-names")] mod std_names; +#[cfg(feature = "glyph-names")] +mod std_names; use core::convert::TryFrom; -use crate::{OutlineBuilder, BBox}; use crate::parser::{FromData, TryNumFrom}; - +use crate::{BBox, OutlineBuilder}; /// A list of errors that can occur during a CFF glyph outlining. #[allow(missing_docs)] @@ -33,12 +34,14 @@ pub enum CFFError { InvalidSubroutineIndex, NoLocalSubroutines, InvalidSeacCode, - #[cfg(feature = "variable-fonts")] InvalidItemVariationDataIndex, - #[cfg(feature = "variable-fonts")] InvalidNumberOfBlendOperands, - #[cfg(feature = "variable-fonts")] BlendRegionsLimitReached, + #[cfg(feature = "variable-fonts")] + InvalidItemVariationDataIndex, + #[cfg(feature = "variable-fonts")] + InvalidNumberOfBlendOperands, + #[cfg(feature = "variable-fonts")] + BlendRegionsLimitReached, } - pub(crate) struct Builder<'a> { builder: &'a mut dyn OutlineBuilder, bbox: BBox, @@ -71,7 +74,6 @@ impl<'a> Builder<'a> { } } - /// A type-safe wrapper for string ID. #[derive(Clone, Copy, PartialEq, PartialOrd, Debug)] pub struct StringId(u16); @@ -85,7 +87,6 @@ impl FromData for StringId { } } - pub trait IsEven { fn is_even(&self) -> bool; fn is_odd(&self) -> bool; @@ -93,13 +94,16 @@ pub trait IsEven { impl IsEven for usize { #[inline] - fn is_even(&self) -> bool { (*self) & 1 == 0 } + fn is_even(&self) -> bool { + (*self) & 1 == 0 + } #[inline] - fn is_odd(&self) -> bool { !self.is_even() } + fn is_odd(&self) -> bool { + !self.is_even() + } } - #[cfg(feature = "std")] #[inline] pub fn f32_abs(n: f32) -> f32 { @@ -109,10 +113,13 @@ pub fn f32_abs(n: f32) -> f32 { #[cfg(not(feature = "std"))] #[inline] pub fn f32_abs(n: f32) -> f32 { - if n.is_sign_negative() { -n } else { n } + if n.is_sign_negative() { + -n + } else { + n + } } - #[inline] pub fn conv_subroutine_index(index: f32, bias: u16) -> Result { conv_subroutine_index_impl(index, bias).ok_or(CFFError::InvalidSubroutineIndex) diff --git a/src/tables/cmap/format0.rs b/src/tables/cmap/format0.rs index e70a7c23..124db4d9 100644 --- a/src/tables/cmap/format0.rs +++ b/src/tables/cmap/format0.rs @@ -1,4 +1,4 @@ -use crate::parser::{Stream, NumFrom}; +use crate::parser::{NumFrom, Stream}; use crate::GlyphId; /// A [format 0](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-0-byte-encoding-table) diff --git a/src/tables/cmap/format10.rs b/src/tables/cmap/format10.rs index b3ceab13..bcfb75c5 100644 --- a/src/tables/cmap/format10.rs +++ b/src/tables/cmap/format10.rs @@ -22,7 +22,10 @@ impl<'a> Subtable10<'a> { let first_code_point = s.read::()?; let count = s.read::()?; let glyphs = s.read_array32::(count)?; - Some(Self { first_code_point, glyphs }) + Some(Self { + first_code_point, + glyphs, + }) } /// Returns a glyph index for a code point. diff --git a/src/tables/cmap/format12.rs b/src/tables/cmap/format12.rs index 6d8e95e4..8b6eca0b 100644 --- a/src/tables/cmap/format12.rs +++ b/src/tables/cmap/format12.rs @@ -24,7 +24,6 @@ impl FromData for SequentialMapGroup { } } - /// A [format 12](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-12-segmented-coverage) /// subtable. #[derive(Clone, Copy)] @@ -59,7 +58,10 @@ impl<'a> Subtable12<'a> { } })?; - let id = group.start_glyph_id.checked_add(code_point)?.checked_sub(group.start_char_code)?; + let id = group + .start_glyph_id + .checked_add(code_point)? + .checked_sub(group.start_char_code)?; return u16::try_from(id).ok().map(GlyphId); } diff --git a/src/tables/cmap/format13.rs b/src/tables/cmap/format13.rs index 509c0c1d..2ba3cdce 100644 --- a/src/tables/cmap/format13.rs +++ b/src/tables/cmap/format13.rs @@ -2,8 +2,8 @@ use core::convert::TryFrom; -use crate::parser::{LazyArray32, Stream}; use super::format12::SequentialMapGroup; +use crate::parser::{LazyArray32, Stream}; use crate::GlyphId; /// A [format 13](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-13-segmented-coverage) diff --git a/src/tables/cmap/format14.rs b/src/tables/cmap/format14.rs index 4854b73d..2a1938d7 100644 --- a/src/tables/cmap/format14.rs +++ b/src/tables/cmap/format14.rs @@ -1,5 +1,5 @@ -use crate::GlyphId; use crate::parser::{FromData, LazyArray32, Offset, Offset32, Stream, U24}; +use crate::GlyphId; #[derive(Clone, Copy)] struct VariationSelectorRecord { @@ -22,7 +22,6 @@ impl FromData for VariationSelectorRecord { } } - #[derive(Clone, Copy)] struct UVSMappingRecord { unicode_value: u32, @@ -42,7 +41,6 @@ impl FromData for UVSMappingRecord { } } - #[derive(Clone, Copy)] struct UnicodeRangeRecord { start_unicode_value: u32, @@ -70,7 +68,6 @@ impl FromData for UnicodeRangeRecord { } } - /// A result of a variation glyph mapping. #[derive(Clone, Copy, PartialEq, Debug)] pub enum GlyphVariationResult { @@ -83,7 +80,6 @@ pub enum GlyphVariationResult { UseDefault, } - /// A [format 14](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-14-unicode-variation-sequences) /// subtable. #[derive(Clone, Copy)] @@ -106,7 +102,9 @@ impl<'a> Subtable14<'a> { /// Returns a glyph index for a code point. pub fn glyph_index(&self, code_point: u32, variation: u32) -> Option { - let (_, record) = self.records.binary_search_by(|v| v.var_selector.cmp(&variation))?; + let (_, record) = self + .records + .binary_search_by(|v| v.var_selector.cmp(&variation))?; if let Some(offset) = record.default_uvs_offset { let data = self.data.get(offset.to_usize()..)?; @@ -125,7 +123,8 @@ impl<'a> Subtable14<'a> { let mut s = Stream::new(data); let count = s.read::()?; let uvs_mappings = s.read_array32::(count)?; - let (_, mapping) = uvs_mappings.binary_search_by(|v| v.unicode_value.cmp(&code_point))?; + let (_, mapping) = + uvs_mappings.binary_search_by(|v| v.unicode_value.cmp(&code_point))?; return Some(GlyphVariationResult::Found(mapping.glyph_id)); } diff --git a/src/tables/cmap/format2.rs b/src/tables/cmap/format2.rs index fe8e0f22..b4979571 100644 --- a/src/tables/cmap/format2.rs +++ b/src/tables/cmap/format2.rs @@ -99,8 +99,7 @@ impl<'a> Subtable2<'a> { // 'The value of the idRangeOffset is the number of bytes // past the actual location of the idRangeOffset'. - let offset = - self.sub_headers_offset + let offset = self.sub_headers_offset // Advance to required subheader. + SubHeaderRecord::SIZE * usize::from(i + 1) // Move back to idRangeOffset start. @@ -115,7 +114,9 @@ impl<'a> Subtable2<'a> { return None; } - u16::try_from((i32::from(glyph) + i32::from(sub_header.id_delta)) % 65536).ok().map(GlyphId) + u16::try_from((i32::from(glyph) + i32::from(sub_header.id_delta)) % 65536) + .ok() + .map(GlyphId) } /// Calls `f` for each codepoint defined in this table. diff --git a/src/tables/cmap/format4.rs b/src/tables/cmap/format4.rs index 3ef7f240..d1d432b2 100644 --- a/src/tables/cmap/format4.rs +++ b/src/tables/cmap/format4.rs @@ -77,7 +77,8 @@ impl<'a> Subtable4<'a> { let delta = (u32::from(code_point) - u32::from(start_value)) * 2; let delta = u16::try_from(delta).ok()?; - let id_range_offset_pos = (self.id_range_offset_pos + usize::from(index) * 2) as u16; + let id_range_offset_pos = + (self.id_range_offset_pos + usize::from(index) * 2) as u16; let pos = id_range_offset_pos.wrapping_add(delta); let pos = pos.wrapping_add(id_range_offset); diff --git a/src/tables/cmap/format6.rs b/src/tables/cmap/format6.rs index ef4558a0..65399cd8 100644 --- a/src/tables/cmap/format6.rs +++ b/src/tables/cmap/format6.rs @@ -23,7 +23,10 @@ impl<'a> Subtable6<'a> { let first_code_point = s.read::()?; let count = s.read::()?; let glyphs = s.read_array16::(count)?; - Some(Self { first_code_point, glyphs }) + Some(Self { + first_code_point, + glyphs, + }) } /// Returns a glyph index for a code point. diff --git a/src/tables/cmap/mod.rs b/src/tables/cmap/mod.rs index 5062b15c..9f203088 100644 --- a/src/tables/cmap/mod.rs +++ b/src/tables/cmap/mod.rs @@ -8,26 +8,26 @@ This module provides a low-level alternative to methods. */ -use crate::{GlyphId, name::PlatformId}; use crate::parser::{FromData, LazyArray16, Offset, Offset32, Stream}; +use crate::{name::PlatformId, GlyphId}; mod format0; -mod format2; -mod format4; -mod format6; mod format10; mod format12; mod format13; mod format14; +mod format2; +mod format4; +mod format6; pub use format0::Subtable0; -pub use format2::Subtable2; -pub use format4::Subtable4; -pub use format6::Subtable6; pub use format10::Subtable10; pub use format12::Subtable12; pub use format13::Subtable13; -pub use format14::{Subtable14, GlyphVariationResult}; +pub use format14::{GlyphVariationResult, Subtable14}; +pub use format2::Subtable2; +pub use format4::Subtable4; +pub use format6::Subtable6; /// A character encoding subtable variant. #[allow(missing_docs)] @@ -44,7 +44,6 @@ pub enum Format<'a> { UnicodeVariationSequences(Subtable14<'a>), } - /// A character encoding subtable. #[derive(Clone, Copy, Debug)] pub struct Subtable<'a> { @@ -70,14 +69,16 @@ impl<'a> Subtable<'a> { PlatformId::Windows => { // "Note: Subtable format 13 has the same structure as format 12; it differs only // in the interpretation of the startGlyphID/glyphID fields". - let is_format_12_compatible = - matches!(self.format, Format::SegmentedCoverage(..) | Format::ManyToOneRangeMappings(..)); + let is_format_12_compatible = matches!( + self.format, + Format::SegmentedCoverage(..) | Format::ManyToOneRangeMappings(..) + ); // "Fonts that support Unicode supplementary-plane characters (U+10000 to U+10FFFF) // on the Windows platform must have a format 12 subtable for platform ID 3, // encoding ID 10." self.encoding_id == WINDOWS_UNICODE_FULL_REPERTOIRE_ENCODING_ID - && is_format_12_compatible + && is_format_12_compatible } _ => false, } @@ -115,7 +116,11 @@ impl<'a> Subtable<'a> { /// - when glyph ID is `0`. /// - when format is not `UnicodeVariationSequences`. #[inline] - pub fn glyph_variation_index(&self, code_point: u32, variation: u32) -> Option { + pub fn glyph_variation_index( + &self, + code_point: u32, + variation: u32, + ) -> Option { match self.format { Format::UnicodeVariationSequences(ref subtable) => { subtable.glyph_index(code_point, variation) @@ -152,7 +157,6 @@ impl<'a> Subtable<'a> { } } - #[derive(Clone, Copy)] struct EncodingRecord { platform_id: PlatformId, @@ -174,7 +178,6 @@ impl FromData for EncodingRecord { } } - /// A list of subtables. #[derive(Clone, Copy, Default)] pub struct Subtables<'a> { @@ -194,11 +197,11 @@ impl<'a> Subtables<'a> { let record = self.records.get(index)?; let data = self.data.get(record.offset.to_usize()..)?; let format = match Stream::read_at::(data, 0)? { - 0 => Format::ByteEncodingTable(Subtable0::parse(data)?), - 2 => Format::HighByteMappingThroughTable(Subtable2::parse(data)?), - 4 => Format::SegmentMappingToDeltaValues(Subtable4::parse(data)?), - 6 => Format::TrimmedTableMapping(Subtable6::parse(data)?), - 8 => Format::MixedCoverage, // unsupported + 0 => Format::ByteEncodingTable(Subtable0::parse(data)?), + 2 => Format::HighByteMappingThroughTable(Subtable2::parse(data)?), + 4 => Format::SegmentMappingToDeltaValues(Subtable4::parse(data)?), + 6 => Format::TrimmedTableMapping(Subtable6::parse(data)?), + 8 => Format::MixedCoverage, // unsupported 10 => Format::TrimmedArray(Subtable10::parse(data)?), 12 => Format::SegmentedCoverage(Subtable12::parse(data)?), 13 => Format::ManyToOneRangeMappings(Subtable13::parse(data)?), @@ -254,7 +257,6 @@ impl<'a> Iterator for SubtablesIter<'a> { } } - /// A [Character to Glyph Index Mapping Table]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/cmap). #[derive(Clone, Copy, Debug)] @@ -270,6 +272,8 @@ impl<'a> Table<'a> { s.skip::(); // version let count = s.read::()?; let records = s.read_array16::(count)?; - Some(Table { subtables: Subtables { data, records }}) + Some(Table { + subtables: Subtables { data, records }, + }) } } diff --git a/src/tables/feat.rs b/src/tables/feat.rs index 90b73cc6..e57fd14b 100644 --- a/src/tables/feat.rs +++ b/src/tables/feat.rs @@ -31,7 +31,6 @@ impl FromData for FeatureNameRecord { } } - /// A setting name. #[derive(Clone, Copy, Debug)] pub struct SettingName { @@ -54,7 +53,6 @@ impl FromData for SettingName { } } - /// A feature names. #[derive(Clone, Copy, Debug)] pub struct FeatureName<'a> { @@ -70,7 +68,6 @@ pub struct FeatureName<'a> { pub name_index: u16, } - /// A list fo feature names. #[derive(Clone, Copy)] pub struct FeatureNames<'a> { @@ -88,8 +85,11 @@ impl<'a> FeatureNames<'a> { Some(FeatureName { feature: record.feature, setting_names, - default_setting_index: - if record.flags & 0x40 != 0 { record.default_setting_index } else { 0 }, + default_setting_index: if record.flags & 0x40 != 0 { + record.default_setting_index + } else { + 0 + }, exclusive: record.flags & 0x80 != 0, name_index: record.name_index, }) @@ -97,8 +97,10 @@ impl<'a> FeatureNames<'a> { /// Finds a feature name by ID. pub fn find(&self, feature: u16) -> Option> { - let index = self.records - .binary_search_by(|name| name.feature.cmp(&feature)).map(|(i, _)| i)?; + let index = self + .records + .binary_search_by(|name| name.feature.cmp(&feature)) + .map(|(i, _)| i)?; self.get(index) } @@ -147,7 +149,6 @@ impl<'a> Iterator for FeatureNamesIter<'a> { } } - /// A [Feature Name Table]( /// https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6feat.html). #[derive(Clone, Copy, Debug)] @@ -171,10 +172,7 @@ impl<'a> Table<'a> { let records = s.read_array16::(count)?; Some(Table { - names: FeatureNames { - data, - records, - } + names: FeatureNames { data, records }, }) } } diff --git a/src/tables/fvar.rs b/src/tables/fvar.rs index d7574da0..1e8d17e9 100644 --- a/src/tables/fvar.rs +++ b/src/tables/fvar.rs @@ -3,8 +3,8 @@ use core::num::NonZeroU16; -use crate::{Tag, NormalizedCoordinate}; -use crate::parser::{Stream, FromData, Fixed, Offset16, Offset, LazyArray16, f32_bound}; +use crate::parser::{f32_bound, Fixed, FromData, LazyArray16, Offset, Offset16, Stream}; +use crate::{NormalizedCoordinate, Tag}; /// A [variation axis](https://docs.microsoft.com/en-us/typography/opentype/spec/fvar#variationaxisrecord). #[repr(C)] @@ -62,7 +62,6 @@ impl VariationAxis { } } - /// A [Font Variations Table]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/fvar). #[derive(Clone, Copy, Debug)] diff --git a/src/tables/gdef.rs b/src/tables/gdef.rs index 09fabf9a..55be2b96 100644 --- a/src/tables/gdef.rs +++ b/src/tables/gdef.rs @@ -1,25 +1,25 @@ //! A [Glyph Definition Table]( //! https://docs.microsoft.com/en-us/typography/opentype/spec/gdef) implementation. -use crate::GlyphId; use crate::opentype_layout::{Class, ClassDefinition, Coverage}; -use crate::parser::{LazyArray16, Offset, Offset16, Offset32, Stream, FromSlice}; - -#[cfg(feature = "variable-fonts")] use crate::NormalizedCoordinate; -#[cfg(feature = "variable-fonts")] use crate::var_store::ItemVariationStore; +use crate::parser::{FromSlice, LazyArray16, Offset, Offset16, Offset32, Stream}; +use crate::GlyphId; +#[cfg(feature = "variable-fonts")] +use crate::var_store::ItemVariationStore; +#[cfg(feature = "variable-fonts")] +use crate::NormalizedCoordinate; /// A [glyph class](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef#glyph-class-definition-table). #[allow(missing_docs)] #[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)] pub enum GlyphClass { - Base = 1, - Ligature = 2, - Mark = 3, + Base = 1, + Ligature = 2, + Mark = 3, Component = 4, } - /// A [Glyph Definition Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef). #[allow(missing_debug_implementations)] #[derive(Clone, Copy, Default)] @@ -27,7 +27,8 @@ pub struct Table<'a> { glyph_classes: Option>, mark_attach_classes: Option>, mark_glyph_coverage_offsets: Option<(&'a [u8], LazyArray16<'a, Offset32>)>, - #[cfg(feature = "variable-fonts")] variation_store: Option>, + #[cfg(feature = "variable-fonts")] + variation_store: Option>, } impl<'a> Table<'a> { @@ -63,7 +64,6 @@ impl<'a> Table<'a> { let mut table = Table::default(); if let Some(offset) = glyph_class_def_offset { - if let Some(subdata) = data.get(offset.to_usize()..) { table.glyph_classes = ClassDefinition::parse(subdata); } @@ -167,11 +167,7 @@ impl<'a> Table<'a> { } #[inline(never)] -fn is_mark_glyph_impl( - table: &Table, - glyph_id: GlyphId, - set_index: Option, -) -> Option<()> { +fn is_mark_glyph_impl(table: &Table, glyph_id: GlyphId, set_index: Option) -> Option<()> { let (data, offsets) = table.mark_glyph_coverage_offsets?; if let Some(set_index) = set_index { diff --git a/src/tables/glyf.rs b/src/tables/glyf.rs index 7a52aa08..871fc2c6 100644 --- a/src/tables/glyf.rs +++ b/src/tables/glyf.rs @@ -3,8 +3,8 @@ use core::num::NonZeroU16; -use crate::parser::{Stream, F2DOT14, LazyArray16, NumFrom}; -use crate::{loca, GlyphId, OutlineBuilder, Rect, BBox}; +use crate::parser::{LazyArray16, NumFrom, Stream, F2DOT14}; +use crate::{loca, BBox, GlyphId, OutlineBuilder, Rect}; pub(crate) struct Builder<'a> { pub builder: &'a mut dyn OutlineBuilder, @@ -20,11 +20,7 @@ pub(crate) struct Builder<'a> { impl<'a> Builder<'a> { #[inline] - pub fn new( - transform: Transform, - bbox: BBox, - builder: &'a mut dyn OutlineBuilder, - ) -> Self { + pub fn new(transform: Transform, bbox: BBox, builder: &'a mut dyn OutlineBuilder) -> Self { Builder { builder, transform, @@ -141,18 +137,28 @@ impl<'a> Builder<'a> { } } - #[derive(Clone, Copy)] pub(crate) struct Transform { - pub a: f32, pub b: f32, pub c: f32, - pub d: f32, pub e: f32, pub f: f32, + pub a: f32, + pub b: f32, + pub c: f32, + pub d: f32, + pub e: f32, + pub f: f32, } impl Transform { #[cfg(feature = "variable-fonts")] #[inline] pub fn new_translate(tx: f32, ty: f32) -> Self { - Transform { a: 1.0, b: 0.0, c: 0.0, d: 1.0, e: tx, f: ty } + Transform { + a: 1.0, + b: 0.0, + c: 0.0, + d: 1.0, + e: tx, + f: ty, + } } #[inline] @@ -178,38 +184,48 @@ impl Transform { #[inline] fn is_default(&self) -> bool { // A direct float comparison is fine in our case. - self.a == 1.0 - && self.b == 0.0 - && self.c == 0.0 - && self.d == 1.0 - && self.e == 0.0 - && self.f == 0.0 + self.a == 1.0 + && self.b == 0.0 + && self.c == 0.0 + && self.d == 1.0 + && self.e == 0.0 + && self.f == 0.0 } } impl Default for Transform { #[inline] fn default() -> Self { - Transform { a: 1.0, b: 0.0, c: 0.0, d: 1.0, e: 0.0, f: 0.0 } + Transform { + a: 1.0, + b: 0.0, + c: 0.0, + d: 1.0, + e: 0.0, + f: 0.0, + } } } impl core::fmt::Debug for Transform { #[inline] fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - write!(f, "Transform({} {} {} {} {} {})", self.a, self.b, self.c, self.d, self.e, self.f) + write!( + f, + "Transform({} {} {} {} {} {})", + self.a, self.b, self.c, self.d, self.e, self.f + ) } } - #[derive(Clone, Copy, Debug)] pub(crate) struct CompositeGlyphInfo { pub glyph_id: GlyphId, pub transform: Transform, - #[allow(dead_code)] pub flags: CompositeGlyphFlags, + #[allow(dead_code)] + pub flags: CompositeGlyphFlags, } - #[derive(Clone)] pub(crate) struct CompositeGlyphIter<'a> { stream: Stream<'a>, @@ -218,7 +234,9 @@ pub(crate) struct CompositeGlyphIter<'a> { impl<'a> CompositeGlyphIter<'a> { #[inline] pub fn new(data: &'a [u8]) -> Self { - CompositeGlyphIter { stream: Stream::new(data) } + CompositeGlyphIter { + stream: Stream::new(data), + } } } @@ -268,7 +286,6 @@ impl<'a> Iterator for CompositeGlyphIter<'a> { } } - // Due to some optimization magic, using f32 instead of i16 // makes the code ~10% slower. At least on my machine. // I guess it's due to the fact that with i16 the struct @@ -283,7 +300,6 @@ pub(crate) struct GlyphPoint { pub last_point: bool, } - #[derive(Clone, Default)] pub(crate) struct GlyphPointsIter<'a> { endpoints: EndpointsIter<'a>, @@ -313,15 +329,18 @@ impl<'a> Iterator for GlyphPointsIter<'a> { let last_point = self.endpoints.next(); let flags = self.flags.next()?; Some(GlyphPoint { - x: self.x_coords.next(flags.x_short(), flags.x_is_same_or_positive_short()), - y: self.y_coords.next(flags.y_short(), flags.y_is_same_or_positive_short()), + x: self + .x_coords + .next(flags.x_short(), flags.x_is_same_or_positive_short()), + y: self + .y_coords + .next(flags.y_short(), flags.y_is_same_or_positive_short()), on_curve_point: flags.on_curve_point(), last_point, }) } } - /// A simple flattening iterator for glyph's endpoints. /// /// Translates endpoints like: 2 4 7 @@ -367,7 +386,6 @@ impl<'a> EndpointsIter<'a> { } } - #[derive(Clone, Default)] struct FlagsIter<'a> { stream: Stream<'a>, @@ -406,7 +424,6 @@ impl<'a> Iterator for FlagsIter<'a> { } } - #[derive(Clone, Default)] struct CoordsIter<'a> { stream: Stream<'a>, @@ -444,7 +461,6 @@ impl<'a> CoordsIter<'a> { } } - #[derive(Clone, Copy, Debug)] struct Point { x: f32, @@ -461,11 +477,11 @@ impl Point { } } - // https://docs.microsoft.com/en-us/typography/opentype/spec/glyf#simple-glyph-description #[derive(Clone, Copy, Default)] struct SimpleGlyphFlags(u8); +#[rustfmt::skip] impl SimpleGlyphFlags { #[inline] fn on_curve_point(self) -> bool { self.0 & 0x01 != 0 } #[inline] fn x_short(self) -> bool { self.0 & 0x02 != 0 } @@ -475,11 +491,11 @@ impl SimpleGlyphFlags { #[inline] fn y_is_same_or_positive_short(self) -> bool { self.0 & 0x20 != 0 } } - // https://docs.microsoft.com/en-us/typography/opentype/spec/glyf#composite-glyph-description #[derive(Clone, Copy, Debug)] pub(crate) struct CompositeGlyphFlags(u16); +#[rustfmt::skip] impl CompositeGlyphFlags { #[inline] pub fn arg_1_and_2_are_words(self) -> bool { self.0 & 0x0001 != 0 } #[inline] pub fn args_are_xy_values(self) -> bool { self.0 & 0x0002 != 0 } @@ -489,7 +505,6 @@ impl CompositeGlyphFlags { #[inline] pub fn we_have_a_two_by_two(self) -> bool { self.0 & 0x0080 != 0 } } - // It's not defined in the spec, so we are using our own value. pub(crate) const MAX_COMPONENTS: u8 = 32; @@ -515,8 +530,12 @@ fn outline_impl( // u16 casting is safe, since we already checked that the value is positive. let number_of_contours = NonZeroU16::new(number_of_contours as u16)?; for point in parse_simple_outline(s.tail()?, number_of_contours)? { - builder.push_point(f32::from(point.x), f32::from(point.y), - point.on_curve_point, point.last_point); + builder.push_point( + f32::from(point.x), + f32::from(point.y), + point.on_curve_point, + point.last_point, + ); } } else if number_of_contours < 0 { // Composite glyph. @@ -579,10 +598,7 @@ pub(crate) fn parse_simple_outline( /// Resolves coordinate arrays length. /// /// The length depends on *Simple Glyph Flags*, so we have to process them all to find it. -fn resolve_coords_len( - s: &mut Stream, - points_total: u16, -) -> Option<(u32, u32)> { +fn resolve_coords_len(s: &mut Stream, points_total: u16) -> Option<(u32, u32)> { let mut flags_left = u32::from(points_total); let mut repeats; let mut x_coords_len = 0; @@ -628,14 +644,12 @@ fn resolve_coords_len( y_coords_len += (flags.0 & 0x04 != 0) as u32 * repeats; y_coords_len += (flags.0 & (0x04 | 0x20) == 0) as u32 * (repeats * 2); - flags_left -= repeats; } Some((x_coords_len, y_coords_len)) } - /// A [Glyph Data Table]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/glyf). #[derive(Clone, Copy)] @@ -659,11 +673,7 @@ impl<'a> Table<'a> { /// Outlines a glyph. #[inline] - pub fn outline( - &self, - glyph_id: GlyphId, - builder: &mut dyn OutlineBuilder, - ) -> Option { + pub fn outline(&self, glyph_id: GlyphId, builder: &mut dyn OutlineBuilder) -> Option { let mut b = Builder::new(Transform::default(), BBox::new(), builder); let glyph_data = self.get(glyph_id)?; outline_impl(self.loca_table, self.data, glyph_data, 0, &mut b)? diff --git a/src/tables/gpos.rs b/src/tables/gpos.rs index 70e23f36..38bd661d 100644 --- a/src/tables/gpos.rs +++ b/src/tables/gpos.rs @@ -6,10 +6,12 @@ use core::convert::TryFrom; -use crate::GlyphId; -use crate::opentype_layout::{Class, ClassDefinition, ContextLookup, Coverage, LookupSubtable}; use crate::opentype_layout::ChainedContextLookup; -use crate::parser::{FromData, FromSlice, LazyArray16, LazyArray32, NumFrom, Offset, Offset16, Stream}; +use crate::opentype_layout::{Class, ClassDefinition, ContextLookup, Coverage, LookupSubtable}; +use crate::parser::{ + FromData, FromSlice, LazyArray16, LazyArray32, NumFrom, Offset, Offset16, Stream, +}; +use crate::GlyphId; /// A [Device Table]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#devVarIdxTbls) @@ -73,7 +75,6 @@ pub struct VariationDevice { pub inner_index: u16, } - /// A [Device Table]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#devVarIdxTbls). #[allow(missing_docs)] @@ -102,21 +103,19 @@ impl<'a> Device<'a> { delta_values, })) } - 0x8000 => { - Some(Self::Variation(VariationDevice { - outer_index: first, - inner_index: second, - })) - } + 0x8000 => Some(Self::Variation(VariationDevice { + outer_index: first, + inner_index: second, + })), _ => None, } } } - #[derive(Clone, Copy, Default, Debug)] struct ValueFormatFlags(u8); +#[rustfmt::skip] impl ValueFormatFlags { #[inline] fn x_placement(self) -> bool { self.0 & 0x01 != 0 } #[inline] fn y_placement(self) -> bool { self.0 & 0x02 != 0 } @@ -145,7 +144,6 @@ impl FromData for ValueFormatFlags { } } - /// A [Value Record](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#value-record). #[derive(Clone, Copy, Default, Debug)] pub struct ValueRecord<'a> { @@ -170,7 +168,11 @@ pub struct ValueRecord<'a> { impl<'a> ValueRecord<'a> { // Returns `None` only on parsing error. - fn parse(table_data: &'a [u8], s: &mut Stream, flags: ValueFormatFlags) -> Option> { + fn parse( + table_data: &'a [u8], + s: &mut Stream, + flags: ValueFormatFlags, + ) -> Option> { let mut record = ValueRecord::default(); if flags.x_placement() { @@ -191,25 +193,29 @@ impl<'a> ValueRecord<'a> { if flags.x_placement_device() { if let Some(offset) = s.read::>()? { - record.x_placement_device = table_data.get(offset.to_usize()..).and_then(Device::parse) + record.x_placement_device = + table_data.get(offset.to_usize()..).and_then(Device::parse) } } if flags.y_placement_device() { if let Some(offset) = s.read::>()? { - record.y_placement_device = table_data.get(offset.to_usize()..).and_then(Device::parse) + record.y_placement_device = + table_data.get(offset.to_usize()..).and_then(Device::parse) } } if flags.x_advance_device() { if let Some(offset) = s.read::>()? { - record.x_advance_device = table_data.get(offset.to_usize()..).and_then(Device::parse) + record.x_advance_device = + table_data.get(offset.to_usize()..).and_then(Device::parse) } } if flags.y_advance_device() { if let Some(offset) = s.read::>()? { - record.y_advance_device = table_data.get(offset.to_usize()..).and_then(Device::parse) + record.y_advance_device = + table_data.get(offset.to_usize()..).and_then(Device::parse) } } @@ -217,7 +223,6 @@ impl<'a> ValueRecord<'a> { } } - /// An array of /// [Value Records](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#value-record). #[derive(Clone, Copy)] @@ -273,7 +278,6 @@ impl core::fmt::Debug for ValueRecordsArray<'_> { } } - /// A [Single Adjustment Positioning Subtable]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#SP). #[allow(missing_docs)] @@ -297,20 +301,14 @@ impl<'a> SingleAdjustment<'a> { let coverage = Coverage::parse(s.read_at_offset16(data)?)?; let flags = s.read::()?; let value = ValueRecord::parse(data, &mut s, flags)?; - Some(Self::Format1 { - coverage, - value, - }) + Some(Self::Format1 { coverage, value }) } 2 => { let coverage = Coverage::parse(s.read_at_offset16(data)?)?; let flags = s.read::()?; let count = s.read::()?; let values = ValueRecordsArray::parse(data, count, flags, &mut s)?; - Some(Self::Format2 { - coverage, - values, - }) + Some(Self::Format2 { coverage, values }) } _ => None, } @@ -326,7 +324,6 @@ impl<'a> SingleAdjustment<'a> { } } - /// A [`ValueRecord`] pairs set used by [`PairAdjustment`]. #[derive(Clone, Copy)] pub struct PairSet<'a> { @@ -342,7 +339,11 @@ impl<'a> PairSet<'a> { // Max len is 34, so u8 is just enough. let record_len = (GlyphId::SIZE + flags.0.size() + flags.1.size()) as u8; let data = s.read_bytes(usize::from(count) * usize::from(record_len))?; - Some(Self { data, flags, record_len }) + Some(Self { + data, + flags, + record_len, + }) } #[inline] @@ -360,9 +361,7 @@ impl<'a> PairSet<'a> { self.data.get(start..end) }; - let get_glyph = |data: &[u8]| { - GlyphId(u16::from_be_bytes([data[0], data[1]])) - }; + let get_glyph = |data: &[u8]| GlyphId(u16::from_be_bytes([data[0], data[1]])); let mut base = 0; while size > 1 { @@ -372,13 +371,21 @@ impl<'a> PairSet<'a> { // mid >= 0: by definition // mid < size: mid = size / 2 + size / 4 + size / 8 ... let cmp = get_glyph(get_record(mid)?).cmp(&second); - base = if cmp == core::cmp::Ordering::Greater { base } else { mid }; + base = if cmp == core::cmp::Ordering::Greater { + base + } else { + mid + }; size -= half; } // base is always in [0, size) because base <= mid. let value = get_record(base)?; - if get_glyph(value).cmp(&second) == core::cmp::Ordering::Equal { Some(value) } else { None } + if get_glyph(value).cmp(&second) == core::cmp::Ordering::Equal { + Some(value) + } else { + None + } } /// Returns a [`ValueRecord`] pair using the second glyph. @@ -399,7 +406,6 @@ impl core::fmt::Debug for PairSet<'_> { } } - // Essentially a `LazyOffsetArray16` but stores additional data required to parse [`PairSet`]. /// A list of [`PairSet`]s. @@ -417,14 +423,20 @@ impl<'a> PairSets<'a> { offsets: LazyArray16<'a, Option>, flags: (ValueFormatFlags, ValueFormatFlags), ) -> Self { - Self { data, offsets, flags } + Self { + data, + offsets, + flags, + } } /// Returns a value at `index`. #[inline] pub fn get(&self, index: u16) -> Option> { let offset = self.offsets.get(index)??.to_usize(); - self.data.get(offset..).and_then(|data| PairSet::parse(data, self.flags)) + self.data + .get(offset..) + .and_then(|data| PairSet::parse(data, self.flags)) } /// Returns array's length. @@ -440,7 +452,6 @@ impl core::fmt::Debug for PairSets<'_> { } } - /// A [`ValueRecord`] pairs matrix used by [`PairAdjustment`]. #[derive(Clone, Copy)] pub struct ClassMatrix<'a> { @@ -464,7 +475,13 @@ impl<'a> ClassMatrix<'a> { // Max len is 32, so u8 is just enough. let record_len = (flags.0.size() + flags.1.size()) as u8; let matrix = s.read_bytes(usize::from(count) * usize::from(record_len))?; - Some(Self { table_data, matrix, counts, flags, record_len }) + Some(Self { + table_data, + matrix, + counts, + flags, + record_len, + }) } /// Returns a [`ValueRecord`] pair using specified classes. @@ -490,7 +507,6 @@ impl core::fmt::Debug for ClassMatrix<'_> { } } - /// A [Pair Adjustment Positioning Subtable]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#PP). #[allow(missing_docs)] @@ -513,37 +529,28 @@ impl<'a> PairAdjustment<'a> { match s.read::()? { 1 => { let coverage = Coverage::parse(s.read_at_offset16(data)?)?; - let flags = ( - s.read::()?, - s.read::()?, - ); + let flags = (s.read::()?, s.read::()?); let count = s.read::()?; let offsets = s.read_array16(count)?; Some(Self::Format1 { coverage, - sets: PairSets::new(data, offsets, flags) + sets: PairSets::new(data, offsets, flags), }) } 2 => { let coverage = Coverage::parse(s.read_at_offset16(data)?)?; - let flags = ( - s.read::()?, - s.read::()?, - ); + let flags = (s.read::()?, s.read::()?); let classes = ( ClassDefinition::parse(s.read_at_offset16(data)?)?, ClassDefinition::parse(s.read_at_offset16(data)?)?, ); - let counts = ( - s.read::()?, - s.read::()?, - ); + let counts = (s.read::()?, s.read::()?); Some(Self::Format2 { coverage, classes, matrix: ClassMatrix::parse(data, counts, flags, &mut s)?, }) - }, + } _ => None, } } @@ -558,7 +565,6 @@ impl<'a> PairAdjustment<'a> { } } - #[derive(Clone, Copy)] struct EntryExitRecord { entry_anchor_offset: Option, @@ -578,7 +584,6 @@ impl FromData for EntryExitRecord { } } - /// A list of entry and exit [`Anchor`] pairs. #[derive(Clone, Copy)] pub struct CursiveAnchorSet<'a> { @@ -611,7 +616,6 @@ impl core::fmt::Debug for CursiveAnchorSet<'_> { } } - /// A [Cursive Attachment Positioning Subtable]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#CAP). #[allow(missing_docs)] @@ -631,7 +635,7 @@ impl<'a> CursiveAdjustment<'a> { let records = s.read_array16(count)?; Some(Self { coverage, - sets: CursiveAnchorSet { data, records } + sets: CursiveAnchorSet { data, records }, }) } _ => None, @@ -639,7 +643,6 @@ impl<'a> CursiveAdjustment<'a> { } } - /// A [Mark-to-Base Attachment Positioning Subtable]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#MBP). #[derive(Clone, Copy, Debug)] @@ -664,7 +667,12 @@ impl<'a> MarkToBaseAdjustment<'a> { let class_count = s.read::()?; let marks = MarkArray::parse(s.read_at_offset16(data)?)?; let anchors = AnchorMatrix::parse(s.read_at_offset16(data)?, class_count)?; - Some(Self { mark_coverage, base_coverage, marks, anchors }) + Some(Self { + mark_coverage, + base_coverage, + marks, + anchors, + }) } _ => None, } @@ -692,7 +700,12 @@ impl<'a> MarkToLigatureAdjustment<'a> { let class_count = s.read::()?; let marks = MarkArray::parse(s.read_at_offset16(data)?)?; let ligature_array = LigatureArray::parse(s.read_at_offset16(data)?, class_count)?; - Some(Self { mark_coverage, ligature_coverage, marks, ligature_array }) + Some(Self { + mark_coverage, + ligature_coverage, + marks, + ligature_array, + }) } _ => None, } @@ -712,7 +725,11 @@ impl<'a> LigatureArray<'a> { let mut s = Stream::new(data); let count = s.read::()?; let offsets = s.read_array16(count)?; - Some(Self { data, class_count, offsets }) + Some(Self { + data, + class_count, + offsets, + }) } /// Returns an [`AnchorMatrix`] at index. @@ -734,7 +751,6 @@ impl core::fmt::Debug for LigatureArray<'_> { } } - #[derive(Clone, Copy)] struct MarkRecord { class: Class, @@ -754,7 +770,6 @@ impl FromData for MarkRecord { } } - /// A [Mark Array](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#mark-array-table). #[derive(Clone, Copy)] pub struct MarkArray<'a> { @@ -773,7 +788,10 @@ impl<'a> MarkArray<'a> { /// Returns contained data at index. pub fn get(&self, index: u16) -> Option<(Class, Anchor<'a>)> { let record = self.array.get(index)?; - let anchor = self.data.get(record.mark_anchor.to_usize()..).and_then(Anchor::parse)?; + let anchor = self + .data + .get(record.mark_anchor.to_usize()..) + .and_then(Anchor::parse)?; Some((record.class, anchor)) } @@ -789,7 +807,6 @@ impl core::fmt::Debug for MarkArray<'_> { } } - /// An [Anchor Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#anchor-tables). /// /// The *Anchor Table Format 2: Design Units Plus Contour Point* is not supported. @@ -824,11 +841,13 @@ impl<'a> Anchor<'a> { // get a glyph contour point by index. if format == 3 { - table.x_device = s.read::>()? + table.x_device = s + .read::>()? .and_then(|offset| data.get(offset.to_usize()..)) .and_then(Device::parse); - table.y_device = s.read::>()? + table.y_device = s + .read::>()? .and_then(|offset| data.get(offset.to_usize()..)) .and_then(Device::parse); } @@ -837,7 +856,6 @@ impl<'a> Anchor<'a> { } } - /// An [`Anchor`] parsing helper. #[derive(Clone, Copy)] pub struct AnchorMatrix<'a> { @@ -855,7 +873,12 @@ impl<'a> AnchorMatrix<'a> { let rows = s.read::()?; let count = u32::from(rows) * u32::from(cols); let matrix = s.read_array32(count)?; - Some(Self { data, rows, cols, matrix }) + Some(Self { + data, + rows, + cols, + matrix, + }) } /// Returns an [`Anchor`] at position. @@ -872,7 +895,6 @@ impl core::fmt::Debug for AnchorMatrix<'_> { } } - /// A [Mark-to-Mark Attachment Positioning Subtable]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#MMP). #[allow(missing_docs)] @@ -894,14 +916,18 @@ impl<'a> MarkToMarkAdjustment<'a> { let class_count = s.read::()?; let marks = MarkArray::parse(s.read_at_offset16(data)?)?; let mark2_matrix = AnchorMatrix::parse(s.read_at_offset16(data)?, class_count)?; - Some(Self { mark1_coverage, mark2_coverage, marks, mark2_matrix }) + Some(Self { + mark1_coverage, + mark2_coverage, + marks, + mark2_matrix, + }) } _ => None, } } } - /// A glyph positioning /// [lookup subtable](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#table-organization) /// enumeration. diff --git a/src/tables/gsub.rs b/src/tables/gsub.rs index 7f897041..60d01896 100644 --- a/src/tables/gsub.rs +++ b/src/tables/gsub.rs @@ -4,9 +4,9 @@ // A heavily modified port of https://github.com/RazrFalcon/rustybuzz implementation // originally written by https://github.com/laurmaedje -use crate::GlyphId; use crate::opentype_layout::{ChainedContextLookup, ContextLookup, Coverage, LookupSubtable}; use crate::parser::{FromSlice, LazyArray16, LazyOffsetArray16, Stream}; +use crate::GlyphId; /// A [Single Substitution Subtable](https://docs.microsoft.com/en-us/typography/opentype/spec/gsub#SS). #[allow(missing_docs)] @@ -35,7 +35,10 @@ impl<'a> SingleSubstitution<'a> { let coverage = Coverage::parse(s.read_at_offset16(data)?)?; let count = s.read::()?; let substitutes = s.read_array16(count)?; - Some(Self::Format2 { coverage, substitutes }) + Some(Self::Format2 { + coverage, + substitutes, + }) } _ => None, } @@ -51,7 +54,6 @@ impl<'a> SingleSubstitution<'a> { } } - /// A sequence of glyphs for /// [Multiple Substitution Subtable](https://docs.microsoft.com/en-us/typography/opentype/spec/gsub#MS). #[derive(Clone, Copy, Debug)] @@ -98,7 +100,6 @@ impl<'a> MultipleSubstitution<'a> { } } - /// A list of glyphs for /// [Alternate Substitution Subtable](https://docs.microsoft.com/en-us/typography/opentype/spec/gsub#AS). #[derive(Clone, Copy, Debug)] @@ -145,7 +146,6 @@ impl<'a> AlternateSubstitution<'a> { } } - /// Glyph components for one ligature. #[derive(Clone, Copy, Debug)] pub struct Ligature<'a> { @@ -203,7 +203,6 @@ impl<'a> LigatureSubstitution<'a> { } } - /// A [Reverse Chaining Contextual Single Substitution Subtable]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/gsub#RCCS). #[allow(missing_docs)] @@ -239,7 +238,6 @@ impl<'a> ReverseChainSingleSubstitution<'a> { } } - /// A glyph substitution /// [lookup subtable](https://docs.microsoft.com/en-us/typography/opentype/spec/gsub#table-organization) /// enumeration. diff --git a/src/tables/gvar.rs b/src/tables/gvar.rs index 7cf259e5..1f91af90 100644 --- a/src/tables/gvar.rs +++ b/src/tables/gvar.rs @@ -7,9 +7,9 @@ use core::cmp; use core::convert::TryFrom; use core::num::NonZeroU16; -use crate::{GlyphId, OutlineBuilder, Rect, BBox, NormalizedCoordinate}; -use crate::parser::{Stream, Offset, Offset16, Offset32, LazyArray16, F2DOT14}; use crate::glyf::{self, Transform}; +use crate::parser::{LazyArray16, Offset, Offset16, Offset32, Stream, F2DOT14}; +use crate::{BBox, GlyphId, NormalizedCoordinate, OutlineBuilder, Rect}; /// 'The TrueType rasterizer dynamically generates 'phantom' points for each glyph /// that represent horizontal and vertical advance widths and side bearings, @@ -24,7 +24,6 @@ enum GlyphVariationDataOffsets<'a> { Long(LazyArray16<'a, Offset32>), } - #[derive(Clone, Copy, Default, Debug)] struct PointAndDelta { x: i16, @@ -33,7 +32,6 @@ struct PointAndDelta { y_delta: f32, } - // This structure will be used by the `VariationTuples` stack buffer, // so it has to be as small as possible. #[derive(Clone, Copy, Default)] @@ -45,7 +43,6 @@ struct VariationTuple<'a> { prev_point: Option, } - /// The maximum number of variation tuples stored on the stack. /// /// The TrueType spec allows up to 4095 tuples, which is way larger @@ -61,17 +58,20 @@ const MAX_STACK_TUPLES_LEN: u16 = 32; enum VariationTuples<'a> { Stack { headers: [VariationTuple<'a>; MAX_STACK_TUPLES_LEN as usize], - len: u16 + len: u16, }, #[cfg(feature = "gvar-alloc")] Heap { - vec: std::vec::Vec> - } + vec: std::vec::Vec>, + }, } impl<'a> Default for VariationTuples<'a> { fn default() -> Self { - Self::Stack { headers: [VariationTuple::default(); MAX_STACK_TUPLES_LEN as usize], len: 0 } + Self::Stack { + headers: [VariationTuple::default(); MAX_STACK_TUPLES_LEN as usize], + len: 0, + } } } @@ -102,7 +102,7 @@ impl<'a> VariationTuples<'a> { true } // ... or do nothing if the vec is already large enough or we're on the stack. - _ => true + _ => true, } } @@ -118,7 +118,7 @@ impl<'a> VariationTuples<'a> { match self { Self::Stack { len, .. } => *len, #[cfg(feature = "gvar-alloc")] - Self::Heap { vec } => vec.len() as u16 + Self::Heap { vec } => vec.len() as u16, } } @@ -134,11 +134,11 @@ impl<'a> VariationTuples<'a> { Self::Stack { headers, len } => { headers[usize::from(*len)] = header; *len += 1; - }, - Self::Heap { vec } => vec.push(header) + } + Self::Heap { vec } => vec.push(header), } } - + /// Append a new tuple header to the list. /// This may panic if the list can't hold a new header. #[cfg(not(feature = "gvar-alloc"))] @@ -157,7 +157,7 @@ impl<'a> VariationTuples<'a> { match self { Self::Stack { len, .. } => *len = 0, #[cfg(feature = "gvar-alloc")] - Self::Heap { vec } => vec.clear() + Self::Heap { vec } => vec.clear(), } } @@ -166,7 +166,7 @@ impl<'a> VariationTuples<'a> { match self { Self::Stack { headers, len } => &mut headers[0..usize::from(*len)], #[cfg(feature = "gvar-alloc")] - Self::Heap { vec } => vec.as_mut_slice() + Self::Heap { vec } => vec.as_mut_slice(), } } @@ -185,7 +185,10 @@ impl<'a> VariationTuples<'a> { if let Some((x_delta, y_delta)) = tuple.deltas.next() { // Remember the last set point and delta. tuple.prev_point = Some(PointAndDelta { - x: point.x, y: point.y, x_delta, y_delta + x: point.x, + y: point.y, + x_delta, + y_delta, }); x += x_delta; @@ -194,7 +197,11 @@ impl<'a> VariationTuples<'a> { // If there are no more deltas, we have to resolve them manually. let set_points = set_points.clone(); let (x_delta, y_delta) = infer_deltas( - tuple, set_points, points.clone(), all_points.clone(), point + tuple, + set_points, + points.clone(), + all_points.clone(), + point, ); x += x_delta; @@ -203,9 +210,8 @@ impl<'a> VariationTuples<'a> { } else { // Point is not referenced, so we have to resolve it. let set_points = set_points.clone(); - let (x_delta, y_delta) = infer_deltas( - tuple, set_points, points.clone(), all_points.clone(), point - ); + let (x_delta, y_delta) = + infer_deltas(tuple, set_points, points.clone(), all_points.clone(), point); x += x_delta; y += y_delta; @@ -252,7 +258,6 @@ impl<'a> VariationTuples<'a> { } } - #[derive(Clone, Copy, Default, Debug)] struct TupleVariationHeaderData { scalar: f32, @@ -260,7 +265,6 @@ struct TupleVariationHeaderData { serialized_data_len: u16, } - // https://docs.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuplevariationheader fn parse_variation_tuples<'a>( count: u16, @@ -356,9 +360,15 @@ fn parse_tuple_variation_header( }; let (start_tuple, end_tuple) = if has_intermediate_region { - (s.read_array16::(axis_count)?, s.read_array16::(axis_count)?) + ( + s.read_array16::(axis_count)?, + s.read_array16::(axis_count)?, + ) } else { - (LazyArray16::::default(), LazyArray16::::default()) + ( + LazyArray16::::default(), + LazyArray16::::default(), + ) }; let mut header = TupleVariationHeaderData { @@ -410,10 +420,9 @@ fn parse_tuple_variation_header( Some(header) } - // https://docs.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#packed-point-numbers mod packed_points { - use crate::parser::{Stream, FromData}; + use crate::parser::{FromData, Stream}; struct Control(u8); @@ -422,23 +431,28 @@ mod packed_points { const POINT_RUN_COUNT_MASK: u8 = 0x7F; #[inline] - fn is_points_are_words(&self) -> bool { self.0 & Self::POINTS_ARE_WORDS_FLAG != 0 } + fn is_points_are_words(&self) -> bool { + self.0 & Self::POINTS_ARE_WORDS_FLAG != 0 + } // 'Mask for the low 7 bits to provide the number of point values in the run, minus one.' // So we have to add 1. // It will never overflow because of a mask. #[inline] - fn run_count(&self) -> u8 { (self.0 & Self::POINT_RUN_COUNT_MASK) + 1 } + fn run_count(&self) -> u8 { + (self.0 & Self::POINT_RUN_COUNT_MASK) + 1 + } } impl FromData for Control { const SIZE: usize = 1; #[inline] - fn parse(data: &[u8]) -> Option { data.get(0).copied().map(Control) } + fn parse(data: &[u8]) -> Option { + data.get(0).copied().map(Control) + } } - #[derive(Clone, Copy, PartialEq)] enum State { Control, @@ -488,7 +502,9 @@ mod packed_points { let run_count = u16::from(control.run_count()); let is_points_are_words = control.is_points_are_words(); // Do not actually parse the number, simply advance. - s.advance_checked(if is_points_are_words { 2 } else { 1 } * usize::from(run_count))?; + s.advance_checked( + if is_points_are_words { 2 } else { 1 } * usize::from(run_count), + )?; i += run_count; } @@ -558,7 +574,6 @@ mod packed_points { } } - // The `PackedPointsIter` will return referenced point numbers as deltas. // i.e. 1 2 4 is actually 1 3 7 // But this is not very useful in our current algorithm, @@ -615,7 +630,6 @@ mod packed_points { } } - #[cfg(test)] mod tests { use super::*; @@ -629,7 +643,9 @@ mod packed_points { assert!(control.run_count > 0, "run count cannot be zero"); let mut n = 0; - if control.deltas_are_words { n |= 0x80; } + if control.deltas_are_words { + n |= 0x80; + } n |= (control.run_count - 1) & 0x7F; n } @@ -650,11 +666,16 @@ mod packed_points { fn single_point() { let data = vec![ 1, // total count - gen_control(NewControl { deltas_are_words: false, run_count: 1 }), - 1 + gen_control(NewControl { + deltas_are_words: false, + run_count: 1, + }), + 1, ]; - let points_iter = PackedPointsIter::new(&mut Stream::new(&data)).unwrap().unwrap(); + let points_iter = PackedPointsIter::new(&mut Stream::new(&data)) + .unwrap() + .unwrap(); let mut iter = SetPointsIter::new(points_iter); assert_eq!(iter.next().unwrap(), false); assert_eq!(iter.next().unwrap(), true); @@ -665,11 +686,17 @@ mod packed_points { fn set_0_and_2() { let data = vec![ 2, // total count - gen_control(NewControl { deltas_are_words: false, run_count: 2 }), - 0, 2 + gen_control(NewControl { + deltas_are_words: false, + run_count: 2, + }), + 0, + 2, ]; - let points_iter = PackedPointsIter::new(&mut Stream::new(&data)).unwrap().unwrap(); + let points_iter = PackedPointsIter::new(&mut Stream::new(&data)) + .unwrap() + .unwrap(); let mut iter = SetPointsIter::new(points_iter); assert_eq!(iter.next().unwrap(), true); assert_eq!(iter.next().unwrap(), false); @@ -681,11 +708,17 @@ mod packed_points { fn set_1_and_2() { let data = vec![ 2, // total count - gen_control(NewControl { deltas_are_words: false, run_count: 2 }), - 1, 1 + gen_control(NewControl { + deltas_are_words: false, + run_count: 2, + }), + 1, + 1, ]; - let points_iter = PackedPointsIter::new(&mut Stream::new(&data)).unwrap().unwrap(); + let points_iter = PackedPointsIter::new(&mut Stream::new(&data)) + .unwrap() + .unwrap(); let mut iter = SetPointsIter::new(points_iter); assert_eq!(iter.next().unwrap(), false); assert_eq!(iter.next().unwrap(), true); @@ -697,11 +730,17 @@ mod packed_points { fn set_1_and_3() { let data = vec![ 2, // total count - gen_control(NewControl { deltas_are_words: false, run_count: 2 }), - 1, 2 + gen_control(NewControl { + deltas_are_words: false, + run_count: 2, + }), + 1, + 2, ]; - let points_iter = PackedPointsIter::new(&mut Stream::new(&data)).unwrap().unwrap(); + let points_iter = PackedPointsIter::new(&mut Stream::new(&data)) + .unwrap() + .unwrap(); let mut iter = SetPointsIter::new(points_iter); assert_eq!(iter.next().unwrap(), false); assert_eq!(iter.next().unwrap(), true); @@ -714,11 +753,18 @@ mod packed_points { fn set_2_5_7() { let data = vec![ 3, // total count - gen_control(NewControl { deltas_are_words: false, run_count: 3 }), - 2, 3, 2 + gen_control(NewControl { + deltas_are_words: false, + run_count: 3, + }), + 2, + 3, + 2, ]; - let points_iter = PackedPointsIter::new(&mut Stream::new(&data)).unwrap().unwrap(); + let points_iter = PackedPointsIter::new(&mut Stream::new(&data)) + .unwrap() + .unwrap(); let mut iter = SetPointsIter::new(points_iter); assert_eq!(iter.next().unwrap(), false); assert_eq!(iter.next().unwrap(), false); @@ -738,16 +784,24 @@ mod packed_points { data.push(Control::POINTS_ARE_WORDS_FLAG); data.push(150); - data.push(gen_control(NewControl { deltas_are_words: false, run_count: 100 })); + data.push(gen_control(NewControl { + deltas_are_words: false, + run_count: 100, + })); for _ in 0..100 { data.push(2); } - data.push(gen_control(NewControl { deltas_are_words: false, run_count: 50 })); + data.push(gen_control(NewControl { + deltas_are_words: false, + run_count: 50, + })); for _ in 0..50 { data.push(2); } - let points_iter = PackedPointsIter::new(&mut Stream::new(&data)).unwrap().unwrap(); + let points_iter = PackedPointsIter::new(&mut Stream::new(&data)) + .unwrap() + .unwrap(); let mut iter = SetPointsIter::new(points_iter); assert_eq!(iter.next().unwrap(), false); for _ in 0..150 { @@ -762,11 +816,19 @@ mod packed_points { fn long_points() { let data = vec![ 2, // total count - gen_control(NewControl { deltas_are_words: true, run_count: 2 }), - 0, 2, 0, 3 + gen_control(NewControl { + deltas_are_words: true, + run_count: 2, + }), + 0, + 2, + 0, + 3, ]; - let points_iter = PackedPointsIter::new(&mut Stream::new(&data)).unwrap().unwrap(); + let points_iter = PackedPointsIter::new(&mut Stream::new(&data)) + .unwrap() + .unwrap(); let mut iter = SetPointsIter::new(points_iter); assert_eq!(iter.next().unwrap(), false); assert_eq!(iter.next().unwrap(), false); @@ -781,13 +843,26 @@ mod packed_points { fn multiple_runs() { let data = vec![ 5, // total count - gen_control(NewControl { deltas_are_words: true, run_count: 2 }), - 0, 2, 0, 3, - gen_control(NewControl { deltas_are_words: false, run_count: 3 }), - 2, 3, 2 + gen_control(NewControl { + deltas_are_words: true, + run_count: 2, + }), + 0, + 2, + 0, + 3, + gen_control(NewControl { + deltas_are_words: false, + run_count: 3, + }), + 2, + 3, + 2, ]; - let points_iter = PackedPointsIter::new(&mut Stream::new(&data)).unwrap().unwrap(); + let points_iter = PackedPointsIter::new(&mut Stream::new(&data)) + .unwrap() + .unwrap(); let mut iter = SetPointsIter::new(points_iter); assert_eq!(iter.next().unwrap(), false); assert_eq!(iter.next().unwrap(), false); @@ -816,7 +891,6 @@ mod packed_points { use packed_points::*; - // https://docs.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#packed-deltas mod packed_deltas { use crate::parser::Stream; @@ -829,19 +903,24 @@ mod packed_deltas { const DELTA_RUN_COUNT_MASK: u8 = 0x3F; #[inline] - fn is_deltas_are_zero(&self) -> bool { self.0 & Self::DELTAS_ARE_ZERO_FLAG != 0 } + fn is_deltas_are_zero(&self) -> bool { + self.0 & Self::DELTAS_ARE_ZERO_FLAG != 0 + } #[inline] - fn is_deltas_are_words(&self) -> bool { self.0 & Self::DELTAS_ARE_WORDS_FLAG != 0 } + fn is_deltas_are_words(&self) -> bool { + self.0 & Self::DELTAS_ARE_WORDS_FLAG != 0 + } // 'Mask for the low 6 bits to provide the number of delta values in the run, minus one.' // So we have to add 1. // It will never overflow because of a mask. #[inline] - fn run_count(&self) -> u8 { (self.0 & Self::DELTA_RUN_COUNT_MASK) + 1 } + fn run_count(&self) -> u8 { + (self.0 & Self::DELTA_RUN_COUNT_MASK) + 1 + } } - #[derive(Clone, Copy, PartialEq, Debug)] enum State { Control, @@ -857,7 +936,6 @@ mod packed_deltas { } } - #[derive(Clone, Copy, Default)] struct RunState { data_offset: u16, @@ -907,7 +985,6 @@ mod packed_deltas { } } - // This structure will be used by the `VariationTuples` stack buffer, // so it has to be as small as possible. // Therefore we cannot use `Stream` and other abstractions. @@ -979,8 +1056,12 @@ mod packed_deltas { assert!(control.run_count > 0, "run count cannot be zero"); let mut n = 0; - if control.deltas_are_zero { n |= 0x80; } - if control.deltas_are_words { n |= 0x40; } + if control.deltas_are_zero { + n |= 0x80; + } + if control.deltas_are_words { + n |= 0x40; + } n |= (control.run_count - 1) & 0x3F; n } @@ -994,8 +1075,13 @@ mod packed_deltas { #[test] fn single_delta() { let data = vec![ - gen_control(NewControl { deltas_are_zero: false, deltas_are_words: false, run_count: 2 }), - 2, 3 + gen_control(NewControl { + deltas_are_zero: false, + deltas_are_words: false, + run_count: 2, + }), + 2, + 3, ]; let mut iter = PackedDeltasIter::new(1.0, 1, &data); @@ -1006,8 +1092,15 @@ mod packed_deltas { #[test] fn two_deltas() { let data = vec![ - gen_control(NewControl { deltas_are_zero: false, deltas_are_words: false, run_count: 4 }), - 2, 3, 4, 5, + gen_control(NewControl { + deltas_are_zero: false, + deltas_are_words: false, + run_count: 4, + }), + 2, + 3, + 4, + 5, ]; let mut iter = PackedDeltasIter::new(1.0, 2, &data); @@ -1020,8 +1113,15 @@ mod packed_deltas { #[test] fn single_long_delta() { let data = vec![ - gen_control(NewControl { deltas_are_zero: false, deltas_are_words: true, run_count: 2 }), - 0, 2, 0, 3 + gen_control(NewControl { + deltas_are_zero: false, + deltas_are_words: true, + run_count: 2, + }), + 0, + 2, + 0, + 3, ]; let mut iter = PackedDeltasIter::new(1.0, 1, &data); @@ -1031,9 +1131,11 @@ mod packed_deltas { #[test] fn zeros() { - let data = vec![ - gen_control(NewControl { deltas_are_zero: true, deltas_are_words: false, run_count: 4 }), - ]; + let data = vec![gen_control(NewControl { + deltas_are_zero: true, + deltas_are_words: false, + run_count: 4, + })]; let mut iter = PackedDeltasIter::new(1.0, 2, &data); assert_eq!(iter.next().unwrap(), (0.0, 0.0)); @@ -1045,9 +1147,11 @@ mod packed_deltas { fn zero_words() { // When `deltas_are_zero` is set, `deltas_are_words` should be ignored. - let data = vec![ - gen_control(NewControl { deltas_are_zero: true, deltas_are_words: true, run_count: 4 }), - ]; + let data = vec![gen_control(NewControl { + deltas_are_zero: true, + deltas_are_words: true, + run_count: 4, + })]; let mut iter = PackedDeltasIter::new(1.0, 2, &data); assert_eq!(iter.next().unwrap(), (0.0, 0.0)); @@ -1058,9 +1162,21 @@ mod packed_deltas { #[test] fn zero_runs() { let data = vec![ - gen_control(NewControl { deltas_are_zero: true, deltas_are_words: false, run_count: 2 }), - gen_control(NewControl { deltas_are_zero: true, deltas_are_words: false, run_count: 4 }), - gen_control(NewControl { deltas_are_zero: true, deltas_are_words: false, run_count: 6 }), + gen_control(NewControl { + deltas_are_zero: true, + deltas_are_words: false, + run_count: 2, + }), + gen_control(NewControl { + deltas_are_zero: true, + deltas_are_words: false, + run_count: 4, + }), + gen_control(NewControl { + deltas_are_zero: true, + deltas_are_words: false, + run_count: 6, + }), ]; let mut iter = PackedDeltasIter::new(1.0, 6, &data); @@ -1079,9 +1195,18 @@ mod packed_deltas { #[test] fn delta_after_zeros() { let data = vec![ - gen_control(NewControl { deltas_are_zero: true, deltas_are_words: false, run_count: 2 }), - gen_control(NewControl { deltas_are_zero: false, deltas_are_words: false, run_count: 2 }), - 2, 3 + gen_control(NewControl { + deltas_are_zero: true, + deltas_are_words: false, + run_count: 2, + }), + gen_control(NewControl { + deltas_are_zero: false, + deltas_are_words: false, + run_count: 2, + }), + 2, + 3, ]; let mut iter = PackedDeltasIter::new(1.0, 2, &data); @@ -1092,9 +1217,11 @@ mod packed_deltas { #[test] fn unexpected_end_of_data_1() { - let data = vec![ - gen_control(NewControl { deltas_are_zero: false, deltas_are_words: false, run_count: 2 }), - ]; + let data = vec![gen_control(NewControl { + deltas_are_zero: false, + deltas_are_words: false, + run_count: 2, + })]; let mut iter = PackedDeltasIter::new(1.0, 1, &data); assert!(iter.next().is_none()); @@ -1105,8 +1232,12 @@ mod packed_deltas { // Only X is set. let data = vec![ - gen_control(NewControl { deltas_are_zero: false, deltas_are_words: false, run_count: 2 }), - 1 + gen_control(NewControl { + deltas_are_zero: false, + deltas_are_words: false, + run_count: 2, + }), + 1, ]; let mut iter = PackedDeltasIter::new(1.0, 1, &data); @@ -1115,9 +1246,11 @@ mod packed_deltas { #[test] fn unexpected_end_of_data_3() { - let data = vec![ - gen_control(NewControl { deltas_are_zero: false, deltas_are_words: true, run_count: 2 }), - ]; + let data = vec![gen_control(NewControl { + deltas_are_zero: false, + deltas_are_words: true, + run_count: 2, + })]; let mut iter = PackedDeltasIter::new(1.0, 1, &data); assert!(iter.next().is_none()); @@ -1128,8 +1261,12 @@ mod packed_deltas { // X data is too short. let data = vec![ - gen_control(NewControl { deltas_are_zero: false, deltas_are_words: true, run_count: 2 }), - 1 + gen_control(NewControl { + deltas_are_zero: false, + deltas_are_words: true, + run_count: 2, + }), + 1, ]; let mut iter = PackedDeltasIter::new(1.0, 1, &data); @@ -1141,8 +1278,13 @@ mod packed_deltas { // Only X is set. let data = vec![ - gen_control(NewControl { deltas_are_zero: false, deltas_are_words: true, run_count: 2 }), - 0, 1 + gen_control(NewControl { + deltas_are_zero: false, + deltas_are_words: true, + run_count: 2, + }), + 0, + 1, ]; let mut iter = PackedDeltasIter::new(1.0, 1, &data); @@ -1154,8 +1296,14 @@ mod packed_deltas { // Y data is too short. let data = vec![ - gen_control(NewControl { deltas_are_zero: false, deltas_are_words: true, run_count: 2 }), - 0, 1, 0 + gen_control(NewControl { + deltas_are_zero: false, + deltas_are_words: true, + run_count: 2, + }), + 0, + 1, + 0, ]; let mut iter = PackedDeltasIter::new(1.0, 1, &data); @@ -1165,8 +1313,13 @@ mod packed_deltas { #[test] fn single_run() { let data = vec![ - gen_control(NewControl { deltas_are_zero: false, deltas_are_words: false, run_count: 1 }), - 2, 3 + gen_control(NewControl { + deltas_are_zero: false, + deltas_are_words: false, + run_count: 1, + }), + 2, + 3, ]; let mut iter = PackedDeltasIter::new(1.0, 1, &data); @@ -1176,8 +1329,13 @@ mod packed_deltas { #[test] fn too_many_pairs() { let data = vec![ - gen_control(NewControl { deltas_are_zero: false, deltas_are_words: false, run_count: 2 }), - 2, 3 + gen_control(NewControl { + deltas_are_zero: false, + deltas_are_words: false, + run_count: 2, + }), + 2, + 3, ]; // We have only one pair, not 10. @@ -1188,8 +1346,17 @@ mod packed_deltas { #[test] fn invalid_number_of_pairs() { let data = vec![ - gen_control(NewControl { deltas_are_zero: false, deltas_are_words: false, run_count: 2 }), - 2, 3, 4, 5, 6, 7, + gen_control(NewControl { + deltas_are_zero: false, + deltas_are_words: false, + run_count: 2, + }), + 2, + 3, + 4, + 5, + 6, + 7, ]; // We have 3 pairs, not 4. @@ -1204,11 +1371,28 @@ mod packed_deltas { #[test] fn mixed_runs() { let data = vec![ - gen_control(NewControl { deltas_are_zero: false, deltas_are_words: false, run_count: 3 }), - 2, 3, 4, - gen_control(NewControl { deltas_are_zero: false, deltas_are_words: true, run_count: 2 }), - 0, 5, 0, 6, - gen_control(NewControl { deltas_are_zero: true, deltas_are_words: false, run_count: 1 }), + gen_control(NewControl { + deltas_are_zero: false, + deltas_are_words: false, + run_count: 3, + }), + 2, + 3, + 4, + gen_control(NewControl { + deltas_are_zero: false, + deltas_are_words: true, + run_count: 2, + }), + 0, + 5, + 0, + 6, + gen_control(NewControl { + deltas_are_zero: true, + deltas_are_words: false, + run_count: 1, + }), ]; let mut iter = PackedDeltasIter::new(1.0, 3, &data); @@ -1221,8 +1405,13 @@ mod packed_deltas { #[test] fn non_default_scalar() { let data = vec![ - gen_control(NewControl { deltas_are_zero: false, deltas_are_words: false, run_count: 2 }), - 2, 3 + gen_control(NewControl { + deltas_are_zero: false, + deltas_are_words: false, + run_count: 2, + }), + 2, + 3, ]; let mut iter = PackedDeltasIter::new(0.5, 1, &data); @@ -1242,7 +1431,6 @@ mod packed_deltas { use packed_deltas::PackedDeltasIter; - /// Infer unreferenced deltas. /// /// A font can define deltas only for specific points, to reduce the file size. @@ -1385,11 +1573,21 @@ fn infer_deltas( None => return (0.0, 0.0), }; - let dx = infer_delta(prev_point.x, curr_point.x, next_point.x, - prev_point.x_delta, next_point.x_delta); - - let dy = infer_delta(prev_point.y, curr_point.y, next_point.y, - prev_point.y_delta, next_point.y_delta); + let dx = infer_delta( + prev_point.x, + curr_point.x, + next_point.x, + prev_point.x_delta, + next_point.x_delta, + ); + + let dy = infer_delta( + prev_point.y, + curr_point.y, + next_point.y, + prev_point.y_delta, + next_point.y_delta, + ); (dx, dy) } @@ -1402,23 +1600,34 @@ fn infer_delta( next_delta: f32, ) -> f32 { if prev_point == next_point { - if prev_delta == next_delta { prev_delta } else { 0.0 } + if prev_delta == next_delta { + prev_delta + } else { + 0.0 + } } else if target_point <= prev_point.min(next_point) { - if prev_point < next_point { prev_delta } else { next_delta } + if prev_point < next_point { + prev_delta + } else { + next_delta + } } else if target_point >= prev_point.max(next_point) { - if prev_point > next_point { prev_delta } else { next_delta } + if prev_point > next_point { + prev_delta + } else { + next_delta + } } else { // 'Target point coordinate is between adjacent point coordinates.' // // 'Target point delta is derived from the adjacent point deltas // using linear interpolation.' - let d = f32::from(try_opt_or!(target_point.checked_sub(prev_point), 0.0)) - / f32::from(try_opt_or!(next_point.checked_sub(prev_point), 0.0)); + let d = f32::from(try_opt_or!(target_point.checked_sub(prev_point), 0.0)) + / f32::from(try_opt_or!(next_point.checked_sub(prev_point), 0.0)); (1.0 - d) * prev_delta + d * next_delta } } - /// A [Glyph Variations Table]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/gvar). #[derive(Clone, Copy)] @@ -1492,11 +1701,15 @@ impl<'a> Table<'a> { GlyphVariationDataOffsets::Short(ref array) => { // 'If the short format (Offset16) is used for offsets, // the value stored is the offset divided by 2.' - (array.get(glyph_id.0)?.to_usize() * 2, array.get(next_glyph_id)?.to_usize() * 2) - } - GlyphVariationDataOffsets::Long(ref array) => { - (array.get(glyph_id.0)?.to_usize(), array.get(next_glyph_id)?.to_usize()) + ( + array.get(glyph_id.0)?.to_usize() * 2, + array.get(next_glyph_id)?.to_usize() * 2, + ) } + GlyphVariationDataOffsets::Long(ref array) => ( + array.get(glyph_id.0)?.to_usize(), + array.get(next_glyph_id)?.to_usize(), + ), }; // Ignore empty data. @@ -1505,7 +1718,13 @@ impl<'a> Table<'a> { } let data = self.glyphs_variation_data.get(start..end)?; - parse_variation_data(coordinates, &self.shared_tuple_records, points_len, data, tuples) + parse_variation_data( + coordinates, + &self.shared_tuple_records, + points_len, + data, + tuples, + ) } /// Outlines a glyph. @@ -1518,7 +1737,15 @@ impl<'a> Table<'a> { ) -> Option { let mut b = glyf::Builder::new(Transform::default(), BBox::new(), builder); let glyph_data = glyf_table.get(glyph_id)?; - outline_var_impl(glyf_table, self, glyph_id, glyph_data, coordinates, 0, &mut b); + outline_var_impl( + glyf_table, + self, + glyph_id, + glyph_data, + coordinates, + 0, + &mut b, + ); b.bbox.to_rect() } } @@ -1602,8 +1829,13 @@ fn outline_var_impl<'a>( let mut b = glyf::Builder::new(transform, builder.bbox, builder.builder); let glyph_data = glyf_table.get(component.glyph_id)?; outline_var_impl( - glyf_table, gvar_table, component.glyph_id, - glyph_data, coordinates, depth + 1, &mut b, + glyf_table, + gvar_table, + component.glyph_id, + glyph_data, + coordinates, + depth + 1, + &mut b, )?; // Take updated bbox. diff --git a/src/tables/head.rs b/src/tables/head.rs index 6a6e3b1e..dc36b51d 100644 --- a/src/tables/head.rs +++ b/src/tables/head.rs @@ -1,8 +1,8 @@ //! A [Font Header Table]( //! https://docs.microsoft.com/en-us/typography/opentype/spec/head) implementation. +use crate::parser::{Fixed, Stream}; use crate::Rect; -use crate::parser::{Stream, Fixed}; /// An index format used by the [Index to Location Table]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/loca). @@ -13,7 +13,6 @@ pub enum IndexToLocationFormat { Long, } - /// A [Font Header Table](https://docs.microsoft.com/en-us/typography/opentype/spec/head). #[derive(Clone, Copy, Debug)] pub struct Table { @@ -34,7 +33,7 @@ impl Table { // Do not check the exact length, because some fonts include // padding in table's length in table records, which is incorrect. if data.len() < 54 { - return None + return None; } let mut s = Stream::new(data); @@ -67,7 +66,12 @@ impl Table { Some(Table { units_per_em, - global_bbox: Rect { x_min, y_min, x_max, y_max }, + global_bbox: Rect { + x_min, + y_min, + x_max, + y_max, + }, index_to_location_format, }) } diff --git a/src/tables/hhea.rs b/src/tables/hhea.rs index 8b846d88..21a5d6c1 100644 --- a/src/tables/hhea.rs +++ b/src/tables/hhea.rs @@ -22,7 +22,7 @@ impl Table { // Do not check the exact length, because some fonts include // padding in table's length in table records, which is incorrect. if data.len() < 36 { - return None + return None; } let mut s = Stream::new(data); diff --git a/src/tables/hmtx.rs b/src/tables/hmtx.rs index 451d8b09..de3eaa9b 100644 --- a/src/tables/hmtx.rs +++ b/src/tables/hmtx.rs @@ -3,8 +3,8 @@ use core::num::NonZeroU16; +use crate::parser::{FromData, LazyArray16, Stream}; use crate::GlyphId; -use crate::parser::{Stream, FromData, LazyArray16}; /// Horizontal/Vertical Metrics. #[derive(Clone, Copy, Debug)] @@ -28,7 +28,6 @@ impl FromData for Metrics { } } - /// A [Horizontal/Vertical Metrics Table]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/hmtx). /// @@ -108,7 +107,8 @@ impl<'a> Table<'a> { // 'If the number_of_metrics is less than the total number of glyphs, // then that array is followed by an array for the side bearing values // of the remaining glyphs.' - self.bearings.get(glyph_id.0.checked_sub(self.metrics.len())?) + self.bearings + .get(glyph_id.0.checked_sub(self.metrics.len())?) } } } diff --git a/src/tables/hvar.rs b/src/tables/hvar.rs index 188ea417..9f1a8047 100644 --- a/src/tables/hvar.rs +++ b/src/tables/hvar.rs @@ -3,9 +3,9 @@ use core::convert::TryFrom; -use crate::{GlyphId, NormalizedCoordinate}; -use crate::parser::{Stream, Offset, Offset32}; +use crate::parser::{Offset, Offset32, Stream}; use crate::var_store::ItemVariationStore; +use crate::{GlyphId, NormalizedCoordinate}; struct DeltaSetIndexMap<'a> { data: &'a [u8], @@ -48,12 +48,11 @@ impl<'a> DeltaSetIndexMap<'a> { let inner_index = n & ((1 << inner_index_bit_count) - 1); Some(( u16::try_from(outer_index).ok()?, - u16::try_from(inner_index).ok()? + u16::try_from(inner_index).ok()?, )) } } - /// A [Horizontal/Vertical Metrics Variations Table]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/hvar). #[derive(Clone, Copy)] @@ -103,7 +102,8 @@ impl<'a> Table<'a> { (0, glyph_id.0) }; - self.variation_store.parse_delta(outer_idx, inner_idx, coordinates) + self.variation_store + .parse_delta(outer_idx, inner_idx, coordinates) } /// Returns side bearing offset for a glyph. @@ -115,7 +115,8 @@ impl<'a> Table<'a> { ) -> Option { let set_data = self.data.get(self.lsb_mapping_offset?.to_usize()..)?; let (outer_idx, inner_idx) = DeltaSetIndexMap::new(set_data).map(glyph_id)?; - self.variation_store.parse_delta(outer_idx, inner_idx, coordinates) + self.variation_store + .parse_delta(outer_idx, inner_idx, coordinates) } } diff --git a/src/tables/kern.rs b/src/tables/kern.rs index 67d82231..41d565f8 100644 --- a/src/tables/kern.rs +++ b/src/tables/kern.rs @@ -14,13 +14,15 @@ a kerning algorithm manually. But we still try to keep the API as high-level as possible. */ -use crate::GlyphId; +#[cfg(feature = "apple-layout")] +use crate::aat; use crate::parser::{FromData, LazyArray16, NumFrom, Offset, Offset16, Stream}; -#[cfg(feature = "apple-layout")] use crate::aat; +use crate::GlyphId; #[derive(Clone, Copy, Debug)] struct OTCoverage(u8); +#[rustfmt::skip] impl OTCoverage { #[inline] fn is_horizontal(self) -> bool { self.0 & (1 << 0) != 0 } #[inline] fn has_cross_stream(self) -> bool { self.0 & (1 << 2) != 0 } @@ -35,10 +37,10 @@ impl FromData for OTCoverage { } } - #[derive(Clone, Copy, Debug)] struct AATCoverage(u8); +#[rustfmt::skip] impl AATCoverage { #[inline] fn is_horizontal(self) -> bool { self.0 & (1 << 7) == 0 } #[inline] fn has_cross_stream(self) -> bool { self.0 & (1 << 6) != 0 } @@ -54,7 +56,6 @@ impl FromData for AATCoverage { } } - /// A kerning pair. #[derive(Clone, Copy, Debug)] pub struct KerningPair { @@ -94,19 +95,19 @@ impl FromData for KerningPair { } } - /// A kerning subtable format. #[allow(missing_docs)] #[derive(Clone, Debug)] pub enum Format<'a> { Format0(Subtable0<'a>), - #[cfg(feature = "apple-layout")] Format1(aat::StateTable<'a>), - #[cfg(not(feature = "apple-layout"))] Format1, + #[cfg(feature = "apple-layout")] + Format1(aat::StateTable<'a>), + #[cfg(not(feature = "apple-layout"))] + Format1, Format2(Subtable2<'a>), Format3(Subtable3<'a>), } - /// A kerning subtable. #[derive(Clone, Debug)] pub struct Subtable<'a> { @@ -139,7 +140,6 @@ impl<'a> Subtable<'a> { } } - /// A list of subtables. /// /// The internal data layout is not designed for random access, @@ -182,7 +182,6 @@ impl<'a> IntoIterator for Subtables<'a> { } } - /// An iterator over kerning subtables. #[allow(missing_debug_implementations)] #[derive(Clone, Copy, Default)] @@ -288,7 +287,6 @@ impl<'a> Iterator for SubtablesIter<'a> { } } - /// A format 0 subtable. /// /// Ordered List of Kerning Pairs. @@ -312,11 +310,12 @@ impl<'a> Subtable0<'a> { #[inline] pub fn glyphs_kerning(&self, left: GlyphId, right: GlyphId) -> Option { let needle = u32::from(left.0) << 16 | u32::from(right.0); - self.pairs.binary_search_by(|v| v.pair.cmp(&needle)).map(|(_, v)| v.value) + self.pairs + .binary_search_by(|v| v.pair.cmp(&needle)) + .map(|(_, v)| v.value) } } - /// A format 2 subtable. /// /// Simple n x m Array of Kerning Values. @@ -350,7 +349,8 @@ impl<'a> Subtable2<'a> { // and fetching the kerning value to which the new address points.' let left_class = get_format2_class(left.0, left_hand_table_offset, self.data).unwrap_or(0); - let right_class = get_format2_class(right.0, right_hand_table_offset, self.data).unwrap_or(0); + let right_class = + get_format2_class(right.0, right_hand_table_offset, self.data).unwrap_or(0); // 'Values within the left-hand offset table should not be less than the kerning array offset.' if usize::from(left_class) < array_offset { @@ -374,7 +374,6 @@ pub(crate) fn get_format2_class(glyph_id: u16, offset: usize, data: &[u8]) -> Op classes.get(index) } - /// A format 3 subtable. /// /// Simple n x m Array of Kerning Indices. @@ -399,7 +398,8 @@ impl<'a> Subtable3<'a> { let left_hand_classes_count = s.read::()?; let right_hand_classes_count = s.read::()?; s.skip::(); // reserved - let indices_count = u16::from(left_hand_classes_count) * u16::from(right_hand_classes_count); + let indices_count = + u16::from(left_hand_classes_count) * u16::from(right_hand_classes_count); let kerning_values = s.read_array16::(u16::from(kerning_values_count))?; let left_hand_classes = s.read_array16::(glyph_count)?; @@ -413,13 +413,13 @@ impl<'a> Subtable3<'a> { return None; } - let index = u16::from(left_class) * u16::from(right_hand_classes_count) + u16::from(right_class); + let index = + u16::from(left_class) * u16::from(right_hand_classes_count) + u16::from(right_class); let index = indices.get(index)?; kerning_values.get(u16::from(index)) } } - /// A [Kerning Table](https://docs.microsoft.com/en-us/typography/opentype/spec/kern). #[derive(Clone, Copy, Debug)] pub struct Table<'a> { @@ -449,7 +449,7 @@ impl<'a> Table<'a> { } } else { s.skip::(); // Skip the second part of u32 version. - // Note that AAT stores the number of tables as u32 and not as u16. + // Note that AAT stores the number of tables as u32 and not as u16. let count = s.read::()?; Subtables { is_aat: true, diff --git a/src/tables/kerx.rs b/src/tables/kerx.rs index 3c0c1601..20a4ff38 100644 --- a/src/tables/kerx.rs +++ b/src/tables/kerx.rs @@ -7,9 +7,9 @@ use core::num::NonZeroU16; -use crate::{aat, GlyphId}; use crate::kern::KerningPair; -use crate::parser::{Stream, FromData, NumFrom, Offset32, Offset, LazyArray32}; +use crate::parser::{FromData, LazyArray32, NumFrom, Offset, Offset32, Stream}; +use crate::{aat, GlyphId}; const HEADER_SIZE: usize = 12; @@ -38,11 +38,12 @@ impl<'a> Subtable0<'a> { #[inline] pub fn glyphs_kerning(&self, left: GlyphId, right: GlyphId) -> Option { let needle = u32::from(left.0) << 16 | u32::from(right.0); - self.pairs.binary_search_by(|v| v.pair.cmp(&needle)).map(|(_, v)| v.value) + self.pairs + .binary_search_by(|v| v.pair.cmp(&needle)) + .map(|(_, v)| v.value) } } - /// A state machine entry. #[derive(Clone, Copy, Debug)] pub struct EntryData { @@ -111,7 +112,6 @@ impl core::fmt::Debug for Subtable1<'_> { } } - /// A format 2 subtable. /// /// Simple n x m Array of Kerning Values. @@ -136,8 +136,10 @@ impl<'a> Subtable2<'a> { // adding the class values to the address of the subtable, // and fetching the kerning value to which the new address points.' - let left_class = crate::kern::get_format2_class(left.0, left_hand_table_offset, self.0).unwrap_or(0); - let right_class = crate::kern::get_format2_class(right.0, right_hand_table_offset, self.0).unwrap_or(0); + let left_class = + crate::kern::get_format2_class(left.0, left_hand_table_offset, self.0).unwrap_or(0); + let right_class = + crate::kern::get_format2_class(right.0, right_hand_table_offset, self.0).unwrap_or(0); // 'Values within the left-hand offset table should not be less than the kerning array offset.' if usize::from(left_class) < array_offset { @@ -157,7 +159,6 @@ impl core::fmt::Debug for Subtable2<'_> { } } - /// A container of Anchor Points used by [`Subtable4`]. #[derive(Clone, Copy)] pub struct AnchorPoints<'a>(&'a [u8]); @@ -226,12 +227,11 @@ impl core::fmt::Debug for Subtable4<'_> { } } - /// A format 6 subtable. /// /// Simple Index-based n x m Array of Kerning Values. #[derive(Clone, Copy)] -pub struct Subtable6<'a>{ +pub struct Subtable6<'a> { data: &'a [u8], number_of_glyphs: NonZeroU16, } @@ -239,7 +239,10 @@ pub struct Subtable6<'a>{ impl<'a> Subtable6<'a> { // TODO: parse actual structure fn parse(number_of_glyphs: NonZeroU16, data: &'a [u8]) -> Self { - Subtable6 { number_of_glyphs, data } + Subtable6 { + number_of_glyphs, + data, + } } /// Returns kerning for a pair of glyphs. @@ -250,9 +253,10 @@ impl<'a> Subtable6<'a> { let flags = s.read::()?; s.skip::(); // row_count s.skip::(); // col_count - // All offsets are from the start of the subtable. + // All offsets are from the start of the subtable. let row_index_table_offset = s.read::()?.to_usize().checked_sub(HEADER_SIZE)?; - let column_index_table_offset = s.read::()?.to_usize().checked_sub(HEADER_SIZE)?; + let column_index_table_offset = + s.read::()?.to_usize().checked_sub(HEADER_SIZE)?; let kerning_array_offset = s.read::()?.to_usize().checked_sub(HEADER_SIZE)?; let kerning_vector_offset = s.read::()?.to_usize().checked_sub(HEADER_SIZE)?; @@ -264,10 +268,12 @@ impl<'a> Subtable6<'a> { let has_long_values = flags & 0x00000001 != 0; if has_long_values { let l: u32 = aat::Lookup::parse(self.number_of_glyphs, row_index_table_data)? - .value(left).unwrap_or(0) as u32; + .value(left) + .unwrap_or(0) as u32; let r: u32 = aat::Lookup::parse(self.number_of_glyphs, column_index_table_data)? - .value(right).unwrap_or(0) as u32; + .value(right) + .unwrap_or(0) as u32; let array_offset = usize::try_from(l + r).ok()?.checked_mul(i32::SIZE)?; let vector_offset: u32 = Stream::read_at(kerning_array_data, array_offset)?; @@ -275,10 +281,12 @@ impl<'a> Subtable6<'a> { Stream::read_at(kerning_vector_data, usize::num_from(vector_offset)) } else { let l: u16 = aat::Lookup::parse(self.number_of_glyphs, row_index_table_data)? - .value(left).unwrap_or(0); + .value(left) + .unwrap_or(0); let r: u16 = aat::Lookup::parse(self.number_of_glyphs, column_index_table_data)? - .value(right).unwrap_or(0); + .value(right) + .unwrap_or(0); let array_offset = usize::try_from(l + r).ok()?.checked_mul(i16::SIZE)?; let vector_offset: u16 = Stream::read_at(kerning_array_data, array_offset)?; @@ -294,7 +302,6 @@ impl core::fmt::Debug for Subtable6<'_> { } } - /// An extended kerning subtable format. #[allow(missing_docs)] #[derive(Clone, Debug)] @@ -343,10 +350,10 @@ impl<'a> Subtable<'a> { } } - #[derive(Clone, Copy, Debug)] struct Coverage(u8); +#[rustfmt::skip] impl Coverage { // TODO: use hex #[inline] pub fn is_horizontal(self) -> bool { self.0 & (1 << 7) == 0 } @@ -354,7 +361,6 @@ impl Coverage { #[inline] pub fn is_variable(self) -> bool { self.0 & (1 << 5) != 0 } } - /// A list of extended kerning subtables. /// /// The internal data layout is not designed for random access, @@ -451,7 +457,6 @@ impl<'a> Iterator for SubtablesIter<'a> { } } - /// An [Extended Kerning Table]( /// https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kerx.html). #[derive(Clone, Copy, Debug)] diff --git a/src/tables/loca.rs b/src/tables/loca.rs index 31857f8f..276587c9 100644 --- a/src/tables/loca.rs +++ b/src/tables/loca.rs @@ -1,12 +1,12 @@ //! An [Index to Location Table](https://docs.microsoft.com/en-us/typography/opentype/spec/loca) //! implementation. +use core::convert::TryFrom; use core::num::NonZeroU16; use core::ops::Range; -use core::convert::TryFrom; +use crate::parser::{LazyArray16, NumFrom, Stream}; use crate::{GlyphId, IndexToLocationFormat}; -use crate::parser::{Stream, LazyArray16, NumFrom}; /// An [Index to Location Table](https://docs.microsoft.com/en-us/typography/opentype/spec/loca). #[derive(Clone, Copy, Debug)] @@ -52,12 +52,8 @@ impl<'a> Table<'a> { let mut s = Stream::new(data); match format { - IndexToLocationFormat::Short => { - Some(Table::Short(s.read_array16::(total)?)) - } - IndexToLocationFormat::Long => { - Some(Table::Long(s.read_array16::(total)?)) - } + IndexToLocationFormat::Short => Some(Table::Short(s.read_array16::(total)?)), + IndexToLocationFormat::Long => Some(Table::Long(s.read_array16::(total)?)), } } @@ -86,10 +82,10 @@ impl<'a> Table<'a> { let range = match self { Table::Short(ref array) => { // 'The actual local offset divided by 2 is stored.' - usize::from(array.get(glyph_id)?) * 2 .. usize::from(array.get(glyph_id + 1)?) * 2 + usize::from(array.get(glyph_id)?) * 2..usize::from(array.get(glyph_id + 1)?) * 2 } Table::Long(ref array) => { - usize::num_from(array.get(glyph_id)?) .. usize::num_from(array.get(glyph_id + 1)?) + usize::num_from(array.get(glyph_id)?)..usize::num_from(array.get(glyph_id + 1)?) } }; diff --git a/src/tables/math.rs b/src/tables/math.rs index 84aed247..444ed575 100644 --- a/src/tables/math.rs +++ b/src/tables/math.rs @@ -1,9 +1,11 @@ //! A [Math Table](https://docs.microsoft.com/en-us/typography/opentype/spec/math) implementation. -use crate::GlyphId; use crate::gpos::Device; use crate::opentype_layout::Coverage; -use crate::parser::{Offset16, Stream, FromSlice, FromData, Offset, LazyArray16, LazyOffsetArray16}; +use crate::parser::{ + FromData, FromSlice, LazyArray16, LazyOffsetArray16, Offset, Offset16, Stream, +}; +use crate::GlyphId; /// A [Math Value](https://docs.microsoft.com/en-us/typography/opentype/spec/math#mathvaluerecord) /// with optional device corrections. @@ -21,7 +23,6 @@ impl<'a> MathValue<'a> { } } - /// A math value record with unresolved offset. #[derive(Clone, Copy)] struct MathValueRecord { @@ -36,20 +37,26 @@ impl FromData for MathValueRecord { let mut s = Stream::new(data); let value = s.read::()?; let device_offset = s.read::>()?; - Some(MathValueRecord { value, device_offset }) + Some(MathValueRecord { + value, + device_offset, + }) } } impl MathValueRecord { fn get(self, data: &[u8]) -> MathValue { - let device = self.device_offset + let device = self + .device_offset .and_then(|offset| data.get(offset.to_usize()..)) .and_then(Device::parse); - MathValue { value: self.value, device } + MathValue { + value: self.value, + device, + } } } - /// A mapping from glyphs to /// [Math Values](https://docs.microsoft.com/en-us/typography/opentype/spec/math#mathvaluerecord). #[derive(Clone, Copy)] @@ -65,7 +72,11 @@ impl<'a> FromSlice<'a> for MathValues<'a> { let coverage = s.parse_at_offset16::(data)?; let count = s.read::()?; let records = s.read_array16::(count)?; - Some(MathValues {data, coverage, records }) + Some(MathValues { + data, + coverage, + records, + }) } } @@ -84,7 +95,6 @@ impl core::fmt::Debug for MathValues<'_> { } } - /// A [Math Constants Table](https://learn.microsoft.com/en-us/typography/opentype/spec/math#mathconstants-table). #[derive(Clone, Copy)] pub struct Constants<'a> { @@ -103,7 +113,6 @@ impl core::fmt::Debug for Constants<'_> { } } - const SCRIPT_PERCENT_SCALE_DOWN_OFFSET: usize = 0; const SCRIPT_SCRIPT_PERCENT_SCALE_DOWN_OFFSET: usize = 2; const DELIMITED_SUB_FORMULA_MIN_HEIGHT_OFFSET: usize = 4; @@ -161,7 +170,6 @@ const RADICAL_KERN_BEFORE_DEGREE_OFFSET: usize = 204; const RADICAL_KERN_AFTER_DEGREE_OFFSET: usize = 208; const RADICAL_DEGREE_BOTTOM_RAISE_PERCENT_OFFSET: usize = 212; - impl<'a> Constants<'a> { /// Percentage of scaling down for level 1 superscripts and subscripts. #[inline] @@ -528,13 +536,16 @@ impl<'a> Constants<'a> { /// Read a `MathValueRecord` at an offset into the table. #[inline] fn read_record(&self, offset: usize) -> MathValue<'a> { - self.data.get(offset..) + self.data + .get(offset..) .and_then(|data| MathValue::parse(data, self.data)) - .unwrap_or(MathValue { value: 0, device: None }) + .unwrap_or(MathValue { + value: 0, + device: None, + }) } } - /// A [Math Kern Table](https://learn.microsoft.com/en-us/typography/opentype/spec/math#mathkern-table). #[derive(Clone)] pub struct Kern<'a> { @@ -570,7 +581,11 @@ impl<'a> FromSlice<'a> for Kern<'a> { let count = s.read::()?; let heights = s.read_array16::(count)?; let kerns = s.read_array16::(count + 1)?; - Some(Kern { data, heights, kerns }) + Some(Kern { + data, + heights, + kerns, + }) } } @@ -580,7 +595,6 @@ impl core::fmt::Debug for Kern<'_> { } } - #[derive(Clone, Copy)] struct KernInfoRecord { top_right: Option, @@ -605,9 +619,11 @@ impl FromData for KernInfoRecord { impl KernInfoRecord { fn get<'a>(&self, data: &'a [u8]) -> KernInfo<'a> { - let parse_field = |offset: Option| offset - .and_then(|offset| data.get(offset.to_usize()..)) - .and_then(Kern::parse); + let parse_field = |offset: Option| { + offset + .and_then(|offset| data.get(offset.to_usize()..)) + .and_then(Kern::parse) + }; KernInfo { top_right: parse_field(self.top_right), top_left: parse_field(self.top_left), @@ -617,7 +633,6 @@ impl KernInfoRecord { } } - /// An [entry in a Math Kern Info Table]( /// https://learn.microsoft.com/en-us/typography/opentype/spec/math#mathkerninforecord). #[derive(Clone, Debug)] @@ -632,7 +647,6 @@ pub struct KernInfo<'a> { pub bottom_left: Option>, } - /// A [Math Kern Info Table](https://docs.microsoft.com/en-us/typography/opentype/spec/math#mathkerninfo-table). #[derive(Clone, Copy)] pub struct KernInfos<'a> { @@ -647,7 +661,11 @@ impl<'a> FromSlice<'a> for KernInfos<'a> { let coverage = s.parse_at_offset16::(data)?; let count = s.read::()?; let records = s.read_array16::(count)?; - Some(KernInfos { data, coverage, records }) + Some(KernInfos { + data, + coverage, + records, + }) } } @@ -666,7 +684,6 @@ impl core::fmt::Debug for KernInfos<'_> { } } - /// A [Math Glyph Info Table](https://learn.microsoft.com/en-us/typography/opentype/spec/math#mathglyphinfo-table). #[derive(Clone, Copy, Debug)] pub struct GlyphInfo<'a> { @@ -692,14 +709,16 @@ impl<'a> FromSlice<'a> for GlyphInfo<'a> { } } - /// Glyph part flags. #[derive(Clone, Copy, Debug)] pub struct PartFlags(pub u16); #[allow(missing_docs)] impl PartFlags { - #[inline] pub fn extender(self) -> bool { self.0 & 0x0001 != 0 } + #[inline] + pub fn extender(self) -> bool { + self.0 & 0x0001 != 0 + } } impl FromData for PartFlags { @@ -710,7 +729,6 @@ impl FromData for PartFlags { } } - /// Details for a glyph part in an assembly. #[derive(Clone, Copy, Debug)] pub struct GlyphPart { @@ -741,7 +759,6 @@ impl FromData for GlyphPart { } } - /// A [Glyph Assembly Table](https://learn.microsoft.com/en-us/typography/opentype/spec/math#glyphassembly-table). #[derive(Clone, Copy, Debug)] pub struct GlyphAssembly<'a> { @@ -757,11 +774,13 @@ impl<'a> FromSlice<'a> for GlyphAssembly<'a> { let italics_correction = s.read::()?.get(data); let count = s.read::()?; let parts = s.read_array16::(count)?; - Some(GlyphAssembly { italics_correction, parts }) + Some(GlyphAssembly { + italics_correction, + parts, + }) } } - /// Description of math glyph variants. #[derive(Clone, Copy, Debug)] pub struct GlyphVariant { @@ -778,12 +797,11 @@ impl FromData for GlyphVariant { let mut s = Stream::new(data); Some(GlyphVariant { variant_glyph: s.read::()?, - advance_measurement:s.read::()?, + advance_measurement: s.read::()?, }) } } - /// A [Math Glyph Construction Table]( /// https://learn.microsoft.com/en-us/typography/opentype/spec/math#mathglyphconstruction-table). #[derive(Clone, Copy, Debug)] @@ -804,7 +822,6 @@ impl<'a> FromSlice<'a> for GlyphConstruction<'a> { } } - /// A mapping from glyphs to /// [Math Glyph Construction Tables]( /// https://learn.microsoft.com/en-us/typography/opentype/spec/math#mathglyphconstruction-table). @@ -822,7 +839,7 @@ impl<'a> GlyphConstructions<'a> { ) -> Self { GlyphConstructions { coverage: coverage.unwrap_or(Coverage::Format1 { - glyphs: LazyArray16::new(&[]) + glyphs: LazyArray16::new(&[]), }), constructions: LazyOffsetArray16::new(data, offsets), } @@ -842,7 +859,6 @@ impl core::fmt::Debug for GlyphConstructions<'_> { } } - /// A [Math Variants Table]( /// https://learn.microsoft.com/en-us/typography/opentype/spec/math#mathvariants-table). #[derive(Clone, Copy, Debug)] @@ -867,13 +883,20 @@ impl<'a> FromSlice<'a> for Variants<'a> { let horizontal_offsets = s.read_array16::>(horizontal_count)?; Some(Variants { min_connector_overlap, - vertical_constructions: GlyphConstructions::new(data, vertical_coverage, vertical_offsets), - horizontal_constructions: GlyphConstructions::new(data, horizontal_coverage, horizontal_offsets), + vertical_constructions: GlyphConstructions::new( + data, + vertical_coverage, + vertical_offsets, + ), + horizontal_constructions: GlyphConstructions::new( + data, + horizontal_coverage, + horizontal_offsets, + ), }) } } - /// A [Math Table](https://docs.microsoft.com/en-us/typography/opentype/spec/math). #[derive(Clone, Copy, Debug)] pub struct Table<'a> { diff --git a/src/tables/maxp.rs b/src/tables/maxp.rs index 8c23dcd1..e1949c8b 100644 --- a/src/tables/maxp.rs +++ b/src/tables/maxp.rs @@ -23,8 +23,6 @@ impl Table { let n = s.read::()?; let number_of_glyphs = NonZeroU16::new(n)?; - Some(Table { - number_of_glyphs - }) + Some(Table { number_of_glyphs }) } } diff --git a/src/tables/mod.rs b/src/tables/mod.rs index 765e0622..7d55941e 100644 --- a/src/tables/mod.rs +++ b/src/tables/mod.rs @@ -17,23 +17,38 @@ pub mod svg; pub mod vhea; pub mod vorg; -#[cfg(feature = "opentype-layout")] pub mod gdef; -#[cfg(feature = "opentype-layout")] pub mod gsub; -#[cfg(feature = "opentype-layout")] pub mod gpos; -#[cfg(feature = "opentype-layout")] pub mod math; +#[cfg(feature = "opentype-layout")] +pub mod gdef; +#[cfg(feature = "opentype-layout")] +pub mod gpos; +#[cfg(feature = "opentype-layout")] +pub mod gsub; +#[cfg(feature = "opentype-layout")] +pub mod math; -#[cfg(feature = "apple-layout")] pub mod ankr; -#[cfg(feature = "apple-layout")] pub mod feat; -#[cfg(feature = "apple-layout")] pub mod kerx; -#[cfg(feature = "apple-layout")] pub mod morx; -#[cfg(feature = "apple-layout")] pub mod trak; +#[cfg(feature = "apple-layout")] +pub mod ankr; +#[cfg(feature = "apple-layout")] +pub mod feat; +#[cfg(feature = "apple-layout")] +pub mod kerx; +#[cfg(feature = "apple-layout")] +pub mod morx; +#[cfg(feature = "apple-layout")] +pub mod trak; -#[cfg(feature = "variable-fonts")] pub mod avar; -#[cfg(feature = "variable-fonts")] pub mod fvar; -#[cfg(feature = "variable-fonts")] pub mod gvar; -#[cfg(feature = "variable-fonts")] pub mod hvar; -#[cfg(feature = "variable-fonts")] pub mod mvar; +#[cfg(feature = "variable-fonts")] +pub mod avar; +#[cfg(feature = "variable-fonts")] +pub mod fvar; +#[cfg(feature = "variable-fonts")] +pub mod gvar; +#[cfg(feature = "variable-fonts")] +pub mod hvar; +#[cfg(feature = "variable-fonts")] +pub mod mvar; pub use cff::cff1; +#[cfg(feature = "variable-fonts")] +pub use cff::cff2; pub use cff::CFFError; -#[cfg(feature = "variable-fonts")] pub use cff::cff2; diff --git a/src/tables/morx.rs b/src/tables/morx.rs index b92d7d93..de80e124 100644 --- a/src/tables/morx.rs +++ b/src/tables/morx.rs @@ -12,8 +12,8 @@ use core::num::NonZeroU16; +use crate::parser::{FromData, LazyArray32, NumFrom, Offset, Offset32, Stream}; use crate::{aat, GlyphId}; -use crate::parser::{Stream, FromData, LazyArray32, NumFrom, Offset32, Offset}; /// The feature table is used to compute the sub-feature flags /// for a list of requested features and settings. @@ -44,7 +44,6 @@ impl FromData for Feature { } } - /// A contextual subtable state table trailing data. #[derive(Clone, Copy, Debug)] pub struct ContextualEntryData { @@ -114,7 +113,6 @@ impl core::fmt::Debug for ContextualSubtable<'_> { } } - /// A ligature subtable. #[derive(Clone, Debug)] pub struct LigatureSubtable<'a> { @@ -153,7 +151,6 @@ impl<'a> LigatureSubtable<'a> { } } - /// A contextual subtable state table trailing data. #[derive(Clone, Copy, Debug)] pub struct InsertionEntryData { @@ -176,7 +173,6 @@ impl FromData for InsertionEntryData { } } - /// An insertion subtable. #[derive(Clone, Debug)] pub struct InsertionSubtable<'a> { @@ -196,14 +192,10 @@ impl<'a> InsertionSubtable<'a> { // The list is unsized. let glyphs = LazyArray32::::new(data.get(offset..)?); - Some(InsertionSubtable { - state, - glyphs, - }) + Some(InsertionSubtable { state, glyphs }) } } - /// A subtable kind. #[allow(missing_docs)] #[derive(Clone, Debug)] @@ -215,11 +207,11 @@ pub enum SubtableKind<'a> { Insertion(InsertionSubtable<'a>), } - /// A subtable coverage. #[derive(Clone, Copy, Debug)] pub struct Coverage(u8); +#[rustfmt::skip] impl Coverage { /// If true, this subtable will process glyphs in logical order /// (or reverse logical order if [`is_vertical`](Self::is_vertical) is also true). @@ -233,7 +225,6 @@ impl Coverage { #[inline] pub fn is_vertical(self) -> bool { self.0 & 0x80 != 0 } } - /// A subtable in a metamorphosis chain. #[derive(Clone, Debug)] pub struct Subtable<'a> { @@ -245,7 +236,6 @@ pub struct Subtable<'a> { pub feature_flags: u32, } - /// A list of subtables in a metamorphosis chain. /// /// The internal data layout is not designed for random access, @@ -278,7 +268,6 @@ impl core::fmt::Debug for Subtables<'_> { } } - /// An iterator over a metamorphosis chain subtables. #[allow(missing_debug_implementations)] #[derive(Clone, Copy)] @@ -327,9 +316,10 @@ impl<'a> Iterator for SubtablesIter<'a> { SubtableKind::Ligature(table) } // 3 - reserved - 4 => { - SubtableKind::NonContextual(aat::Lookup::parse(self.number_of_glyphs, subtables_data)?) - } + 4 => SubtableKind::NonContextual(aat::Lookup::parse( + self.number_of_glyphs, + subtables_data, + )?), 5 => { let table = InsertionSubtable::parse(self.number_of_glyphs, subtables_data)?; SubtableKind::Insertion(table) @@ -345,7 +335,6 @@ impl<'a> Iterator for SubtablesIter<'a> { } } - /// A metamorphosis chain. #[derive(Clone, Copy, Debug)] pub struct Chain<'a> { @@ -357,7 +346,6 @@ pub struct Chain<'a> { pub subtables: Subtables<'a>, } - /// A list of metamorphosis chains. /// /// The internal data layout is not designed for random access, @@ -456,7 +444,6 @@ impl<'a> Iterator for ChainsIter<'a> { } } - /// An [Extended Glyph Metamorphosis Table]( /// https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6morx.html). /// diff --git a/src/tables/mvar.rs b/src/tables/mvar.rs index 5e8a48a6..6e4ad0f4 100644 --- a/src/tables/mvar.rs +++ b/src/tables/mvar.rs @@ -1,9 +1,9 @@ //! A [Metrics Variations Table]( //! https://docs.microsoft.com/en-us/typography/opentype/spec/mvar) implementation. -use crate::{Tag, NormalizedCoordinate}; -use crate::parser::{Stream, FromData, Offset, Offset16, LazyArray16}; +use crate::parser::{FromData, LazyArray16, Offset, Offset16, Stream}; use crate::var_store::ItemVariationStore; +use crate::{NormalizedCoordinate, Tag}; #[derive(Clone, Copy)] struct ValueRecord { @@ -26,7 +26,6 @@ impl FromData for ValueRecord { } } - /// A [Metrics Variations Table]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/mvar). #[derive(Clone, Copy)] @@ -73,7 +72,7 @@ impl<'a> Table<'a> { self.variation_store.parse_delta( record.delta_set_outer_index, record.delta_set_inner_index, - coordinates + coordinates, ) } } diff --git a/src/tables/name.rs b/src/tables/name.rs index 12c775db..8143e524 100644 --- a/src/tables/name.rs +++ b/src/tables/name.rs @@ -1,44 +1,45 @@ //! A [Naming Table]( //! https://docs.microsoft.com/en-us/typography/opentype/spec/name) implementation. -#[cfg(feature = "std")] use std::vec::Vec; -#[cfg(feature = "std")] use std::string::String; +#[cfg(feature = "std")] +use std::string::String; +#[cfg(feature = "std")] +use std::vec::Vec; -use crate::parser::{LazyArray16, FromData, Offset, Offset16, Stream}; +use crate::parser::{FromData, LazyArray16, Offset, Offset16, Stream}; /// A list of [name ID](https://docs.microsoft.com/en-us/typography/opentype/spec/name#name-ids)'s. pub mod name_id { #![allow(missing_docs)] - pub const COPYRIGHT_NOTICE: u16 = 0; - pub const FAMILY: u16 = 1; - pub const SUBFAMILY: u16 = 2; - pub const UNIQUE_ID: u16 = 3; - pub const FULL_NAME: u16 = 4; - pub const VERSION: u16 = 5; - pub const POST_SCRIPT_NAME: u16 = 6; - pub const TRADEMARK: u16 = 7; - pub const MANUFACTURER: u16 = 8; - pub const DESIGNER: u16 = 9; - pub const DESCRIPTION: u16 = 10; - pub const VENDOR_URL: u16 = 11; - pub const DESIGNER_URL: u16 = 12; - pub const LICENSE: u16 = 13; - pub const LICENSE_URL: u16 = 14; + pub const COPYRIGHT_NOTICE: u16 = 0; + pub const FAMILY: u16 = 1; + pub const SUBFAMILY: u16 = 2; + pub const UNIQUE_ID: u16 = 3; + pub const FULL_NAME: u16 = 4; + pub const VERSION: u16 = 5; + pub const POST_SCRIPT_NAME: u16 = 6; + pub const TRADEMARK: u16 = 7; + pub const MANUFACTURER: u16 = 8; + pub const DESIGNER: u16 = 9; + pub const DESCRIPTION: u16 = 10; + pub const VENDOR_URL: u16 = 11; + pub const DESIGNER_URL: u16 = 12; + pub const LICENSE: u16 = 13; + pub const LICENSE_URL: u16 = 14; // RESERVED = 15 - pub const TYPOGRAPHIC_FAMILY: u16 = 16; - pub const TYPOGRAPHIC_SUBFAMILY: u16 = 17; - pub const COMPATIBLE_FULL: u16 = 18; - pub const SAMPLE_TEXT: u16 = 19; - pub const POST_SCRIPT_CID: u16 = 20; - pub const WWS_FAMILY: u16 = 21; - pub const WWS_SUBFAMILY: u16 = 22; - pub const LIGHT_BACKGROUND_PALETTE: u16 = 23; - pub const DARK_BACKGROUND_PALETTE: u16 = 24; - pub const VARIATIONS_POST_SCRIPT_NAME_PREFIX: u16 = 25; + pub const TYPOGRAPHIC_FAMILY: u16 = 16; + pub const TYPOGRAPHIC_SUBFAMILY: u16 = 17; + pub const COMPATIBLE_FULL: u16 = 18; + pub const SAMPLE_TEXT: u16 = 19; + pub const POST_SCRIPT_CID: u16 = 20; + pub const WWS_FAMILY: u16 = 21; + pub const WWS_SUBFAMILY: u16 = 22; + pub const LIGHT_BACKGROUND_PALETTE: u16 = 23; + pub const DARK_BACKGROUND_PALETTE: u16 = 24; + pub const VARIATIONS_POST_SCRIPT_NAME_PREFIX: u16 = 25; } - /// A [platform ID](https://docs.microsoft.com/en-us/typography/opentype/spec/name#platform-ids). #[allow(missing_docs)] #[derive(Clone, Copy, PartialEq, Debug)] @@ -66,7 +67,6 @@ impl FromData for PlatformId { } } - #[inline] fn is_unicode_encoding(platform_id: PlatformId, encoding_id: u16) -> bool { // https://docs.microsoft.com/en-us/typography/opentype/spec/name#windows-encoding-ids @@ -76,15 +76,13 @@ fn is_unicode_encoding(platform_id: PlatformId, encoding_id: u16) -> bool { match platform_id { PlatformId::Unicode => true, PlatformId::Windows => match encoding_id { - WINDOWS_SYMBOL_ENCODING_ID | - WINDOWS_UNICODE_BMP_ENCODING_ID => true, + WINDOWS_SYMBOL_ENCODING_ID | WINDOWS_UNICODE_BMP_ENCODING_ID => true, _ => false, - } + }, _ => false, } } - #[derive(Clone, Copy)] struct NameRecord { platform_id: PlatformId, @@ -112,7 +110,6 @@ impl FromData for NameRecord { } } - /// A [Name Record](https://docs.microsoft.com/en-us/typography/opentype/spec/name#name-records). #[derive(Clone, Copy)] pub struct Name<'a> { @@ -177,8 +174,13 @@ impl<'a> core::fmt::Debug for Name<'a> { let name = self.to_string(); f.debug_struct("Name") - .field("name", &name.as_ref().map(core::ops::Deref::deref) - .unwrap_or("unsupported encoding")) + .field( + "name", + &name + .as_ref() + .map(core::ops::Deref::deref) + .unwrap_or("unsupported encoding"), + ) .field("platform_id", &self.platform_id) .field("encoding_id", &self.encoding_id) .field("language_id", &self.language_id) @@ -200,7 +202,6 @@ impl<'a> core::fmt::Debug for Name<'a> { } } - /// A list of face names. #[derive(Clone, Copy, Default)] pub struct Names<'a> { @@ -275,7 +276,6 @@ impl<'a> Iterator for NamesIter<'a> { } } - /// A [Naming Table]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/name). #[derive(Clone, Copy, Default, Debug)] @@ -314,6 +314,8 @@ impl<'a> Table<'a> { let storage = s.tail()?; - Some(Table { names: Names { records, storage } }) + Some(Table { + names: Names { records, storage }, + }) } } diff --git a/src/tables/os2.rs b/src/tables/os2.rs index cdbe225e..bde42e88 100644 --- a/src/tables/os2.rs +++ b/src/tables/os2.rs @@ -1,8 +1,8 @@ //! A [OS/2 and Windows Metrics Table](https://docs.microsoft.com/en-us/typography/opentype/spec/os2) //! implementation. -use crate::LineMetrics; use crate::parser::Stream; +use crate::LineMetrics; const WEIGHT_CLASS_OFFSET: usize = 4; const WIDTH_CLASS_OFFSET: usize = 6; @@ -40,16 +40,16 @@ impl Weight { #[inline] pub fn to_number(self) -> u16 { match self { - Weight::Thin => 100, - Weight::ExtraLight => 200, - Weight::Light => 300, - Weight::Normal => 400, - Weight::Medium => 500, - Weight::SemiBold => 600, - Weight::Bold => 700, - Weight::ExtraBold => 800, - Weight::Black => 900, - Weight::Other(n) => n, + Weight::Thin => 100, + Weight::ExtraLight => 200, + Weight::Light => 300, + Weight::Normal => 400, + Weight::Medium => 500, + Weight::SemiBold => 600, + Weight::Bold => 700, + Weight::ExtraBold => 800, + Weight::Black => 900, + Weight::Other(n) => n, } } } @@ -67,7 +67,7 @@ impl From for Weight { 700 => Weight::Bold, 800 => Weight::ExtraBold, 900 => Weight::Black, - _ => Weight::Other(value), + _ => Weight::Other(value), } } } @@ -79,7 +79,6 @@ impl Default for Weight { } } - /// A face [width](https://docs.microsoft.com/en-us/typography/opentype/spec/os2#uswidthclass). #[allow(missing_docs)] #[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)] @@ -100,15 +99,15 @@ impl Width { #[inline] pub fn to_number(self) -> u16 { match self { - Width::UltraCondensed => 1, - Width::ExtraCondensed => 2, - Width::Condensed => 3, - Width::SemiCondensed => 4, - Width::Normal => 5, - Width::SemiExpanded => 6, - Width::Expanded => 7, - Width::ExtraExpanded => 8, - Width::UltraExpanded => 9, + Width::UltraCondensed => 1, + Width::ExtraCondensed => 2, + Width::Condensed => 3, + Width::SemiCondensed => 4, + Width::Normal => 5, + Width::SemiExpanded => 6, + Width::Expanded => 7, + Width::ExtraExpanded => 8, + Width::UltraExpanded => 9, } } } @@ -120,7 +119,6 @@ impl Default for Width { } } - /// A face style. #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] pub enum Style { @@ -139,7 +137,6 @@ impl Default for Style { } } - /// A script metrics used by subscript and superscript. #[repr(C)] #[derive(Clone, Copy, Eq, PartialEq, Debug, Hash)] @@ -157,11 +154,11 @@ pub struct ScriptMetrics { pub y_offset: i16, } - // https://docs.microsoft.com/en-us/typography/opentype/spec/os2#fsselection #[derive(Clone, Copy)] struct SelectionFlags(u16); +#[rustfmt::skip] impl SelectionFlags { #[inline] fn italic(self) -> bool { self.0 & (1 << 0) != 0 } #[inline] fn bold(self) -> bool { self.0 & (1 << 5) != 0 } @@ -170,7 +167,6 @@ impl SelectionFlags { #[inline] fn oblique(self) -> bool { self.0 & (1 << 9) != 0 } } - /// A [OS/2 and Windows Metrics Table](https://docs.microsoft.com/en-us/typography/opentype/spec/os2). #[derive(Clone, Copy)] pub struct Table<'a> { diff --git a/src/tables/post.rs b/src/tables/post.rs index e3007306..ed696dc3 100644 --- a/src/tables/post.rs +++ b/src/tables/post.rs @@ -1,9 +1,10 @@ //! A [PostScript Table]( //! https://docs.microsoft.com/en-us/typography/opentype/spec/post) implementation. +use crate::parser::{Fixed, LazyArray16, Stream}; +#[cfg(feature = "glyph-names")] +use crate::GlyphId; use crate::LineMetrics; -use crate::parser::{Stream, Fixed, LazyArray16}; -#[cfg(feature = "glyph-names")] use crate::GlyphId; const ITALIC_ANGLE_OFFSET: usize = 4; const UNDERLINE_POSITION_OFFSET: usize = 8; @@ -274,7 +275,6 @@ const MACINTOSH_NAMES: &[&str] = &[ "dcroat", ]; - /// An iterator over glyph names. /// /// The `post` table doesn't provide the glyph names count, @@ -310,13 +310,12 @@ impl<'a> Iterator for Names<'a> { return None; } - let name = self.data.get(self.offset .. self.offset + usize::from(len))?; + let name = self.data.get(self.offset..self.offset + usize::from(len))?; self.offset += usize::from(len); core::str::from_utf8(name).ok() } } - /// A [PostScript Table](https://docs.microsoft.com/en-us/typography/opentype/spec/post). #[derive(Clone, Copy, Debug)] pub struct Table<'a> { @@ -331,7 +330,6 @@ pub struct Table<'a> { names_data: &'a [u8], } - impl<'a> Table<'a> { /// Parses a table from raw data. pub fn parse(data: &'a [u8]) -> Option { @@ -342,9 +340,11 @@ impl<'a> Table<'a> { } let version = Stream::new(data).read::()?; - if !(version == 0x00010000 || version == 0x00020000 || - version == 0x00025000 || version == 0x00030000 || - version == 0x00040000) + if !(version == 0x00010000 + || version == 0x00020000 + || version == 0x00025000 + || version == 0x00030000 + || version == 0x00040000) { return None; } @@ -398,11 +398,15 @@ impl<'a> Table<'a> { #[cfg(feature = "glyph-names")] pub fn glyph_index_by_name(&self, name: &str) -> Option { let id = if let Some(index) = MACINTOSH_NAMES.iter().position(|n| *n == name) { - self.glyph_indexes.into_iter().position(|i| usize::from(i) == index)? + self.glyph_indexes + .into_iter() + .position(|i| usize::from(i) == index)? } else { let mut index = self.names().position(|n| n == name)?; index += MACINTOSH_NAMES.len(); - self.glyph_indexes.into_iter().position(|i| usize::from(i) == index)? + self.glyph_indexes + .into_iter() + .position(|i| usize::from(i) == index)? }; Some(GlyphId(id as u16)) @@ -412,6 +416,9 @@ impl<'a> Table<'a> { /// /// Default/predefined names are not included. Just the one in the font file. pub fn names(&self) -> Names<'a> { - Names { data: self.names_data, offset: 0 } + Names { + data: self.names_data, + offset: 0, + } } } diff --git a/src/tables/sbix.rs b/src/tables/sbix.rs index 36c20b25..92ea465e 100644 --- a/src/tables/sbix.rs +++ b/src/tables/sbix.rs @@ -4,8 +4,8 @@ use core::convert::TryFrom; use core::num::NonZeroU16; +use crate::parser::{FromData, LazyArray16, LazyArray32, Offset, Offset32, Stream}; use crate::{GlyphId, RasterGlyphImage, RasterImageFormat, Tag}; -use crate::parser::{Stream, FromData, Offset, Offset32, LazyArray16, LazyArray32}; /// A strike of glyphs. #[derive(Clone, Copy)] @@ -106,7 +106,6 @@ impl core::fmt::Debug for Strike<'_> { } } - /// A list of [`Strike`]s. #[derive(Clone, Copy)] pub struct Strikes<'a> { @@ -172,7 +171,6 @@ impl<'a> Iterator for StrikesIter<'a> { } } - /// A [Standard Bitmap Graphics Table]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/sbix). #[derive(Clone, Copy, Debug)] @@ -218,8 +216,8 @@ impl<'a> Table<'a> { let mut idx = 0; let mut max_ppem = 0; for (i, strike) in self.strikes.into_iter().enumerate() { - if (pixels_per_em <= strike.pixels_per_em && strike.pixels_per_em < max_ppem) || - (pixels_per_em > max_ppem && strike.pixels_per_em > max_ppem) + if (pixels_per_em <= strike.pixels_per_em && strike.pixels_per_em < max_ppem) + || (pixels_per_em > max_ppem && strike.pixels_per_em > max_ppem) { idx = i as u32; max_ppem = strike.pixels_per_em; @@ -240,8 +238,5 @@ fn png_size(data: &[u8]) -> Option<(u16, u16)> { let height = s.read::()?; // PNG size larger than u16::MAX is an error. - Some(( - u16::try_from(width).ok()?, - u16::try_from(height).ok()?, - )) + Some((u16::try_from(width).ok()?, u16::try_from(height).ok()?)) } diff --git a/src/tables/svg.rs b/src/tables/svg.rs index 3b0ff4c4..e569bc6e 100644 --- a/src/tables/svg.rs +++ b/src/tables/svg.rs @@ -1,7 +1,7 @@ //! An [SVG Table](https://docs.microsoft.com/en-us/typography/opentype/spec/svg) implementation. -use crate::GlyphId; use crate::parser::{FromData, LazyArray16, NumFrom, Offset, Offset32, Stream}; +use crate::GlyphId; #[derive(Clone, Copy)] struct SvgDocumentRecord { @@ -26,7 +26,6 @@ impl FromData for SvgDocumentRecord { } } - /// A list of [SVG documents]( /// https://docs.microsoft.com/en-us/typography/opentype/spec/svg#svg-document-list). #[derive(Clone, Copy)] @@ -43,13 +42,16 @@ impl<'a> SvgDocumentsList<'a> { pub fn get(&self, index: u16) -> Option<&'a [u8]> { let record = self.records.get(index)?; let offset = record.svg_doc_offset?.to_usize(); - self.data.get(offset..offset + usize::num_from(record.svg_doc_length)) + self.data + .get(offset..offset + usize::num_from(record.svg_doc_length)) } /// Returns a SVG document data by glyph ID. #[inline] pub fn find(&self, glyph_id: GlyphId) -> Option<&'a [u8]> { - let index = self.records.into_iter() + let index = self + .records + .into_iter() .position(|v| (v.start_glyph_id..=v.end_glyph_id).contains(&glyph_id))?; self.get(index as u16) } @@ -66,7 +68,7 @@ impl core::fmt::Debug for SvgDocumentsList<'_> { } } -impl<'a> IntoIterator for SvgDocumentsList<'a,> { +impl<'a> IntoIterator for SvgDocumentsList<'a> { type Item = &'a [u8]; type IntoIter = SvgDocumentsListIter<'a>; @@ -79,7 +81,6 @@ impl<'a> IntoIterator for SvgDocumentsList<'a,> { } } - /// An iterator over [`SvgDocumentsList`] values. #[derive(Clone, Copy)] #[allow(missing_debug_implementations)] @@ -107,7 +108,6 @@ impl<'a> Iterator for SvgDocumentsListIter<'a> { } } - /// An [SVG Table](https://docs.microsoft.com/en-us/typography/opentype/spec/svg). #[derive(Clone, Copy, Debug)] pub struct Table<'a> { @@ -130,7 +130,7 @@ impl<'a> Table<'a> { documents: SvgDocumentsList { data: &data[doc_list_offset.0 as usize..], records, - } + }, }) } } diff --git a/src/tables/trak.rs b/src/tables/trak.rs index 7cc7c200..f0ac2c17 100644 --- a/src/tables/trak.rs +++ b/src/tables/trak.rs @@ -1,7 +1,7 @@ //! A [Tracking Table]( //! https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6trak.html) implementation. -use crate::parser::{FromData, LazyArray16, Offset, Offset16, Offset32, Fixed, Stream}; +use crate::parser::{Fixed, FromData, LazyArray16, Offset, Offset16, Offset32, Stream}; #[derive(Clone, Copy, Debug)] struct TrackTableRecord { @@ -35,7 +35,6 @@ pub struct Track<'a> { pub values: LazyArray16<'a, i16>, } - /// A list of tracks. #[derive(Clone, Copy, Default, Debug)] pub struct Tracks<'a> { @@ -95,7 +94,6 @@ impl<'a> Iterator for TracksIter<'a> { } } - /// A track data. #[derive(Clone, Copy, Default, Debug)] pub struct TrackData<'a> { @@ -129,7 +127,6 @@ impl<'a> TrackData<'a> { } } - /// A [Tracking Table]( /// https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6trak.html). #[derive(Clone, Copy, Debug)] diff --git a/src/tables/vhea.rs b/src/tables/vhea.rs index c1701e27..fca5d897 100644 --- a/src/tables/vhea.rs +++ b/src/tables/vhea.rs @@ -22,7 +22,7 @@ impl Table { // Do not check the exact length, because some fonts include // padding in table's length in table records, which is incorrect. if data.len() < 36 { - return None + return None; } let mut s = Stream::new(data); diff --git a/src/tables/vorg.rs b/src/tables/vorg.rs index eb344af4..85dcbd7c 100644 --- a/src/tables/vorg.rs +++ b/src/tables/vorg.rs @@ -1,8 +1,8 @@ //! A [Vertical Origin Table]( //! https://docs.microsoft.com/en-us/typography/opentype/spec/vorg) implementation. +use crate::parser::{FromData, LazyArray16, Stream}; use crate::GlyphId; -use crate::parser::{Stream, FromData, LazyArray16}; /// Vertical origin metrics for the /// [Vertical Origin Table](https://docs.microsoft.com/en-us/typography/opentype/spec/vorg). @@ -27,7 +27,6 @@ impl FromData for VerticalOriginMetrics { } } - /// A [Vertical Origin Table](https://docs.microsoft.com/en-us/typography/opentype/spec/vorg). #[derive(Clone, Copy, Debug)] pub struct Table<'a> { @@ -53,15 +52,13 @@ impl<'a> Table<'a> { let count = s.read::()?; let metrics = s.read_array16::(count)?; - Some(Table { - default_y, - metrics, - }) + Some(Table { default_y, metrics }) } /// Returns glyph's Y origin. pub fn glyph_y_origin(&self, glyph_id: GlyphId) -> i16 { - self.metrics.binary_search_by(|m| m.glyph_id.cmp(&glyph_id)) + self.metrics + .binary_search_by(|m| m.glyph_id.cmp(&glyph_id)) .map(|(_, m)| m.y) .unwrap_or(self.default_y) } diff --git a/src/var_store.rs b/src/var_store.rs index 6a7ad3cf..a37fcb25 100644 --- a/src/var_store.rs +++ b/src/var_store.rs @@ -2,9 +2,8 @@ //! //! +use crate::parser::{FromData, LazyArray16, NumFrom, Stream}; use crate::NormalizedCoordinate; -use crate::parser::{Stream, FromData, LazyArray16, NumFrom}; - #[derive(Clone, Copy)] pub(crate) struct ItemVariationStore<'a> { @@ -22,7 +21,7 @@ impl<'a> Default for ItemVariationStore<'a> { regions: VariationRegionList { axis_count: 0, regions: LazyArray16::new(&[]), - } + }, } } } @@ -54,7 +53,11 @@ impl<'a> ItemVariationStore<'a> { } }; - Some(ItemVariationStore { data, data_offsets: offsets, regions }) + Some(ItemVariationStore { + data, + data_offsets: offsets, + regions, + }) } pub fn region_indices(&self, index: u16) -> Option> { @@ -106,7 +109,6 @@ impl<'a> ItemVariationStore<'a> { } } - #[derive(Clone, Copy)] pub struct VariationRegionList<'a> { axis_count: u16, @@ -115,11 +117,7 @@ pub struct VariationRegionList<'a> { impl<'a> VariationRegionList<'a> { #[inline] - pub(crate) fn evaluate_region( - &self, - index: u16, - coordinates: &[NormalizedCoordinate], - ) -> f32 { + pub(crate) fn evaluate_region(&self, index: u16, coordinates: &[NormalizedCoordinate]) -> f32 { let mut v = 1.0; for (i, coord) in coordinates.iter().enumerate() { let region = match self.regions.get(index * self.axis_count + i as u16) { @@ -139,7 +137,6 @@ impl<'a> VariationRegionList<'a> { } } - #[derive(Clone, Copy)] struct RegionAxisCoordinatesRecord { start_coord: i16, diff --git a/tests/tables/main.rs b/tests/tables/main.rs index 71ee48d6..c37490bb 100644 --- a/tests/tables/main.rs +++ b/tests/tables/main.rs @@ -1,15 +1,15 @@ -mod aat; -mod ankr; -mod cff1; -mod cmap; -mod feat; -mod glyf; -mod hmtx; -mod maxp; -mod sbix; -mod trak; - -use ttf_parser::{Face, FaceParsingError, fonts_in_collection}; +#[rustfmt::skip] mod aat; +#[rustfmt::skip] mod ankr; +#[rustfmt::skip] mod cff1; +#[rustfmt::skip] mod cmap; +#[rustfmt::skip] mod feat; +#[rustfmt::skip] mod glyf; +#[rustfmt::skip] mod hmtx; +#[rustfmt::skip] mod maxp; +#[rustfmt::skip] mod sbix; +#[rustfmt::skip] mod trak; + +use ttf_parser::{fonts_in_collection, Face, FaceParsingError}; #[allow(dead_code)] #[derive(Clone, Copy)] @@ -62,11 +62,12 @@ fn convert_unit(unit: Unit, data: &mut Vec) { } } - #[test] fn empty_font() { - assert_eq!(Face::parse(&[], 0).unwrap_err(), - FaceParsingError::UnknownMagic); + assert_eq!( + Face::parse(&[], 0).unwrap_err(), + FaceParsingError::UnknownMagic + ); } #[test] @@ -74,14 +75,16 @@ fn zero_tables() { use Unit::*; let data = convert(&[ Raw(&[0x00, 0x01, 0x00, 0x00]), // magic - UInt16(0), // numTables - UInt16(0), // searchRange - UInt16(0), // entrySelector - UInt16(0), // rangeShift + UInt16(0), // numTables + UInt16(0), // searchRange + UInt16(0), // entrySelector + UInt16(0), // rangeShift ]); - assert_eq!(Face::parse(&data, 0).unwrap_err(), - FaceParsingError::NoHeadTable); + assert_eq!( + Face::parse(&data, 0).unwrap_err(), + FaceParsingError::NoHeadTable + ); } #[test] @@ -89,14 +92,16 @@ fn tables_count_overflow() { use Unit::*; let data = convert(&[ Raw(&[0x00, 0x01, 0x00, 0x00]), // magic - UInt16(std::u16::MAX), // numTables - UInt16(0), // searchRange - UInt16(0), // entrySelector - UInt16(0), // rangeShift + UInt16(std::u16::MAX), // numTables + UInt16(0), // searchRange + UInt16(0), // entrySelector + UInt16(0), // rangeShift ]); - assert_eq!(Face::parse(&data, 0).unwrap_err(), - FaceParsingError::MalformedFont); + assert_eq!( + Face::parse(&data, 0).unwrap_err(), + FaceParsingError::MalformedFont + ); } #[test] @@ -104,14 +109,16 @@ fn empty_font_collection() { use Unit::*; let data = convert(&[ Raw(&[0x74, 0x74, 0x63, 0x66]), // magic - UInt16(0), // majorVersion - UInt16(0), // minorVersion - UInt32(0), // numFonts + UInt16(0), // majorVersion + UInt16(0), // minorVersion + UInt32(0), // numFonts ]); assert_eq!(fonts_in_collection(&data), Some(0)); - assert_eq!(Face::parse(&data, 0).unwrap_err(), - FaceParsingError::FaceIndexOutOfBounds); + assert_eq!( + Face::parse(&data, 0).unwrap_err(), + FaceParsingError::FaceIndexOutOfBounds + ); } #[test] @@ -119,14 +126,16 @@ fn font_collection_num_fonts_overflow() { use Unit::*; let data = convert(&[ Raw(&[0x74, 0x74, 0x63, 0x66]), // magic - UInt16(0), // majorVersion - UInt16(0), // minorVersion - UInt32(std::u32::MAX), // numFonts + UInt16(0), // majorVersion + UInt16(0), // minorVersion + UInt32(std::u32::MAX), // numFonts ]); assert_eq!(fonts_in_collection(&data), Some(std::u32::MAX)); - assert_eq!(Face::parse(&data, 0).unwrap_err(), - FaceParsingError::MalformedFont); + assert_eq!( + Face::parse(&data, 0).unwrap_err(), + FaceParsingError::MalformedFont + ); } #[test] @@ -134,13 +143,15 @@ fn font_index_overflow() { use Unit::*; let data = convert(&[ Raw(&[0x74, 0x74, 0x63, 0x66]), // magic - UInt16(0), // majorVersion - UInt16(0), // minorVersion - UInt32(1), // numFonts - UInt32(12), // offset [0] + UInt16(0), // majorVersion + UInt16(0), // minorVersion + UInt32(1), // numFonts + UInt32(12), // offset [0] ]); assert_eq!(fonts_in_collection(&data), Some(1)); - assert_eq!(Face::parse(&data, std::u32::MAX).unwrap_err(), - FaceParsingError::FaceIndexOutOfBounds); + assert_eq!( + Face::parse(&data, std::u32::MAX).unwrap_err(), + FaceParsingError::FaceIndexOutOfBounds + ); }