diff options
| author | Martin Haug <mhaug@live.de> | 2021-11-20 12:36:03 +0100 |
|---|---|---|
| committer | Martin Haug <mhaug@live.de> | 2021-11-20 12:36:03 +0100 |
| commit | c020707ebc02be12290224d00679b6b323665c1f (patch) | |
| tree | b59206f46f78b258da795b7ed65c9b920e1320dc /src | |
| parent | 63c274e7f6aa3a8c3f43abb91935ec924a186f73 (diff) | |
Add tracking to font function
Diffstat (limited to 'src')
| -rw-r--r-- | src/geom/em.rs | 2 | ||||
| -rw-r--r-- | src/library/text.rs | 24 | ||||
| -rw-r--r-- | src/style/mod.rs | 3 |
3 files changed, 28 insertions, 1 deletions
diff --git a/src/geom/em.rs b/src/geom/em.rs index 6d2f3aca..caddbcdd 100644 --- a/src/geom/em.rs +++ b/src/geom/em.rs @@ -3,7 +3,7 @@ use super::*; /// A length that is relative to the font size. /// /// `1em` is the same as the font size. -#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[derive(Serialize, Deserialize)] pub struct Em(N64); diff --git a/src/library/text.rs b/src/library/text.rs index 914122a1..f2c19516 100644 --- a/src/library/text.rs +++ b/src/library/text.rs @@ -163,6 +163,7 @@ pub fn font(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> { let fallback = args.named("fallback")?; let style = args.named("style")?; let weight = args.named("weight")?; + let tracking = args.named::<f64>("tracking")?; let stretch = args.named("stretch")?; let size = args.named::<Linear>("size")?.or_else(|| args.find()); let top_edge = args.named("top-edge")?; @@ -203,6 +204,10 @@ pub fn font(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> { text.fill = Paint::Color(fill); } + if let Some(tracking) = tracking { + text.tracking = Em::new(tracking); + } + set!(text.variant.style => style); set!(text.variant.weight => weight); set!(text.variant.stretch => stretch); @@ -259,6 +264,8 @@ pub fn shape<'a>( ); } + track_segment(&mut glyphs, style.tracking); + let (size, baseline) = measure(ctx, &glyphs, style); ShapedText { text, @@ -555,6 +562,23 @@ fn shape_segment<'a>( } } +/// Apply tracking to a slice of shaped glyphs. +fn track_segment(glyphs: &mut [ShapedGlyph], tracking: Em) { + if tracking.is_zero() { + return; + } + + let mut glyphs = glyphs.iter_mut().peekable(); + while let Some(glyph) = glyphs.next() { + if glyphs + .peek() + .map_or(false, |next| glyph.text_index != next.text_index) + { + glyph.x_advance += tracking; + } + } +} + /// Measure the size and baseline of a run of shaped glyphs with the given /// properties. fn measure( diff --git a/src/style/mod.rs b/src/style/mod.rs index 60734716..bb662032 100644 --- a/src/style/mod.rs +++ b/src/style/mod.rs @@ -140,6 +140,8 @@ pub struct TextStyle { pub families: Rc<FamilyStyle>, /// OpenType features. pub features: Rc<FontFeatures>, + /// The amount of space that should be added between character. + pub tracking: Em, /// Whether 300 extra font weight should be added to what is defined by the /// `variant`. pub strong: bool, @@ -222,6 +224,7 @@ impl Default for TextStyle { fill: Paint::Color(Color::Rgba(RgbaColor::BLACK)), families: Rc::new(FamilyStyle::default()), features: Rc::new(FontFeatures::default()), + tracking: Em::zero(), strong: false, emph: false, monospace: false, |
