summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Haug <mhaug@live.de>2021-11-20 12:36:03 +0100
committerMartin Haug <mhaug@live.de>2021-11-20 12:36:03 +0100
commitc020707ebc02be12290224d00679b6b323665c1f (patch)
treeb59206f46f78b258da795b7ed65c9b920e1320dc /src
parent63c274e7f6aa3a8c3f43abb91935ec924a186f73 (diff)
Add tracking to font function
Diffstat (limited to 'src')
-rw-r--r--src/geom/em.rs2
-rw-r--r--src/library/text.rs24
-rw-r--r--src/style/mod.rs3
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,