{"record":{"id":"b016caf3c044b034","repo":"flxzt/rnote","slug":"building-piet-text-layout-failed-err-e","errorCode":null,"errorMessage":"Building piet text layout failed, Err: {e:?}","messagePattern":"Building piet text layout failed, Err: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/rnote-engine/src/strokes/textstroke.rs","lineNumber":284,"sourceCode":"        let mut ranged_text_attributes = self.ranged_text_attributes.clone();\n        ranged_text_attributes.sort_unstable_by_key(|first| first.range.start);\n\n        // Apply ranged attributes\n        for (range, piet_attr) in ranged_text_attributes\n            .into_iter()\n            .filter_map(|ranged_attr| {\n                Some((\n                    ranged_attr.range,\n                    ranged_attr.attribute.try_into_piet(piet_text).ok()?,\n                ))\n            })\n        {\n            text_layout_builder = text_layout_builder.range_attribute(range, piet_attr);\n        }\n\n        text_layout_builder\n            .build()\n            .map_err(|e| anyhow::anyhow!(\"Building piet text layout failed, Err: {e:?}\"))\n    }\n\n    pub fn untransformed_size<T>(&self, piet_text: &mut T, text: String) -> anyhow::Result<Vector2>\n    where\n        T: piet::Text,\n    {\n        let text_layout = self.build_text_layout(piet_text, text)?;\n        let size = text_layout.size();\n        Ok(Vector2::new(size.width, size.height))\n    }\n\n    /// The cursors line metric relative to the textstroke bounds.\n    pub fn lines<T>(&self, piet_text: &mut T, text: String) -> anyhow::Result<Vec<piet::LineMetric>>\n    where\n        T: piet::Text,\n    {\n        let text_layout = self.build_text_layout(piet_text, text)?;\n","sourceCodeStart":266,"sourceCodeEnd":302,"githubUrl":"https://github.com/flxzt/rnote/blob/bbc5354502ba2fc83eec2670b535348825e679a6/crates/rnote-engine/src/strokes/textstroke.rs#L266-L302","documentation":"build_text_layout uses a piet TextLayoutBuilder to lay out the text stroke; piet's build() returns a Result with a BuildError. Any layout failure (bad attributes, font issues, invalid ranges) is wrapped into this anyhow error. Callers like untransformed_size and cursor/selection APIs depend on it, so a failure here breaks all text measurement and editing.","triggerScenarios":"Calling untransformed_size, lines, cursor_hittest_position, or get_selection_rects_for_cursors when the underlying layout build fails — typically because a TextAttribute references an unavailable font (see error 143) or an out-of-order/invalid range attribute.","commonSituations":"Text containing characters unsupported by the resolved font; attributes applied with ranges beyond text length; systems with broken fontconfig where piet cannot load any font.","solutions":["Fix the root attribute error: ensure all font families in text_style resolve on this system","Validate attribute ranges fit within the text length before building the layout","Catch this error in callers and render fallback metrics or an error placeholder instead of propagating","Verify fontconfig works (fc-list) on the target machine; install base fonts in containers/headless environments"],"exampleFix":"// before\nlet size = stroke.untransformed_size(&mut piet_cairo::CairoText::new(), text)?;\n// after\nlet size = stroke.untransformed_size(&mut piet_cairo::CairoText::new(), text)\n    .with_context(|| format!(\"text layout failed for {:?}\", stroke.text_style.font_attrs()))?;","handlingStrategy":"try-catch","validationCode":"// ensure all font families resolve before building\nfor attr in &stroke.text_style.attributes {\n    if let TextAttribute::FontFamily(f) = attr {\n        if piet_text.font_family(f.as_str()).is_none() { return Err(anyhow!(\"font '{f}' unavailable\")); }\n    }\n}","typeGuard":null,"tryCatchPattern":"let size = stroke.untransformed_size(&mut piet_cairo::CairoText::new(), text)\n    .context(\"text layout failed; check font availability and attribute ranges\")?;","preventionTips":["Validate font families resolve before setting text attributes (see error 143)","Keep attribute ranges within the text's byte length","Install baseline fonts (fontconfig + DejaVu) in containers/headless environments","Log the inner {e:?} BuildError — it names the exact failing attribute"],"tags":["piet","text-layout","text-rendering"],"backgroundTag":"text-layout-build-failed","analyzedSha":"bbc5354502ba2fc83eec2670b535348825e679a6","analyzedAt":"2026-09-08T13:20:33.747Z","contentChangedAt":"2026-09-08T13:20:33.747Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}