Skip to content

feat: add gradient and image-filled text (Feature 3)#4

Merged
sjquant merged 5 commits intomainfrom
claude/review-tasks-codebase-jT6LQ
Mar 28, 2026
Merged

feat: add gradient and image-filled text (Feature 3)#4
sjquant merged 5 commits intomainfrom
claude/review-tasks-codebase-jT6LQ

Conversation

@sjquant
Copy link
Copy Markdown
Owner

@sjquant sjquant commented Mar 27, 2026

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

claude added 2 commits March 27, 2026 12:40
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
@cursor
Copy link
Copy Markdown

cursor Bot commented Mar 27, 2026

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.

claude added 3 commits March 28, 2026 01:34
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
…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
@sjquant sjquant merged commit 65e2c46 into main Mar 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants