Open ennis opened 2 months ago
So the current implementation of computed height computes the height of each line as line_height * font_size
(where these are the input styles). This matches how the web / CSS computes line height, and is necessary if you want to match how browsers layout text. (see https://github.com/linebender/parley/pull/84)
However as you have discovered, it does not accurately measure how much space is actually needed for a visual rendering of the text. We do have this information, so we could definitely expose this in addition to the "layout line height". We could also consider making the line height computation (for the purposes of layout) configurable.
In the meantime you might want to consider increasing the line height you are using. 1.2
is the default used by web browsers, and will generally leave enough room for descenders. And anything from 1.3 to 1.5 is often recommended by typographic experts for aesthetic / readability purposes.
I see, this makes sense; in my case I am interested in the pixel bounds of the rendered glyph runs, and not so much about the typographic height, so that I can allocate an image large enough for rendering. But extra padding / line height will do in the meantime.
The following example, adapted from
swash_render
, fails on my machine (Windows 11)Code
```rust //! A simple example that lays out some text using Parley, rasterises the glyph using Swash //! and then renders it into a PNG using the `image` crate. use image::codecs::png::PngEncoder; use image::{self, Pixel, Rgba, RgbaImage}; use parley::layout::{Alignment, Glyph, GlyphRun, Layout, PositionedLayoutItem}; use parley::style::{FontStack, FontWeight, StyleProperty, TextStyle}; use parley::{FontContext, InlineBox, LayoutContext}; use peniko::Color; use std::fs::File; use swash::scale::image::Content; use swash::scale::{Render, ScaleContext, Scaler, Source, StrikeWith}; use swash::zeno; use swash::FontRef; use zeno::{Format, Vector}; fn main() { // The text we are going to style and lay out let text = String::from("Sample Text"); // The display scale for HiDPI rendering let display_scale = 1.0; // The width for line wrapping let max_advance = Some(400.0 * display_scale); // Colours for rendering let text_color = Color::rgb8(0, 0, 0); let bg_color = Rgba([255, 255, 255, 255]); // Padding around the output image let padding = 1; // Create a FontContext, LayoutContext and ScaleContext // // These are all intended to be constructed rarely (perhaps even once per app (or once per thread)) // and provide caches and scratch space to avoid allocations let mut font_cx = FontContext::default(); let mut layout_cx = LayoutContext::new(); let mut scale_cx = ScaleContext::new(); // Setup some Parley text styles let font_stack = FontStack::Source("Inter"); let mut layout = { // TREE BUILDER // ============ let root_style = TextStyle { brush: text_color, font_stack, line_height: 1.0, font_size: 40.0, ..Default::default() }; let mut builder = layout_cx.tree_builder(&mut font_cx, display_scale, &root_style); builder.push_text(&text); // Build the builder into a Layout // let mut layout: Layoutwith
thread 'main' panicked at examples\swash_render\src/main.rs:197:25: Image index (86, 42) out of bounds (235, 42)
. It seems that the allocated image isn't tall enough. It does work correctly if I change the text toSamle Text
(without thep
). It's as if the height calculation didn't take into account the descender of thep
.