feat: add gradient and image-filled text (Feature 3)#4
Merged
Conversation
Adds the ability to fill text glyphs with LinearGradient, RadialGradient, or a TextFillImage instead of a flat color. - New `TextFillImage` model with `path` and `fit` fields - New `fill` field on `TextLayer` and `TextPart` - `Canvas.text()` accepts a `fill` parameter - Per-part fill overrides layer-level fill for that segment - Block-level fill for multiline text: gradient/image spans the entire text block rather than repeating per line - Full JSON round-trip support via Pydantic discriminated union - Effects (shadow, glow, stroke, background) compose correctly with fill - 25 new tests covering models, JSON serialization, and rendering https://claude.ai/code/session_01QK5iq4VqPsjWK8R9zJp1cg
- Fix letter_spacing silently dropped when TextPart has both fill and letter_spacing set (_render_text_part now uses letter-spaced mask path) - Fix letter_spacing silently dropped in multiline fill path (_render_multiline_text now pre-computes spaced widths for block bounds and draws stroke/mask character-by-character when letter_spacing is set) - Add TextFillImage path validation in _validate_image_paths (checks layer fill and per-part fills before rendering) - Add rendering tests for TextFillImage and TextPart fill+letter_spacing https://claude.ai/code/session_01QK5iq4VqPsjWK8R9zJp1cg
|
You have used all of your free Bugbot PR reviews. To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |
Adding fill to TextLayer and TextPart caused "fill": null to appear in all serialized text layers, breaking existing snapshot tests. Fix by adding a model_serializer to both classes that omits the fill key when it is None. JSON round-trips still work because fill defaults to None when the key is absent. Also reverts the snapshot changes in test_canvas.py and test_text_layers.py that were patching around the serialization noise. https://claude.ai/code/session_01QK5iq4VqPsjWK8R9zJp1cg
…tion" This reverts commit 1300bf4.
…tests - Delete tests/test_text_fill.py (model/rendering smoke tests that were too trivial to be worth maintaining separately) - Add 7 snapshot tests to test_rendering.py covering: linear gradient fill, radial gradient fill, image fill (TextFillImage), fill + stroke, fill + letter spacing, multiline block fill, and rich text per-part fill - Add TestTextFill class to test_text_layers.py with 8 validation and serialization tests: JSON serialization for all 3 fill types, null fill serialization, JSON round-trip, TextPart fill serialization, and FileNotFoundError for missing TextFillImage paths (layer-level and part-level) https://claude.ai/code/session_01QK5iq4VqPsjWK8R9zJp1cg
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.
Adds the ability to fill text glyphs with LinearGradient, RadialGradient,
or a TextFillImage instead of a flat color.
TextFillImagemodel withpathandfitfieldsfillfield onTextLayerandTextPartCanvas.text()accepts afillparametertext block rather than repeating per line
https://claude.ai/code/session_01QK5iq4VqPsjWK8R9zJp1cg