Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial support for parsing the PANOSE number #172

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/font-info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ fn main() {
}
}

println!("{:?}", face.tables().os2.unwrap().panose());

println!("Elapsed: {}us", now.elapsed().as_micros());
}

Expand Down
45 changes: 40 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1408,16 +1408,38 @@ impl<'a> Face<'a> {
/// Checks that face is marked as *Italic*.
#[inline]
pub fn is_italic(&self) -> bool {
let panose_italic = self
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's make it less functional... We can move a panose getter into a private function, similar to Face::style().

.tables
.os2
.map(|os2| {
os2.panose()
.map(|panose| panose.is_italic())
.unwrap_or(false)
})
.unwrap_or(false);

// A face can have a Normal style and a non-zero italic angle, which also makes it italic.
self.style() == Style::Italic || self.italic_angle() != 0.0
self.style() == Style::Italic || self.italic_angle() != 0.0 || panose_italic
}

/// Checks that face is marked as *Bold*.
///
/// Returns `false` when OS/2 table is not present.
#[inline]
pub fn is_bold(&self) -> bool {
self.tables.os2.map(|os2| os2.is_bold()).unwrap_or(false)
let panose_bold = self
.tables
.os2
.map(|os2| {
os2.panose()
.map(|panose| panose.is_italic())
.unwrap_or(false)
})
.unwrap_or(false);

let sf_bold = self.tables.os2.map(|os2| os2.is_bold()).unwrap_or(false);

sf_bold || panose_bold
}

/// Checks that face is marked as *Oblique*.
Expand All @@ -1436,13 +1458,26 @@ impl<'a> Face<'a> {

/// Checks that face is marked as *Monospaced*.
///
/// Returns `false` when `post` table is not present.
/// Returns `false` when neither `post` nor `os2` tables are not present.
#[inline]
pub fn is_monospaced(&self) -> bool {
self.tables
let panose_monospaced = self
.tables
.os2
.map(|os2| {
os2.panose()
.map(|panose| panose.is_monospaced())
.unwrap_or(false)
})
.unwrap_or(false);

let post_monospaced = self
.tables
.post
.map(|post| post.is_monospaced)
.unwrap_or(false)
.unwrap_or(false);

post_monospaced || panose_monospaced
}

/// Checks that face is variable.
Expand Down
11 changes: 11 additions & 0 deletions src/tables/os2.rs → src/tables/os2/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
//! A [OS/2 and Windows Metrics Table](https://docs.microsoft.com/en-us/typography/opentype/spec/os2)
//! implementation.

pub mod panose;

use panose::Panose;

use crate::parser::Stream;
use crate::LineMetrics;

Expand All @@ -11,6 +15,7 @@ const Y_SUBSCRIPT_X_SIZE_OFFSET: usize = 10;
const Y_SUPERSCRIPT_X_SIZE_OFFSET: usize = 18;
const Y_STRIKEOUT_SIZE_OFFSET: usize = 26;
const Y_STRIKEOUT_POSITION_OFFSET: usize = 28;
const PANOSE_OFFSET: usize = 32;
const UNICODE_RANGES_OFFSET: usize = 42;
const SELECTION_OFFSET: usize = 62;
const TYPO_ASCENDER_OFFSET: usize = 68;
Expand Down Expand Up @@ -522,6 +527,12 @@ impl<'a> Table<'a> {
UnicodeRanges(n4 << 96 | n3 << 64 | n2 << 32 | n1)
}

/// Returns the [PANOSE classification](https://monotype.github.io/panose/pan1.htm) information.
pub fn panose(&self) -> Option<Panose> {
let mut s = Stream::new_at(self.data, PANOSE_OFFSET).unwrap();
s.read::<Panose>()
}

#[inline]
fn fs_selection(&self) -> u16 {
Stream::read_at::<u16>(self.data, SELECTION_OFFSET).unwrap_or(0)
Expand Down
Loading
Loading