WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED WORKSFORME
110357
ClippPath artifacts due to mask image clamping
https://bugs.webkit.org/show_bug.cgi?id=110357
Summary
ClippPath artifacts due to mask image clamping
Florin Malita
Reported
2013-02-20 10:47:02 PST
Created
attachment 189338
[details]
The softest clip you've ever seen
https://code.google.com/p/chromium/issues/detail?id=176850
For clipPaths containing more than one shape, we devolve to masking (see below). The mask is drawn anti-aliased into an image buffer clamped to 4096 x 4096. If the clip target is larger than that, the mask gets scaled, and so do its subpixel artifacts. The reason for using mask-based clipping is explained in RenderSVGResourceClipper::pathOnlyClipping(): // If clip-path only contains one visible shape or path, we can use path-based clipping. Invisible // shapes don't affect the clipping and can be ignored. If clip-path contains more than one // visible shape, the additive clipping may not work, caused by the clipRule. EvenOdd // as well as NonZero can cause self-clipping of the elements. // See also
http://www.w3.org/TR/SVG/painting.html#FillRuleProperty
Attachments
The softest clip you've ever seen
(438 bytes, image/svg+xml)
2013-02-20 10:47 PST
,
Florin Malita
no flags
Details
View All
Add attachment
proposed patch, testcase, etc.
Florin Malita
Comment 1
2013-02-20 11:03:39 PST
I don't see an ideal solution here, but I'll throw in a couple of ideas: * try harder to avoid mask-based clipping - the graphics backends should be able to handle multiple simple shapes with consistent fill-rules natively * do not cache the mask image for objects with a size > 4096px, but instead always draw it on the fly clamped to the current clip region (which, presumably, is < 4096px). This would avoid mask scaling issues but the result is not cacheable since it doesn't cover the whole object.
Dirk Schulze
Comment 2
2013-02-20 11:28:38 PST
(In reply to
comment #1
)
> I don't see an ideal solution here, but I'll throw in a couple of ideas: > > * try harder to avoid mask-based clipping - the graphics backends should be able to handle multiple simple shapes with consistent fill-rules natively > > * do not cache the mask image for objects with a size > 4096px, but instead always draw it on the fly clamped to the current clip region (which, presumably, is < 4096px). This would avoid mask scaling issues but the result is not cacheable since it doesn't cover the whole object.
Sounds both reasonable. Additionally, the SVG WG want to allow all graphics elements and container elements as content for <clipPath>. This makes a lot of sense for web authors, but makes is harder to optimize for us. A possible solution is to create the union of all paths according to the winding rule of each path. This is very complicated and we might use a library for that (as inkscape does). But this is something that we need to decide in the future.
Matt
Comment 3
2013-02-23 10:03:31 PST
I reported the original issue in chromium. I mentioned there that I hit this when using a scale transform but reduced it to having large coordinates in the reproducer I filed. I made a slightly different reproducer that is closer to my original problem and uses a scale transform. You can see it at
http://jsfiddle.net/maliberty/KAxLq
It shows the same clipping artifact but the untransformed clippath is small enough to fit in a 4096x4096 buffer. It is applied to shapes that are themselves inside the same transform group. It would seem you could apply the clippath pre-transform and then transform the result without any of these issues. It would solve my particular issue though not the more general problem that has been discussed here. Is this reasonable? Note that Safari 5.1.7 doesn't have a problem with either case. That was surprising to some but it is verifiable and it would be nice to understand why it works there.
Florin Malita
Comment 4
2013-02-23 10:39:26 PST
(In reply to
comment #3
)
> It shows the same clipping artifact but the untransformed clippath is small enough to fit in a 4096x4096 buffer. It is applied to shapes that are themselves inside the same transform group. It would seem you could apply the clippath pre-transform and then transform the result without any of these issues. It would solve my particular issue though not the more general problem that has been discussed here. Is this reasonable?
Unfortunately, due to the current mask-based clipping approach, I don't think that would help: for results to be accurate, the mask bitmap needs to match the device resolution (hence it needs to be sized in absolute coordinates). Otherwise whatever intermediate bitmap we get by applying it in user coordinates would still have to be scaled when drawn, with the same undesirable results. Basically the root cause is the mask resolution not matching the device resolution; whether this is because we clamp its size to 4096^2 or because we compute it in a different coordinate space doesn't really make a difference.
> Note that Safari 5.1.7 doesn't have a problem with either case. That was surprising to some but it is verifiable and it would be nice to understand why it works there.
Yes, agreed. I can't easily check the WK version used in 5.1.7, but I presume it's < 96155 (where the 4096 clamping was introduced -
http://trac.webkit.org/changeset/96155
). So I'm guessing it works because in 5.1.7 we allocate an appropriately sized mask.
Florin Malita
Comment 5
2013-02-23 10:47:50 PST
BTW, you can avoid the artifacts by forcing AA off on the clipPath (shape-rendering='crispEdges' -
http://www.w3.org/TR/SVG/painting.html#ShapeRenderingProperty
) but that's not much help because now the location & size will be snapped to ($element_size / 4096) multiples
Florin Malita
Comment 6
2013-02-23 10:49:03 PST
http://jsfiddle.net/Jt8Pg/
(for the above comment)(In reply to
comment #5
)
> BTW, you can avoid the artifacts by forcing AA off on the clipPath (shape-rendering='crispEdges' -
http://www.w3.org/TR/SVG/painting.html#ShapeRenderingProperty
) but that's not much help because now the location & size will be snapped to ($element_size / 4096) multiples
http://jsfiddle.net/Jt8Pg/
Matt
Comment 7
2013-02-23 16:00:30 PST
> Yes, agreed. I can't easily check the WK version used in 5.1.7, but I presume it's < 96155 (where the 4096 clamping was introduced -
http://trac.webkit.org/changeset/96155
). So I'm guessing it works because in 5.1.7 we allocate an appropriately sized mask.
According to
http://en.wikipedia.org/wiki/Safari_version_history#Mac
5.1.7 uses webkit 534.57.2. I'm not sure how that relates to the number you gave but your supposition seems reasonable.
mahi
Comment 8
2018-09-11 01:20:08 PDT
yeah facing same problem
https://www.cheatengineapkdl.com/
Brent Fulgham
Comment 9
2022-07-15 16:05:34 PDT
Safari, Chrome, and Firefox render the test case the same way. I'm not sure there is an issue here.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug