fix(text): honor element color/anchor on parse_colors path and drop O(n²) fitting#28
Merged
Merged
Conversation
…(n^2) fitting - A6: unmarked text on the parse_colors path now uses the element-level color instead of a hardcoded black. parse_colored_text() gains a default_color arg. - A7: the vertical anchor component (e.g. 'mm', 'mb') is now applied to single-line parse_colors text, matching the plain path — previously it drew at the raw y with a 'lt' anchor and shifted down by half the text height. - B2: replace the character-at-a-time truncate (O(n^2), seconds on the event loop for long strings) with a binary-search cut (O(n log n)), and wrap by accumulating precomputed word widths instead of re-measuring the whole line per word. - B7: remove the two textbbox() calls in draw_multiline whose results were discarded, and the per-segment textbbox() calls on the parse_colors paths of draw_text (pos_y now derives from font metrics / precomputed block height). Adds regression tests for A6, A7, and the B2 helpers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UVpLN4Rzdv7y3ud7QzutVJ
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Correctness and performance fixes for the
textandmultilineelements, focused on theparse_colorspath and on text fitting.Findings addressed
parse_colorsignored elementcolor.parse_colored_texthardcodedblackfor text outside any[color]markup, so{value: "plain text", color: red, parse_colors: true}rendered black. The helper now takes adefault_colorargument anddraw_text/draw_multilinepass the element color through.parse_colorsdropped the vertical anchor for single-line text. The single-line branch drew at the rawywithanchor="lt", soanchor: mm/mbwere silently ignored and the text shifted down by half its height the momentparse_colorswas enabled. The vertical anchor offset is now applied, matching the plain path.truncate: trueshrank the string one character at a time, re-measuring the whole string each step (measured at ~3s for a 1600-word string — that blocks HA's event loop). It now binary-searches the cut point (O(n log n)). Word-wrap accumulates precomputed word widths instead of re-measuring the whole current line per word.textbboxafterdraw.text.draw_multilinecalledtextbboxtwice and threw the result away (pure waste); those are removed. The per-segmenttextbboxcalls on theparse_colorspaths ofdraw_textare replaced with cheap font-metric / precomputed block-height math for thepos_ycursor.Note / deferred
Finding A7 also mentions a related inconsistency: on the
parse_colorspath,calculate_segment_positionsapplies bothalignand the horizontal anchor component, soanchor: mm+align: centerdouble-offsets horizontally. Fixing that cleanly depends on the intended semantics ofalignvsanchoron this path (Pillow treatsalignas intra-block justification only), so I've left it out of this PR to avoid guessing at behavior — happy to follow up if you confirm the desired semantics.Tests
Adds regression tests for A6 (element color applied), A7 (vertical anchor respected), and unit tests for the B2 truncate/wrap helpers (including a check that binary-search truncation matches the old linear result). No new failures in the suite (pre-existing
tests/visual/*byte-snapshot failures under Pillow 12 are unrelated).🤖 Generated with Claude Code