{"record":{"id":"fba90743d0a6b901","repo":"FyroxEngine/Fyrox","slug":"unable-to-measure-text-due-to-unloaded-fonts","errorCode":null,"errorMessage":"Unable to measure text due to unloaded fonts. {:?}.\n{}","messagePattern":"Unable to measure text due to unloaded fonts\\. (.+?)\\.\n(.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"fyrox-ui/src/formatted_text.rs","lineNumber":897,"sourceCode":"            if let Some(font) = run.font() {\n                write!(result, \"\\nRun {:?}: {}\", run.range, font.header().state).unwrap();\n            }\n        }\n        result\n    }\n\n    pub fn measure_and_arrange(&mut self) -> Vector2<f32> {\n        let size = self.measure();\n        self.arrange(self.constraint);\n        size\n    }\n\n    pub fn measure(&mut self) -> Vector2<f32> {\n        let mut lines = std::mem::take(&mut self.lines);\n        lines.clear();\n        // Fail early if any font is not available.\n        if !self.are_fonts_loaded() {\n            Log::err(format!(\n                \"Unable to measure text due to unloaded fonts. {:?}.\\n{}\",\n                self.text(),\n                self.font_loading_summary(),\n            ));\n            return Vector2::default();\n        }\n        let constraint = Vector2::new(\n            (self.constraint.x - (self.padding.left + self.padding.right)).max(0.0),\n            (self.constraint.y - (self.padding.top + self.padding.bottom)).max(0.0),\n        );\n        let first_indent = self.line_indent.max(0.0);\n        let normal_indent = -self.line_indent.min(0.0);\n        let sink = WrapSink {\n            lines: &mut lines,\n            normal_width: constraint.x - normal_indent,\n            first_width: constraint.x - first_indent,\n        };\n        if let Some(mask) = *self.mask_char {","sourceCodeStart":879,"sourceCodeEnd":915,"githubUrl":"https://github.com/FyroxEngine/Fyrox/blob/76c91aad8eca488ce527b1af707be8b3b24ad72d/fyrox-ui/src/formatted_text.rs#L879-L915","documentation":"FormattedText::measure needs every font referenced by the text to be loaded; measuring with missing fonts would produce garbage metrics. If any font is absent it logs this error with the text and a per-font loading summary, and returns a zero-size measurement.","triggerScenarios":"Calling measure (directly or via text-measuring during layout) when the UI's font resource is still loading, failed to load, or was never set.","commonSituations":"Referencing fonts by path that don't exist on disk; measuring on the first frame before async font loading finishes; deleted font resources in .rgs files; wrong resource path in theme.","solutions":["Wait for font resources to finish loading before building/measuring text widgets","Verify font resource paths and that the resource load succeeded","Check font_loading_summary() output to see which font failed and why","Provide a fallback font that is always loaded"],"exampleFix":"// before\nlet size = formatted_text.measure();\n// after\nif formatted_text.are_fonts_loaded() {\n    let size = formatted_text.measure();\n} else {\n    // retry next frame or log font_loading_summary()\n}","handlingStrategy":"validation","validationCode":"if !formatted_text.are_fonts_loaded() {\n    // defer measuring / rendering until fonts load\n} else {\n    let size = formatted_text.measure();\n}","typeGuard":"fn text_ready(ft: &FormattedText) -> bool { ft.are_fonts_loaded() }","tryCatchPattern":null,"preventionTips":["Await font resource load completion before first layout pass","Verify font paths in themes and widget styles","Ship a guaranteed-loaded fallback font","Inspect font_loading_summary() when measurement returns zero size"],"tags":["ui","text","font","resource-loading"],"backgroundTag":"file-not-found","analyzedSha":"76c91aad8eca488ce527b1af707be8b3b24ad72d","analyzedAt":"2026-09-10T16:04:01.633Z","contentChangedAt":"2026-09-10T16:04:01.633Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}