Skip to content

Legacy .ai export: a radial gradient's color stops are written from ramp point 0 to 100 - #3285

Open
dotCooCoo wants to merge 1 commit into
storytold:mainfrom
dotCooCoo:fix/legacy-ai-radial-gradient-stop-order
Open

dotCooCoo wants to merge 1 commit into
storytold:mainfrom
dotCooCoo:fix/legacy-ai-radial-gradient-stop-order

Conversation

@dotCooCoo

@dotCooCoo dotCooCoo commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

What and why

Fixes #2687. This follows up #2807.

On main, saving #2687's SVG as a version 7 .ai (--ai-version 7) writes the %_Bs color stops of both gradients
from ramp point 100 down to 0. On #2807, @alongtheblue-sketch
reported that the reference app reads
both stops of the radial gradient written that way at ramp point 100 and draws the circle in #1b2a6b. It reads a
radial gradient with three stops written the same way in reverse order. The same file with the radial stops listed
from 0 to 100 drew as the SVG does, with or without Bh.

The Adobe Illustrator File Format Specification version 7.0
(PDF) lists a linear gradient's stops from 100 to 0
(§1.4.3, p. 10). Its radial definition, "White & Purple Radial" (§3.5.2, p. 42), lists them from 10 to 100.

The writer now lists a radial gradient's stops from the first to the last. Each stop is written with its own midpoint
to the next stop, and §3.5.2 says the last stop's midpoint is ignored. Linear gradients are unchanged. This branch was
not checked in the reference app.

How it was tested

  • legacy_ai::tests::radial_gradient_stops_are_listed_from_the_first (crates/eps) writes a radial and a linear
    gradient with three stops and checks each %_Bs line's color, midpoint and ramp point in order. It reads the file
    back and checks both gradients' stops.
  • tests_legacy_ai::a_radial_gradient_lists_its_stops_from_the_first (crates/engine) saves convert --ai-version 7: radial gradient fill draws as a flat colour in Illustrator 2026 #2687's SVG with
    file.saveCopy as a version 7 file and checks the order of both definitions' stops.

With the writer's stops reversed for every gradient again, both tests fail at the radial definition.

On Windows 11 (x86-64) with rustc 1.99.0, on top of main at bc1ae08:

  • CRAFT_FONTS_DIR=<craft-fonts checkout> cargo xtask ci passes its 10 steps: 8,572 tests passed, 0 failed, 13 ignored.

git merge-tree reports no conflicts with main at bc1ae08 or with #2326 and #2672, which also change
crates/eps/src/legacy_ai.rs. #2804 also changes that file, and that file merges cleanly with it.

Checklist

  • cargo xtask ci passes (fmt, clippy, tests, assets, brands, layers, wasm).
  • No panics in shipped code: no unwrap(), expect(), panic!, unreachable!, todo! or
    unimplemented! outside tests, and no unchecked indexing on data from files, parameters or
    messages. Errors are returned as Result and shown to the user
    (why and how).
  • Clean-room: nothing copied from Adobe products or GPL/AGPL code (AGENTS.md).
  • Every new asset has a row in ASSETS.md.

Summary by CodeRabbit

  • Bug Fixes
    • Corrected gradient stop ordering when importing and exporting legacy AI files.
    • Radial gradients now preserve stops in their original source order.
    • Linear gradients now emit stops in reverse order as expected by the legacy format.
    • Preserved gradient colors, midpoints, offsets, and gradient types during conversion.
  • Documentation
    • Updated legacy AI gradient documentation to accurately describe rendering behavior.

…amp point 0 to 100

The version 7 .ai writer wrote the %_Bs color stops of every gradient
from ramp point 100 down to 0. The Adobe Illustrator File Format
Specification version 7.0 lists a linear gradient's stops in that order
(section 1.4.3). Its radial definition, "White & Purple Radial", lists
them from 10 to 100 (section 3.5.2). As reported on storytold#2807, the
reference app reads both stops of storytold#2687's radial gradient, written from
100 down to 0, at ramp point 100 and draws the circle in #1b2a6b. It
reads a radial gradient with three stops written that way in reverse
order.

