Add tracking to font function

This commit is contained in:
Martin Haug 2021-11-20 12:36:03 +01:00
parent 63c274e7f6
commit c020707ebc
5 changed files with 36 additions and 1 deletions

View File

@ -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);

View File

@ -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(

View File

@ -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,

BIN
tests/ref/text/tracking.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1,8 @@
// Test tracking characters apart or together.
---
#font(tracking: -0.01)
I saw Zoe yӛsterday, on the tram.
---
I'm in#font(tracking: 0.3)[ spaace]!