[vector_graphics][vector_graphics_compiler] Fix text-anchor and tspan gap with adjacent <tspan>s (#11637) ## Summary `<text x="..." text-anchor="middle"><tspan>ABCDEFG</tspan><tspan>ABCDEFG</tspan></text>` rendered noticeably differently from the equivalent single-tspan `<tspan>ABCDEFGABCDEFG</tspan>`: the two-tspan version was shifted right past the anchor *and* had a visible space between the two tspans. Two independent root causes, fixed in two separate places. **1. `vector_graphics` — anchor applies per-chunk, not per-tspan.** The listener was independently offsetting each tspan's paragraph by `dx - paragraphWidth * xAnchorMultiplier`. Per the SVG spec, `text-anchor` applies to the entire anchored chunk (the contiguous run of glyphs whose start is established by an explicit `x`/`y`), not to each tspan in isolation. The listener now buffers per-tspan paragraphs within a chunk, flushes on the next explicit position update or on `toPicture()`, and applies the anchor offset to the chunk total. `text-anchor="start"` behavior is unchanged. A new TextPosition with `x` (or `reset=true`) starts a new chunk; bare per-tspan TextPositions emitted by the parser do not. **2. `vector_graphics_compiler` — parser injected a spurious space between adjacent tspans.** `_appendText` had a "previous element was a tspan ⇒ prepend a space" rule that fired regardless of whether the source actually had whitespace at the boundary. So `<tspan>A</tspan><tspan>B</tspan>` parsed to `['A', ' B']` (the visible gap), even though every browser parses it to `'AB'`. Replaced with a rule that only prepends when whitespace truly exists at the boundary — either as a leading-whitespace prefix on the current text, or as an earlier whitespace-only text event we've now flagged. Tests added on both sides: - `vector_graphics/test/listener_test.dart`: `Text anchor middle centers the entire chunk across tspans` — drives the listener with a two-tspan middle-anchored chunk (including the parser's bare per-tspan TextPosition between them) and asserts the second tspan starts at the original x. - `vector_graphics_compiler/test/parser_test.dart`: `adjacent tspans without whitespace are not separated by a space` and `adjacent tspans with whitespace between still get a space` — locks down both branches of the new parser rule. Both packages bumped to `1.2.1` with CHANGELOG entries. Fixes flutter/flutter#185927 ## Before / After | SVG | Before (buggy) | After (this PR) | | --- | --- | --- | | **svg1** (single tspan)<br>`<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100" fill="none">`<br> `<text x="100" y="50" text-anchor="middle" fill="#FF0000">`<br> `<tspan>ABCDEFGABCDEFG</tspan>`<br> `</text>`<br>`</svg>`<br><br>**svg2** (two tspans)<br>`<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100" fill="none">`<br> `<text x="100" y="50" text-anchor="middle" fill="#FF0000">`<br> `<tspan>ABCDEFG</tspan><tspan>ABCDEFG</tspan>`<br> `</text>`<br>`</svg>` | <img width="390" height="844" alt="image" src="https://github.com/user-attachments/assets/7ffbe594-d821-4b4c-b759-c5fb61a61339" /> | <img width="780" height="1688" alt="image" src="https://github.com/user-attachments/assets/076b69fb-2bfc-490a-9669-566e45f7e9a2" /> | ## Test plan 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This repo is a companion repo to the main flutter repo. It contains the source code for Flutter's first-party packages (i.e., packages developed by the core Flutter team). Check the packages directory to see all packages.
These packages are also available on pub.
Please file any issues, bugs, or feature requests in the main flutter repo. Issues pertaining to this repository are labeled “package”.
If you wish to contribute a new package to the Flutter ecosystem, please see the documentation for developing packages. You can store your package source code in any GitHub repository (the present repo is only intended for packages developed by the core Flutter team). Once your package is ready you can publish to the pub repository.
If you wish to contribute a change to any of the existing packages in this repo, please review our contribution guide, and send a pull request.
These are the packages hosted in this repository: