diff options
Diffstat (limited to 'src/layout')
| -rw-r--r-- | src/layout/actions.rs | 16 | ||||
| -rw-r--r-- | src/layout/mod.rs | 10 | ||||
| -rw-r--r-- | src/layout/model.rs | 11 | ||||
| -rw-r--r-- | src/layout/text.rs | 52 |
4 files changed, 43 insertions, 46 deletions
diff --git a/src/layout/actions.rs b/src/layout/actions.rs index 317cff25..7806932e 100644 --- a/src/layout/actions.rs +++ b/src/layout/actions.rs @@ -2,7 +2,7 @@ use std::fmt::{self, Debug, Formatter}; use serde::ser::{Serialize, Serializer, SerializeTuple}; -use toddle::query::FontIndex; +use fontdock::FaceId; use crate::length::{Length, Size}; use super::Layout; @@ -15,7 +15,7 @@ pub enum LayoutAction { /// Move to an absolute position. MoveAbsolute(Size), /// Set the font given the index from the font loader and font size. - SetFont(FontIndex, Length), + SetFont(FaceId, Length), /// Write text at the current position. WriteText(String), /// Visualize a box for debugging purposes. @@ -31,10 +31,10 @@ impl Serialize for LayoutAction { tup.serialize_element(&pos)?; tup.end() } - LayoutAction::SetFont(index, size) => { + LayoutAction::SetFont(id, size) => { let mut tup = serializer.serialize_tuple(4)?; tup.serialize_element(&1u8)?; - tup.serialize_element(index)?; + tup.serialize_element(id)?; tup.serialize_element(size)?; tup.end() } @@ -59,7 +59,7 @@ impl Debug for LayoutAction { use LayoutAction::*; match self { MoveAbsolute(s) => write!(f, "move {} {}", s.x, s.y), - SetFont(i, s) => write!(f, "font {}-{} {}", i.id, i.variant, s), + SetFont(id, s) => write!(f, "font {}-{} {}", id.index, id.variant, s), WriteText(s) => write!(f, "write {:?}", s), DebugBox(s) => write!(f, "box {} {}", s.x, s.y), } @@ -82,9 +82,9 @@ impl Debug for LayoutAction { pub struct LayoutActions { origin: Size, actions: Vec<LayoutAction>, - active_font: (FontIndex, Length), + active_font: (FaceId, Length), next_pos: Option<Size>, - next_font: Option<(FontIndex, Length)>, + next_font: Option<(FaceId, Length)>, } impl LayoutActions { @@ -93,7 +93,7 @@ impl LayoutActions { LayoutActions { actions: vec![], origin: Size::ZERO, - active_font: (FontIndex::MAX, Length::ZERO), + active_font: (FaceId::MAX, Length::ZERO), next_pos: None, next_font: None, } diff --git a/src/layout/mod.rs b/src/layout/mod.rs index 4863d554..8bcceda6 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -3,7 +3,7 @@ use std::fmt::{self, Display, Formatter}; use smallvec::SmallVec; use serde::Serialize; -use toddle::query::FontIndex; +use fontdock::FaceId; use crate::length::{Length, Size, Margins}; use self::prelude::*; @@ -44,12 +44,12 @@ pub struct Layout { impl Layout { /// Returns a vector with all used font indices. - pub fn find_used_fonts(&self) -> Vec<FontIndex> { + pub fn find_used_fonts(&self) -> Vec<FaceId> { let mut fonts = Vec::new(); for action in &self.actions { - if let LayoutAction::SetFont(index, _) = action { - if !fonts.contains(index) { - fonts.push(*index); + if let &LayoutAction::SetFont(id, _) = action { + if !fonts.contains(&id) { + fonts.push(id); } } } diff --git a/src/layout/model.rs b/src/layout/model.rs index a15598d2..3fb594d5 100644 --- a/src/layout/model.rs +++ b/src/layout/model.rs @@ -5,10 +5,9 @@ use std::future::Future; use std::pin::Pin; use smallvec::smallvec; -use toddle::query::FontStyle; use crate::{Pass, Feedback}; -use crate::GlobalFontLoader; +use crate::SharedFontLoader; use crate::style::{LayoutStyle, PageStyle, TextStyle}; use crate::length::{Length, Size}; use crate::syntax::{Model, SyntaxModel, Node, Decoration}; @@ -31,7 +30,7 @@ pub struct ModelLayouter<'a> { pub struct LayoutContext<'a> { /// The font loader to retrieve fonts from when typesetting text /// using [`layout_text`]. - pub loader: &'a GlobalFontLoader, + pub loader: &'a SharedFontLoader, /// The style for pages and text. pub style: &'a LayoutStyle, /// The base unpadded dimensions of this container (for relative sizing). @@ -167,7 +166,7 @@ impl<'a> ModelLayouter<'a> { Linebreak => self.layouter.finish_line(), Text(text) => { - if self.style.text.variant.style == FontStyle::Italic { + if self.style.text.italic { decorate(self, Decoration::Italic); } @@ -179,7 +178,7 @@ impl<'a> ModelLayouter<'a> { } ToggleItalic => { - self.style.text.variant.style.toggle(); + self.style.text.italic = !self.style.text.italic; decorate(self, Decoration::Italic); } @@ -191,7 +190,7 @@ impl<'a> ModelLayouter<'a> { Raw(lines) => { // TODO: Make this more efficient. let fallback = self.style.text.fallback.clone(); - self.style.text.fallback.list.insert(0, "monospace".to_string()); + self.style.text.fallback.list_mut().insert(0, "monospace".to_string()); self.style.text.fallback.flatten(); // Layout the first line. diff --git a/src/layout/text.rs b/src/layout/text.rs index cbe40214..22616667 100644 --- a/src/layout/text.rs +++ b/src/layout/text.rs @@ -4,10 +4,8 @@ //! When the primary layouting axis horizontally inversed, the word is spelled //! backwards. Vertical word layout is not yet supported. -use toddle::query::{FontQuery, FontIndex}; -use toddle::tables::{CharMap, Header, HorizontalMetrics}; - -use crate::GlobalFontLoader; +use fontdock::{FaceId, FaceQuery, FontStyle}; +use crate::font::SharedFontLoader; use crate::length::{Length, Size}; use crate::style::TextStyle; use super::*; @@ -19,7 +17,7 @@ struct TextLayouter<'a> { text: &'a str, actions: LayoutActions, buffer: String, - active_font: FontIndex, + active_font: FaceId, width: Length, } @@ -28,7 +26,7 @@ struct TextLayouter<'a> { pub struct TextContext<'a> { /// The font loader to retrieve fonts from when typesetting text /// using [`layout_text`]. - pub loader: &'a GlobalFontLoader, + pub loader: &'a SharedFontLoader, /// The style for text: Font selection with classes, weights and variants, /// font sizes, spacing and so on. pub style: &'a TextStyle, @@ -52,7 +50,7 @@ impl<'a> TextLayouter<'a> { text, actions: LayoutActions::new(), buffer: String::new(), - active_font: FontIndex::MAX, + active_font: FaceId::MAX, width: Length::ZERO, } } @@ -109,41 +107,41 @@ impl<'a> TextLayouter<'a> { /// Select the best font for a character and return its index along with /// the width of the char in the font. - async fn select_font(&mut self, c: char) -> Option<(FontIndex, Length)> { + async fn select_font(&mut self, c: char) -> Option<(FaceId, Length)> { let mut loader = self.ctx.loader.borrow_mut(); let mut variant = self.ctx.style.variant; + if self.ctx.style.bolder { variant.weight.0 += 300; } - let query = FontQuery { + if self.ctx.style.italic { + variant.style = match variant.style { + FontStyle::Normal => FontStyle::Italic, + FontStyle::Italic => FontStyle::Normal, + FontStyle::Oblique => FontStyle::Normal, + } + } + + let query = FaceQuery { fallback: self.ctx.style.fallback.iter(), variant, c, }; - if let Some((font, index)) = loader.get(query).await { + if let Some((id, face)) = loader.query(query).await { // Determine the width of the char. - let header = font.read_table::<Header>().ok()?; - let font_unit_ratio = 1.0 / (header.units_per_em as f64); - let font_unit_to_size = |x| Length::pt(font_unit_ratio * x); - - let glyph = font - .read_table::<CharMap>() - .ok()? - .get(c)?; - - let glyph_width = font - .read_table::<HorizontalMetrics>() - .ok()? - .get(glyph)? - .advance_width as f64; - - let char_width = font_unit_to_size(glyph_width) + let units_per_em = face.units_per_em().unwrap_or(1000); + let ratio = 1.0 / (units_per_em as f64); + let to_length = |x| Length::pt(ratio * x as f64); + + let glyph = face.glyph_index(c)?; + let glyph_width = face.glyph_hor_advance(glyph)?; + let char_width = to_length(glyph_width) * self.ctx.style.font_size().to_pt(); - Some((index, char_width)) + Some((id, char_width)) } else { None } |
