-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
fix: Fix combining of ClipPath child elements #2198
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
fix: Fix combining of ClipPath child elements #2198
Conversation
|
@WoLewicki I would love your thoughts on this if you have any? Unfortunately I have no experience with the iOS side of this, so struggled to get anywhere with it, and have run out of energy for the moment. While looking into this I came across the SVG 1.1 Second Edition Test Suite I wonder whether it would be useful to take the test cases from the test suite and display the RNSVG version and a WebView version next to each other for visual comparison? |
|
I am no expert in this code either unfortunately. As for displaying the web versions of the components next to the original ones, I am up for it 🚀 We also have a web version inside |
|
I'm not sure whether it's better to be consistent between Android and iOS or at least fix clipPath on Android |
Do you mean I thought of maybe running EDIT: It's not quite as straightforward as that, but it sort of works with a bit of tweaking: RNSVG is on top and the WebView is below it. This one is testing |
|
Here's one that's relevant to this PR:
|
03fdc6b to
3d38e37
Compare
3d38e37 to
39624be
Compare
39624be to
77b86ad
Compare
77b86ad to
c5961ea
Compare
|
OK @jakex7, I've made more updates for this and added relevant test cases from the W3C SVG test suite. |
|
Hi @jakex7 I managed to run the Those discrepancies are obviously not part of what this PR is trying to address, so will keep them in Another issue I ran into is that on iOS, the test that includes @kacperzolkiewski I see you make a fix to the e2e tests recently. Do you have any suggestions for the above issues? I am unsure of the license for the W3C tests. The tests themselves contain a reference to their "legal" page, and if you follow the links there you end up here: According to that, as long as RN SVG does not claim compliance with the spec as a result of passing these modified tests, it seems they should be safe to include in the project and modify them however we like. However, it also says:
and the text included in the files says "All Rights Reserved." I'll probably see if I can come up with some alternative images to avoid the licensing uncertainty. Maybe it would be best to leave the tests out of this PR. |
a9ce60a to
2b40153
Compare
2b40153 to
cda175e
Compare
|
I've replaced the W3C tests with new ones and tidied up the branch, so no more test case license uncertainty. The reference generation is still broken for I also added a test case based on #1520. This one still fails on iOS after the changes because of antialiasing differences. Other failed cases are unrelated to these changes: clip-path-shapes (iOS + Android):
mask-edge-cases (iOS + Android):
I tested on both PaperExample and FabricExample. I discovered that the macOS examples don't support the E2E tests. |
cda175e to
8465469
Compare
Also allow non-numeric test cases to work
8465469 to
3dd9427
Compare
Combine clipPath children with UNION per SVG spec. Previously used simple path-based clipping that ignored per-child clipRule. - Fast path for non-overlapping children with uniform clipRule - Bitmap mask for overlapping/mixed clipRule cases - Default clipRule to nonzero (SVG spec)
Combine clipPath children with UNION per SVG spec. Previously used simple path-based clipping that ignored per-child clipRule. - Fast path for non-overlapping children with uniform clipRule - Mask-based path for overlapping/mixed clipRule cases - Default clipRule to nonzero (SVG spec) - Update Fabric TS specs and codegen defaults
3dd9427 to
a4e8c9b
Compare





Summary
Fixes combining of ClipPath child elements to match the spec and browsers, Inkscape, etc.
The problem affected both Android and iOS - both are now fixed.
Relevant issues
The code was conflating clipRules with how child elements need to be combined. These are unrelated. Children always need to be combined using UNION
From https://www.w3.org/TR/SVG11/masking.html#EstablishingANewClippingPath
iOS
After spending some more time trying to understand the iOS code it looks to me like it does not keep track of the individual
clipRules on theClipPath's child elements when adding them together. I believe this is part of the problem.As mentioned above, all of the child elements' silhouettes need to be OR'd (or UNION'd) together. The
clipRuleaffects what the silhouette of each child element looks like. So one needs to keep track of the individualclipRules, or else somehow calculate the silhouette while adding the child elements together.Given that the SVG spec says the following, maybe this can be implemented in terms of masks.
And according to ChatGPT, that is what SVGKit does:
Related commits
766926f
a1097b8
Breaking Changes
Default
clip-rulechanged fromevenoddtononzero- Per SVG spec,nonzerois the default. If your clipPaths relied on the previousevenodddefault for self-intersecting paths, addclip-rule="evenodd"explicitly.ClipPath children now correctly UNION - Previously, overlapping children could create holes. Now they combine as the spec requires.
The ClipPath example image will need to be updated in USAGE.
Test Plan
yarn testgave the following warning on themainbranch (i.e. before my change. My fix is completely unrelated to this file):After adding
// eslint-disable-next-line @typescript-eslint/no-explicit-anyon the previous line, everything is happy with my changes applied:yarn jestfailed before my change. I ranyarn jest -uon themainbranch to update the snapshots.After that,
yarn jestpasses on the branch containing my change.What's required for testing (prerequisites)?
N/A
What are the steps to reproduce (after prerequisites)?
Code like this reproduces the problem and demonstrates that the fix works:
Before the fix the result looks like this:

After the fix it looks like this:

Compatibility
Checklist
README.md__tests__folder