diff --git a/system/ui/widgets/html_render.py b/system/ui/widgets/html_render.py index 4d1e9d78e1..9ff91a5099 100644 --- a/system/ui/widgets/html_render.py +++ b/system/ui/widgets/html_render.py @@ -53,7 +53,10 @@ class HtmlRenderer(Widget): text_size: dict | None = None, text_color: rl.Color = rl.WHITE): super().__init__() self._text_color = text_color - self.elements: list[HtmlElement] = [] + + self._total_height = 0.0 + self._height_needs_recompute = True + self._prev_content_width = -1 self._normal_font = gui_app.font(FontWeight.NORMAL) self._bold_font = gui_app.font(FontWeight.BOLD) self._indent_level = 0 @@ -73,6 +76,7 @@ class HtmlRenderer(Widget): ElementType.BR: {"size": 0, "weight": FontWeight.NORMAL, "margin_top": 0, "margin_bottom": 12}, } + self.elements: list[HtmlElement] = [] if file_path is not None: self.parse_html_file(file_path) elif text is not None: @@ -87,6 +91,7 @@ class HtmlRenderer(Widget): def parse_html_content(self, html_content: str) -> None: self.elements.clear() + self._height_needs_recompute = True # Remove HTML comments html_content = re.sub(r'', '', html_content, flags=re.DOTALL) @@ -190,27 +195,32 @@ class HtmlRenderer(Widget): return current_y - rect.y def get_total_height(self, content_width: int) -> float: - total_height = 0.0 + if not self._height_needs_recompute and self._prev_content_width == content_width: + return self.total_height + + self.total_height = 0.0 padding = 20 usable_width = content_width - (padding * 2) for element in self.elements: if element.type == ElementType.BR: - total_height += element.margin_bottom + self.total_height += element.margin_bottom continue - total_height += element.margin_top + self.total_height += element.margin_top if element.content: font = self._get_font(element.font_weight) wrapped_lines = wrap_text(font, element.content, element.font_size, int(usable_width)) for _ in wrapped_lines: - total_height += element.font_size * element.line_height + self.total_height += element.font_size * element.line_height - total_height += element.margin_bottom + self.total_height += element.margin_bottom - return total_height + self._prev_content_width = content_width + self._height_needs_recompute = False + return self.total_height def _get_font(self, weight: FontWeight): if weight == FontWeight.BOLD: