summaryrefslogtreecommitdiff
path: root/src/exec/state.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-03-24 17:12:34 +0100
committerLaurenz <laurmaedje@gmail.com>2021-03-24 17:12:34 +0100
commit73615f7e3ce23f2ea656d04ea9f96184f5ebdc0a (patch)
tree7691b792e1e4b33469a72c40fc76854f1de0814e /src/exec/state.rs
parent6720520ec06dd0718f81049b2b11e81664f7ef62 (diff)
Text shaping 🚀
- Shapes text with rustybuzz - Font fallback with family list - Tofus are shown in the first font Co-Authored-By: Martin <mhaug@live.de>
Diffstat (limited to 'src/exec/state.rs')
-rw-r--r--src/exec/state.rs76
1 files changed, 60 insertions, 16 deletions
diff --git a/src/exec/state.rs b/src/exec/state.rs
index 0322c437..7957f312 100644
--- a/src/exec/state.rs
+++ b/src/exec/state.rs
@@ -4,8 +4,9 @@ use std::rc::Rc;
use fontdock::{FontStretch, FontStyle, FontVariant, FontWeight};
use crate::color::{Color, RgbaColor};
+use crate::font::VerticalFontMetric;
use crate::geom::*;
-use crate::layout::{Fill, VerticalFontMetric};
+use crate::layout::Fill;
use crate::paper::{Paper, PaperClass, PAPER_A4};
/// The evaluation state.
@@ -100,7 +101,7 @@ impl Default for ParState {
#[derive(Debug, Clone, PartialEq)]
pub struct FontState {
/// A list of font families with generic class definitions.
- pub families: Rc<FamilyMap>,
+ pub families: Rc<FamilyList>,
/// The selected font variant.
pub variant: FontVariant,
/// The font size.
@@ -111,32 +112,58 @@ pub struct FontState {
pub top_edge: VerticalFontMetric,
/// The bottom end of the text bounding box.
pub bottom_edge: VerticalFontMetric,
+ /// The glyph fill color / texture.
+ pub color: Fill,
/// Whether the strong toggle is active or inactive. This determines
/// whether the next `*` adds or removes font weight.
pub strong: bool,
/// Whether the emphasis toggle is active or inactive. This determines
/// whether the next `_` makes italic or non-italic.
pub emph: bool,
- /// The glyph fill color / texture.
- pub color: Fill,
}
impl FontState {
- /// Access the `families` mutably.
- pub fn families_mut(&mut self) -> &mut FamilyMap {
- Rc::make_mut(&mut self.families)
+ /// The resolved font size.
+ pub fn resolve_size(&self) -> Length {
+ self.scale.resolve(self.size)
}
- /// The absolute font size.
- pub fn font_size(&self) -> Length {
- self.scale.resolve(self.size)
+ /// Resolve font properties.
+ pub fn resolve_props(&self) -> FontProps {
+ let mut variant = self.variant;
+
+ if self.strong {
+ variant.weight = variant.weight.thicken(300);
+ }
+
+ if self.emph {
+ variant.style = match variant.style {
+ FontStyle::Normal => FontStyle::Italic,
+ FontStyle::Italic => FontStyle::Normal,
+ FontStyle::Oblique => FontStyle::Normal,
+ }
+ }
+
+ FontProps {
+ families: Rc::clone(&self.families),
+ variant,
+ size: self.resolve_size(),
+ top_edge: self.top_edge,
+ bottom_edge: self.bottom_edge,
+ color: self.color,
+ }
+ }
+
+ /// Access the `families` mutably.
+ pub fn families_mut(&mut self) -> &mut FamilyList {
+ Rc::make_mut(&mut self.families)
}
}
impl Default for FontState {
fn default() -> Self {
Self {
- families: Rc::new(FamilyMap::default()),
+ families: Rc::new(FamilyList::default()),
variant: FontVariant {
style: FontStyle::Normal,
weight: FontWeight::REGULAR,
@@ -146,16 +173,33 @@ impl Default for FontState {
top_edge: VerticalFontMetric::CapHeight,
bottom_edge: VerticalFontMetric::Baseline,
scale: Linear::ONE,
+ color: Fill::Color(Color::Rgba(RgbaColor::BLACK)),
strong: false,
emph: false,
- color: Fill::Color(Color::Rgba(RgbaColor::BLACK)),
}
}
}
+/// Properties used for font selection and layout.
+#[derive(Debug, Clone, PartialEq)]
+pub struct FontProps {
+ /// The list of font families to use for shaping.
+ pub families: Rc<FamilyList>,
+ /// Which variant of the font to use.
+ pub variant: FontVariant,
+ /// The font size.
+ pub size: Length,
+ /// What line to consider the top edge of text.
+ pub top_edge: VerticalFontMetric,
+ /// What line to consider the bottom edge of text.
+ pub bottom_edge: VerticalFontMetric,
+ /// The color of the text.
+ pub color: Fill,
+}
+
/// Font family definitions.
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
-pub struct FamilyMap {
+pub struct FamilyList {
/// The user-defined list of font families.
pub list: Vec<FontFamily>,
/// Definition of serif font families.
@@ -168,9 +212,9 @@ pub struct FamilyMap {
pub base: Vec<String>,
}
-impl FamilyMap {
+impl FamilyList {
/// Flat iterator over this map's family names.
- pub fn iter(&self) -> impl Iterator<Item = &str> {
+ pub fn iter(&self) -> impl Iterator<Item = &str> + Clone {
self.list
.iter()
.flat_map(move |family: &FontFamily| {
@@ -186,7 +230,7 @@ impl FamilyMap {
}
}
-impl Default for FamilyMap {
+impl Default for FamilyList {
fn default() -> Self {
Self {
list: vec![FontFamily::Serif],