summaryrefslogtreecommitdiff
path: root/src/font.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-09-19 11:31:37 +0200
committerLaurenz <laurmaedje@gmail.com>2022-09-19 11:36:59 +0200
commit30be75c6687f1e03cf867d258b3ddba353cc7aa2 (patch)
tree51afd42ae8875811ae51974e66681a17990de7f2 /src/font.rs
parent4ec3bcee487c1567bc6551f81d4f69eee4379076 (diff)
Renaming
`Face` -> `Font` `FaceId` -> `FontId` `SourceFile` -> `Source`
Diffstat (limited to 'src/font.rs')
-rw-r--r--src/font.rs176
1 files changed, 88 insertions, 88 deletions
diff --git a/src/font.rs b/src/font.rs
index fd979943..8f440c52 100644
--- a/src/font.rs
+++ b/src/font.rs
@@ -15,12 +15,12 @@ use unicode_segmentation::UnicodeSegmentation;
use crate::geom::Em;
use crate::loading::{FileHash, Loader};
-/// A unique identifier for a loaded font face.
+/// A unique identifier for a loaded font.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub struct FaceId(u32);
+pub struct FontId(u32);
-impl FaceId {
- /// Create a face id from the raw underlying value.
+impl FontId {
+ /// Create a font id from the raw underlying value.
///
/// This should only be called with values returned by
/// [`into_raw`](Self::into_raw).
@@ -34,38 +34,38 @@ impl FaceId {
}
}
-/// Storage for loaded and parsed font faces.
+/// Storage for loaded and parsed fonts.
pub struct FontStore {
loader: Arc<dyn Loader>,
failed: Vec<bool>,
- faces: Vec<Option<Face>>,
- families: BTreeMap<String, Vec<FaceId>>,
+ fonts: Vec<Option<Font>>,
+ families: BTreeMap<String, Vec<FontId>>,
buffers: HashMap<FileHash, Arc<Vec<u8>>>,
}
impl FontStore {
/// Create a new, empty font store.
pub fn new(loader: Arc<dyn Loader>) -> Self {
- let mut faces = vec![];
+ let mut fonts = vec![];
let mut failed = vec![];
- let mut families = BTreeMap::<String, Vec<FaceId>>::new();
+ let mut families = BTreeMap::<String, Vec<FontId>>::new();
- let infos = loader.faces();
+ let infos = loader.fonts();
for (i, info) in infos.iter().enumerate() {
- let id = FaceId(i as u32);
- faces.push(None);
+ let id = FontId(i as u32);
+ fonts.push(None);
failed.push(false);
families.entry(info.family.to_lowercase()).or_default().push(id);
}
- for faces in families.values_mut() {
- faces.sort_by_key(|id| infos[id.0 as usize].variant);
- faces.dedup_by_key(|id| infos[id.0 as usize].variant);
+ for fonts in families.values_mut() {
+ fonts.sort_by_key(|id| infos[id.0 as usize].variant);
+ fonts.dedup_by_key(|id| infos[id.0 as usize].variant);
}
Self {
loader,
- faces,
+ fonts,
failed,
families,
buffers: HashMap::new(),
@@ -73,73 +73,73 @@ impl FontStore {
}
/// An ordered iterator over all font families this loader knows and details
- /// about the faces that are part of them.
+ /// about the fonts that are part of them.
pub fn families(
&self,
- ) -> impl Iterator<Item = (&str, impl Iterator<Item = &FaceInfo>)> + '_ {
+ ) -> impl Iterator<Item = (&str, impl Iterator<Item = &FontInfo>)> + '_ {
// Since the keys are lowercased, we instead use the family field of the
- // first face's info.
- let faces = self.loader.faces();
+ // first font's info.
+ let fonts = self.loader.fonts();
self.families.values().map(|ids| {
- let family = faces[ids[0].0 as usize].family.as_str();
- let infos = ids.iter().map(|&id| &faces[id.0 as usize]);
+ let family = fonts[ids[0].0 as usize].family.as_str();
+ let infos = ids.iter().map(|&id| &fonts[id.0 as usize]);
(family, infos)
})
}
- /// Get a reference to a loaded face.
+ /// Get a reference to a loaded font.
///
- /// This panics if the face with this `id` was not loaded. This function
+ /// This panics if the font with this `id` was not loaded. This function
/// should only be called with ids returned by this store's
/// [`select()`](Self::select) and
/// [`select_fallback()`](Self::select_fallback) methods.
#[track_caller]
- pub fn get(&self, id: FaceId) -> &Face {
- self.faces[id.0 as usize].as_ref().expect("font face was not loaded")
+ pub fn get(&self, id: FontId) -> &Font {
+ self.fonts[id.0 as usize].as_ref().expect("font was not loaded")
}
- /// Try to find and load a font face from the given `family` that matches
+ /// Try to find and load a font from the given `family` that matches
/// the given `variant` as closely as possible.
- pub fn select(&mut self, family: &str, variant: FontVariant) -> Option<FaceId> {
+ pub fn select(&mut self, family: &str, variant: FontVariant) -> Option<FontId> {
let ids = self.families.get(family)?;
let id = self.find_best_variant(None, variant, ids.iter().copied())?;
self.load(id)
}
/// Try to find and load a fallback font that
- /// - is as close as possible to the face `like` (if any)
+ /// - is as close as possible to the font `like` (if any)
/// - is as close as possible to the given `variant`
/// - is suitable for shaping the given `text`
pub fn select_fallback(
&mut self,
- like: Option<FaceId>,
+ like: Option<FontId>,
variant: FontVariant,
text: &str,
- ) -> Option<FaceId> {
- // Find the faces that contain the text's first char ...
+ ) -> Option<FontId> {
+ // Find the fonts that contain the text's first char ...
let c = text.chars().next()?;
let ids = self
.loader
- .faces()
+ .fonts()
.iter()
.enumerate()
.filter(|(_, info)| info.coverage.contains(c as u32))
- .map(|(i, _)| FaceId(i as u32));
+ .map(|(i, _)| FontId(i as u32));
// ... and find the best variant among them.
let id = self.find_best_variant(like, variant, ids)?;
self.load(id)
}
- /// Find the face in the passed iterator that
- /// - is closest to the face `like` (if any)
+ /// Find the font in the passed iterator that
+ /// - is closest to the font `like` (if any)
/// - is closest to the given `variant`
///
/// To do that we compute a key for all variants and select the one with the
/// minimal key. This key prioritizes:
- /// - If `like` is some other face:
- /// - Are both faces (not) monospaced?
- /// - Do both faces (not) have serifs?
+ /// - If `like` is some other font:
+ /// - Are both fonts (not) monospaced?
+ /// - Do both fonts (not) have serifs?
/// - How many words do the families share in their prefix? E.g. "Noto
/// Sans" and "Noto Sans Arabic" share two words, whereas "IBM Plex
/// Arabic" shares none with "Noto Sans", so prefer "Noto Sans Arabic"
@@ -154,11 +154,11 @@ impl FontStore {
/// - The absolute distance to the target weight.
fn find_best_variant(
&self,
- like: Option<FaceId>,
+ like: Option<FontId>,
variant: FontVariant,
- ids: impl IntoIterator<Item = FaceId>,
- ) -> Option<FaceId> {
- let infos = self.loader.faces();
+ ids: impl IntoIterator<Item = FontId>,
+ ) -> Option<FontId> {
+ let infos = self.loader.fonts();
let like = like.map(|id| &infos[id.0 as usize]);
let mut best = None;
@@ -190,12 +190,12 @@ impl FontStore {
best
}
- /// Load the face with the given id.
+ /// Load the font with the given id.
///
- /// Returns `Some(id)` if the face was loaded successfully.
- fn load(&mut self, id: FaceId) -> Option<FaceId> {
+ /// Returns `Some(id)` if the font was loaded successfully.
+ fn load(&mut self, id: FontId) -> Option<FontId> {
let idx = id.0 as usize;
- let slot = &mut self.faces[idx];
+ let slot = &mut self.fonts[idx];
if slot.is_some() {
return Some(id);
}
@@ -204,11 +204,11 @@ impl FontStore {
return None;
}
- let FaceInfo { ref path, index, .. } = self.loader.faces()[idx];
+ let FontInfo { ref path, index, .. } = self.loader.fonts()[idx];
self.failed[idx] = true;
- // Check the buffer cache since multiple faces may
- // refer to the same data (font collection).
+ // Check the buffer cache since multiple fonts may refer to the same
+ // data (font collection).
let hash = self.loader.resolve(path).ok()?;
let buffer = match self.buffers.entry(hash) {
Entry::Occupied(entry) => entry.into_mut(),
@@ -218,8 +218,8 @@ impl FontStore {
}
};
- let face = Face::new(Arc::clone(buffer), index)?;
- *slot = Some(face);
+ let font = Font::new(Arc::clone(buffer), index)?;
+ *slot = Some(font);
self.failed[idx] = false;
Some(id)
@@ -234,24 +234,24 @@ fn shared_prefix_words(left: &str, right: &str) -> usize {
.count()
}
-/// A font face.
-pub struct Face {
- /// The raw face data, possibly shared with other faces from the same
+/// An OpenType font.
+pub struct Font {
+ /// The raw font data, possibly shared with other fonts from the same
/// collection. The vector's allocation must not move, because `ttf` points
/// into it using unsafe code.
buffer: Arc<Vec<u8>>,
- /// The face's index in the collection (zero if not a collection).
+ /// The font's index in the collection (zero if not a collection).
index: u32,
/// The underlying ttf-parser/rustybuzz face.
ttf: rustybuzz::Face<'static>,
- /// The face's metrics.
- metrics: FaceMetrics,
+ /// The font's metrics.
+ metrics: FontMetrics,
/// The parsed ReX math header.
math: OnceCell<Option<MathHeader>>,
}
-impl Face {
- /// Parse a font face from a buffer and collection index.
+impl Font {
+ /// Parse a font from a buffer and collection index.
pub fn new(buffer: Arc<Vec<u8>>, index: u32) -> Option<Self> {
// Safety:
// - The slices's location is stable in memory:
@@ -263,7 +263,7 @@ impl Face {
unsafe { std::slice::from_raw_parts(buffer.as_ptr(), buffer.len()) };
let ttf = rustybuzz::Face::from_slice(slice, index)?;
- let metrics = FaceMetrics::from_ttf(&ttf);
+ let metrics = FontMetrics::from_ttf(&ttf);
Some(Self {
buffer,
@@ -296,8 +296,8 @@ impl Face {
self.metrics.units_per_em
}
- /// Access the face's metrics.
- pub fn metrics(&self) -> &FaceMetrics {
+ /// Access the font's metrics.
+ pub fn metrics(&self) -> &FontMetrics {
&self.metrics
}
@@ -329,9 +329,9 @@ impl Face {
}
}
-/// Metrics for a font face.
+/// Metrics for a font.
#[derive(Debug, Copy, Clone)]
-pub struct FaceMetrics {
+pub struct FontMetrics {
/// How many font units represent one em unit.
pub units_per_em: f64,
/// The distance from the baseline to the typographic ascender.
@@ -350,8 +350,8 @@ pub struct FaceMetrics {
pub overline: LineMetrics,
}
-impl FaceMetrics {
- /// Extract the face's metrics.
+impl FontMetrics {
+ /// Extract the font's metrics.
pub fn from_ttf(ttf: &ttf_parser::Face) -> Self {
let units_per_em = f64::from(ttf.units_per_em());
let to_em = |units| Em::from_units(units, units_per_em);
@@ -437,36 +437,36 @@ pub enum VerticalFontMetric {
Descender,
}
-/// Properties of a single font face.
+/// Properties of a single font.
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
-pub struct FaceInfo {
+pub struct FontInfo {
/// The path to the font file.
pub path: PathBuf,
/// The collection index in the font file.
pub index: u32,
- /// The typographic font family this face is part of.
+ /// The typographic font family this font is part of.
pub family: String,
- /// Properties that distinguish this face from other faces in the same
+ /// Properties that distinguish this font from other fonts in the same
/// family.
pub variant: FontVariant,
- /// Whether the face is monospaced.
+ /// Whether the font is monospaced.
pub monospaced: bool,
- /// Whether the face has serifs (if known).
+ /// Whether the font has serifs (if known).
pub serif: Option<bool>,
- /// The unicode coverage of the face.
+ /// The unicode coverage of the font.
pub coverage: Coverage,
}
-impl FaceInfo {
- /// Compute metadata for all faces in the given data.
+impl FontInfo {
+ /// Compute metadata for all fonts in the given data.
pub fn from_data<'a>(
path: &'a Path,
data: &'a [u8],
- ) -> impl Iterator<Item = FaceInfo> + 'a {
+ ) -> impl Iterator<Item = FontInfo> + 'a {
let count = ttf_parser::fonts_in_collection(data).unwrap_or(1);
(0 .. count).filter_map(move |index| {
- let face = ttf_parser::Face::from_slice(data, index).ok()?;
- Self::from_ttf(path, index, &face)
+ let ttf = ttf_parser::Face::from_slice(data, index).ok()?;
+ Self::from_ttf(path, index, &ttf)
})
}
@@ -477,7 +477,7 @@ impl FaceInfo {
// variants (e.g. Display variants of Noto fonts) and then some
// variants become inaccessible from Typst. And even though the
// fsSelection bit WWS should help us decide whether that is the
- // case, it's wrong for some fonts (e.g. for some faces of "Noto
+ // case, it's wrong for some fonts (e.g. for certain variants of "Noto
// Sans Display").
//
// So, instead we use Name ID 1 "Family" and trim many common
@@ -539,7 +539,7 @@ impl FaceInfo {
}
}
- Some(FaceInfo {
+ Some(FontInfo {
path: path.to_owned(),
index,
family,
@@ -648,15 +648,15 @@ fn trim_styles(mut family: &str) -> &str {
&family[.. len]
}
-/// Properties that distinguish a face from other faces in the same family.
+/// Properties that distinguish a font from other fonts in the same family.
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[derive(Serialize, Deserialize)]
pub struct FontVariant {
- /// The style of the face (normal / italic / oblique).
+ /// The style of the font (normal / italic / oblique).
pub style: FontStyle,
- /// How heavy the face is (100 - 900).
+ /// How heavy the font is (100 - 900).
pub weight: FontWeight,
- /// How condensed or expanded the face is (0.5 - 2.0).
+ /// How condensed or expanded the font is (0.5 - 2.0).
pub stretch: FontStretch,
}
@@ -673,7 +673,7 @@ impl Debug for FontVariant {
}
}
-/// The style of a font face.
+/// The style of a font.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
@@ -705,7 +705,7 @@ impl Default for FontStyle {
}
}
-/// The weight of a font face.
+/// The weight of a font.
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[derive(Serialize, Deserialize)]
#[serde(transparent)]
@@ -773,7 +773,7 @@ impl Debug for FontWeight {
}
}
-/// The width of a font face.
+/// The width of a font.
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[derive(Serialize, Deserialize)]
#[serde(transparent)]