diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-03-19 13:20:58 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-03-19 13:20:58 +0100 |
| commit | 54a9ccb1a5e9f1f1e5d2538d2f4ce3d4f7afc4ae (patch) | |
| tree | 3a0f45af5d1cd6d65420887f8412a5594b6300bd /src/library | |
| parent | bd12d135cab32d61b32945433e77579d04298d52 (diff) | |
Configurable font edges ⚙
Adds top-edge and bottom-edge parameters to the font function. These define how
the box around a word is computed. The possible values are:
- ascender
- cap-height (default top edge)
- x-height
- baseline (default bottom edge)
- descender
The defaults are chosen so that it's easy to create good-looking designs with
vertical alignment. Since they are much tighter than what most other software
uses by default, the default leading had to be increased to 50% of the font size
and paragraph spacing to 100% of the font size.
The values cap-height and x-height fall back to ascender in case they are zero
because this value may occur in fonts that don't have glyphs with cap- or
x-height (like Twitter Color Emoji). Since cap-height is the default top edge,
doing no fallback would break things badly.
Removes softness in favor of a simple boolean for pages and a more finegread u8
for spacing. This is needed to make paragraph spacing consume line spacing
created by hard line breaks.
Diffstat (limited to 'src/library')
| -rw-r--r-- | src/library/font.rs | 31 | ||||
| -rw-r--r-- | src/library/mod.rs | 7 | ||||
| -rw-r--r-- | src/library/page.rs | 6 | ||||
| -rw-r--r-- | src/library/spacing.rs | 2 |
4 files changed, 37 insertions, 9 deletions
diff --git a/src/library/font.rs b/src/library/font.rs index 460cfba1..ecc15d96 100644 --- a/src/library/font.rs +++ b/src/library/font.rs @@ -1,6 +1,7 @@ use fontdock::{FontStretch, FontStyle, FontWeight}; use super::*; +use crate::shaping::VerticalFontMetric; /// `font`: Configure the font. /// @@ -13,6 +14,8 @@ use super::*; /// - Font Style: `style`, of type `font-style`. /// - Font Weight: `weight`, of type `font-weight`. /// - Font Stretch: `stretch`, of type `relative`, between 0.5 and 2.0. +/// - Top edge of the font: `top-edge`, of type `vertical-font-metric`. +/// - Bottom edge of the font: `bottom-edge`, of type `vertical-font-metric`. /// - Serif family definition: `serif`, of type `font-familiy-list`. /// - Sans-serif family definition: `sans-serif`, of type `font-familiy-list`. /// - Monospace family definition: `monospace`, of type `font-familiy-list`. @@ -22,15 +25,15 @@ use super::*; /// if present. /// /// # Relevant types and constants -/// - Type `font-family-list` -/// - coerces from `string` -/// - coerces from `array` -/// - coerces from `font-family` /// - Type `font-family` /// - `serif` /// - `sans-serif` /// - `monospace` /// - coerces from `string` +/// - Type `font-family-list` +/// - coerces from `string` +/// - coerces from `array` +/// - coerces from `font-family` /// - Type `font-style` /// - `normal` /// - `italic` @@ -46,12 +49,20 @@ use super::*; /// - `extrabold` (800) /// - `black` (900) /// - coerces from `integer` +/// - Type `vertical-font-metric` +/// - `ascender` +/// - `cap-height` +/// - `x-height` +/// - `baseline` +/// - `descender` pub fn font(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value { let size = args.find::<Linear>(ctx); let list: Vec<_> = args.filter::<FontFamily>(ctx).map(|f| f.to_string()).collect(); let style = args.get(ctx, "style"); let weight = args.get(ctx, "weight"); let stretch = args.get(ctx, "stretch"); + let top_edge = args.get(ctx, "top-edge"); + let bottom_edge = args.get(ctx, "bottom-edge"); let serif = args.get(ctx, "serif"); let sans_serif = args.get(ctx, "sans-serif"); let monospace = args.get(ctx, "monospace"); @@ -87,6 +98,14 @@ pub fn font(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value { ctx.state.font.variant.stretch = stretch; } + if let Some(top_edge) = top_edge { + ctx.state.font.top_edge = top_edge; + } + + if let Some(bottom_edge) = bottom_edge { + ctx.state.font.bottom_edge = bottom_edge; + } + for (variant, arg) in &[ (FontFamily::Serif, &serif), (FontFamily::SansSerif, &sans_serif), @@ -185,3 +204,7 @@ typify! { }; }, } + +typify! { + VerticalFontMetric: "vertical font metric", +} diff --git a/src/library/mod.rs b/src/library/mod.rs index 09fda20f..453eab26 100644 --- a/src/library/mod.rs +++ b/src/library/mod.rs @@ -26,9 +26,9 @@ use std::fmt::{self, Display, Formatter}; use fontdock::{FontStyle, FontWeight}; use crate::eval::{Scope, ValueAny, ValueFunc}; -use crate::exec::Softness; use crate::layout::*; use crate::prelude::*; +use crate::shaping::VerticalFontMetric; /// Construct a scope containing all standard library definitions. pub fn new() -> Scope { @@ -81,6 +81,11 @@ pub fn new() -> Scope { set!(any: "bold", FontWeight::BOLD); set!(any: "extrabold", FontWeight::EXTRABOLD); set!(any: "black", FontWeight::BLACK); + set!(any: "ascender", VerticalFontMetric::Ascender); + set!(any: "cap-height", VerticalFontMetric::CapHeight); + set!(any: "x-height", VerticalFontMetric::XHeight); + set!(any: "baseline", VerticalFontMetric::Baseline); + set!(any: "descender", VerticalFontMetric::Descender); std } diff --git a/src/library/page.rs b/src/library/page.rs index 17021607..f7d76eaf 100644 --- a/src/library/page.rs +++ b/src/library/page.rs @@ -95,13 +95,13 @@ pub fn page(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value { } ctx.set_dirs(Gen::new(main, cross)); - ctx.finish_page(false, Softness::Hard, span); + ctx.finish_page(false, true, span); if let Some(body) = &body { // TODO: Restrict body to a single page? body.exec(ctx); ctx.state = snapshot; - ctx.finish_page(true, Softness::Soft, span); + ctx.finish_page(true, false, span); } }) } @@ -113,6 +113,6 @@ pub fn page(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value { pub fn pagebreak(_: &mut EvalContext, args: &mut ValueArgs) -> Value { let span = args.span; Value::template("pagebreak", move |ctx| { - ctx.finish_page(true, Softness::Hard, span); + ctx.finish_page(true, true, span); }) } diff --git a/src/library/spacing.rs b/src/library/spacing.rs index d8f18f41..4965a220 100644 --- a/src/library/spacing.rs +++ b/src/library/spacing.rs @@ -28,7 +28,7 @@ fn spacing(ctx: &mut EvalContext, args: &mut ValueArgs, axis: SpecAxis) -> Value Value::template("spacing", move |ctx| { if let Some(linear) = spacing { let amount = linear.resolve(ctx.state.font.font_size()); - let spacing = NodeSpacing { amount, softness: Softness::Hard }; + let spacing = NodeSpacing { amount, softness: 0 }; if axis == ctx.state.dirs.main.axis() { ctx.push_into_stack(spacing); } else { |
