Skip to content

Commit

Permalink
Improve text position in SVG.
Browse files Browse the repository at this point in the history
Because SVG uses the baseline to position text, while we use the
top-left of the text, we need to convert between the two.

Before this PR, the whole font height was used, which pushes the text
down too far.

After this PR, we tell SVG to use the top of the ascender as our anchor
point (`dominant-baseline: hanging`), with an additional fiddle factor
of 0.06 * font height because we actually want the top of the line, not
the ascender. The fiddle factor was worked out by eye looking at the
default sans-serif font, comparing the svg to a png generated by
piet-cairo.

Use `dominant-baseline` for text positioning.
  • Loading branch information
richard-uk1 committed Oct 29, 2022
1 parent f467cd4 commit 07318d3
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 4 deletions.
2 changes: 0 additions & 2 deletions piet-cairo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ pub struct CairoRenderContext<'a> {
error: Result<(), cairo::Error>,
}

impl<'a> CairoRenderContext<'a> {}

#[derive(Clone)]
pub enum Brush {
Solid(u32),
Expand Down
10 changes: 9 additions & 1 deletion piet-svg/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,9 +272,17 @@ impl piet::RenderContext for RenderContext {
.unwrap()
.insert(layout.font_face.clone());

// We use the top of the text for y position, but SVG uses baseline, so we need to convert
// between the two.
//
// `dominant-baseline` gets us most of the way (to the top of the ascender), so we add a
// small fiddle factor in to cover the difference between the top of the line and the top
// of the ascender (currently 6% of the font height, calcuated by eye).
let y = pos.y + 0.06 * layout.size().height;
let mut text = svg::node::element::Text::new()
.set("x", x)
.set("y", pos.y + layout.size().height)
.set("y", y)
.set("dominant-baseline", "hanging")
.set(
"style",
format!(
Expand Down
2 changes: 1 addition & 1 deletion piet-svg/src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use rustybuzz::{Face, UnicodeBuffer};

type Result<T> = std::result::Result<T, Error>;

/// SVG text (unimplemented)
/// SVG text (partially implemented)
#[derive(Clone)]
pub struct Text {
source: Arc<Mutex<MultiSource>>,
Expand Down

0 comments on commit 07318d3

Please sign in to comment.