flxzt/rnote · error

Building text layout failed, Err

Error message

Building text layout failed, Err: {e:?}

What it means

get_selection_rects_for_cursors first builds a text layout via build_text_layout; any layout failure is re-wrapped with this message. It is the same piet BuildError family as error 144, surfaced specifically while computing selection rectangles for drawing the text selection highlight.

Solutions

  1. Resolve the underlying font/layout issue (install or substitute the missing font)
  2. Catch the error in draw_text_selection and skip drawing the selection for that frame instead of failing the render pass
  3. Cache a fallback layout built with a guaranteed default family
  4. Ensure attribute ranges are recomputed whenever the text string changes before selection queries

Example fix

// before
let text_layout = self.build_text_layout(&mut piet_cairo::CairoText::new(), text)
    .map_err(|e| anyhow!("Building text layout failed, Err: {e:?}"))?;
// after
let text_layout = match self.build_text_layout(&mut piet_cairo::CairoText::new(), text) {
    Ok(l) => l,
    Err(e) => { log::warn!("selection layout failed: {e:?}"); return Ok(Vec::new()); }
};
Defensive patterns

Strategy: try-catch

Validate before calling

let n = text.len();
let range_ok = cursor.cur_cursor() <= n && selection_cursor.cur_cursor() <= n;
if !range_ok { return Ok(Vec::new()); }

Try / catch

match stroke.get_selection_rects_for_cursors(piet, text, cursor, sel) {
    Ok(rects) => rects,
    Err(e) => { log::warn!("selection rendering skipped: {e:?}"); Vec::new() }
}

Prevention

When it happens

Trigger: draw_text_selection requesting selection rects when the layout cannot be built — unavailable font family in the text style, or text state changed such that attributes/ranges are invalid.

Common situations: Rendering selections in text whose font was uninstalled since the file was saved; headless rendering where no fonts are available.

Related errors


AI-assisted analysis of flxzt/rnote@bbc5354502 (2026-09-08). Data as JSON: /api/errors/d06bdba4ee0d8b0a. Report an issue: GitHub.

Appendix: source

Thrown at crates/rnote-engine/src/strokes/textstroke.rs:348

        cursor: &GraphemeCursor,
    ) -> anyhow::Result<piet::HitTestPosition>
    where
        T: piet::Text,
    {
        let text_layout = self.build_text_layout(piet_text, text)?;

        Ok(text_layout.hit_test_text_position(cursor.cur_cursor()))
    }

    pub fn get_selection_rects_for_cursors(
        &self,
        text: String,
        cursor: &GraphemeCursor,
        selection_cursor: &GraphemeCursor,
    ) -> anyhow::Result<Vec<kurbo::Rect>> {
        let text_layout = self
            .build_text_layout(&mut piet_cairo::CairoText::new(), text)
            .map_err(|e| anyhow::anyhow!("Building text layout failed, Err: {e:?}"))?;

        let range = if selection_cursor.cur_cursor() >= cursor.cur_cursor() {
            cursor.cur_cursor()..selection_cursor.cur_cursor()
        } else {
            selection_cursor.cur_cursor()..cursor.cur_cursor()
        };

        Ok(text_layout.rects_for_range(range))
    }

    /// Draw the cursor.
    pub fn draw_cursor(
        &self,
        cx: &mut impl piet::RenderContext,
        text: String,
        cursor: &GraphemeCursor,
        affine: &DAffine2,
        camera: &Camera,

View on GitHub (pinned to bbc5354502)