The writer now lists a radial gradient's stops from the first to the
last. Each stop is written with its own midpoint to the next stop, and
section 3.5.2 says the last stop's midpoint is ignored. Linear
gradients are unchanged.
@coderabbitai

coderabbitai Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: storytold/vectorcraft/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 1eea66a0-d6ee-4fd2-be24-4368f7e0aeae
📥 Commits

Reviewing files that changed from the base of the PR and between bc1ae08 and fb356e8.

📒 Files selected for processing: 3
  • crates/engine/src/tests_legacy_ai.rs
  • crates/eps/src/legacy_ai.rs
  • crates/eps/src/tests_legacy_ai.rs

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 5 remain after this review.

📝 Walkthrough

The AI v7 exporter now preserves source stop order for radial gradients and reverses stop order for linear gradients. Tests verify gradient stop ordering, colors, ramp positions, midpoints, and round-trip import.

Changes: AI gradient export

Layer / File(s) Summary
Gradient stop serialization and validation
crates/eps/src/legacy_ai.rs, crates/eps/src/tests_legacy_ai.rs, crates/engine/src/tests_legacy_ai.rs
gradient_def preserves radial stop order and reverses linear stop order. Tests check serialized stop values and round-trip import. Gradient documentation and a test comment were updated.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: danngreen

Merge Risk: ⚪ Minimal · up to fb356

The radial-gradient ordering change is ready to merge after normal checks. The separate artwork and layer-name issues are outside this change.

Architecture risk: 🔵 Low · up to fb356

The change affects 1 system.

Changed systems: crates

Architecture concerns
No architecture-level concerns identified.

Review details

Systems and components

  • observed — crates (service) was modified; 3 changed files map to changed impact.

Before / after behavior

  • observed — Modified behavior in crates/engine/src/tests_legacy_ai.rs: Updated the radial-gradient comment to state that the source file and linear gradient have no focal highlight, without retaining the reference-app rendering claim.
  • observed — Modified behavior in crates/engine/src/tests_legacy_ai.rs: Added coverage that parses AI gradient definitions and verifies radial stops are emitted white at ramp point 0 then navy at 100, while linear stops are emitted navy at 100 then white at 0.
  • observed — Modified behavior in crates/eps/src/legacy_ai.rs: Documented that linear gradient stops are listed last-to-first, while radial gradient stops are listed first-to-last.
  • observed — Modified behavior in crates/eps/src/legacy_ai.rs: gradient_def now determines whether the gradient is radial, preserves stop order for radial gradients, and reverses stops only for linear gradients instead of reversing every gradient.
Pre-merge checks: Passed 5
Check name Status Explanation
Title check Passed The title clearly identifies the primary change: writing radial-gradient color stops from ramp point 0 to 100 in legacy .ai export.
Description check Passed The description is complete and follows the repository template. It explains the change, motivation, testing, linked issues, test results, and checklist status.
Linked Issues check Passed For directly linked issue #2687, the PR changes gradient_def so radial stops retain source order (0 to 100) and linear stops retain reverse order. The radial stops include their midpoint values. The…
Out of Scope Changes check Passed The changes are limited to legacy AI gradient documentation, radial and linear stop serialization, and focused EPS and engine tests. The tests directly verify the linked issue's radial-gradient export…
Docstring Coverage Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 8 functions across 3 files.
Full details: Linked Issues check

Explanation

For directly linked issue #2687, the PR changes gradient_def so radial stops retain source order (0 to 100) and linear stops retain reverse order. The radial stops include their midpoint values. The new crates/eps test checks serialized colors, midpoints, ramp points, gradient kinds, and read-back values. The new crates/engine test checks the version 7 export for the reported white-to-#1b2a6b radial gradient. The issue also reports missing artwork and layer-name encoding symptoms, but the linked issue provides no coding acceptance criteria that require this PR to resolve those separate symptoms.

Full details: Out of Scope Changes check

Explanation

The changes are limited to legacy AI gradient documentation, radial and linear stop serialization, and focused EPS and engine tests. The tests directly verify the linked issue's radial-gradient export behavior and protect the unchanged linear-gradient ordering. No unrelated product behavior or unrelated files are changed.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

This branch has not been deployed

No deployments
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.

convert --ai-version 7: radial gradient fill draws as a flat colour in Illustrator 2026

1 participant