Bug 30479 - Add a CSS property that allows shadows to work for SVG content
Summary: Add a CSS property that allows shadows to work for SVG content
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: SVG (show other bugs)
Version: 528+ (Nightly build)
Hardware: PC OS X 10.5
: P2 Normal
Assignee: Beth Dakin
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2009-10-17 10:27 PDT by Beth Dakin
Modified: 2009-10-22 16:51 PDT (History)
8 users (show)

See Also:


Attachments
Patch (124.82 KB, patch)
2009-10-17 10:30 PDT, Beth Dakin
no flags Details | Formatted Diff | Diff
Test for -webkit-box-shadow and SVG Filters (788 bytes, image/svg+xml)
2009-10-18 00:47 PDT, Dirk Schulze
no flags Details
Patch with more tests (430.23 KB, patch)
2009-10-20 16:33 PDT, Beth Dakin
no flags Details | Formatted Diff | Diff
Patch after talking with Dan (431.22 KB, patch)
2009-10-22 16:08 PDT, Beth Dakin
mitz: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Beth Dakin 2009-10-17 10:27:35 PDT
We want to add a property that is like -webkit-box-shadow for SVG. It should follow the path of the SVG rather than being a box. (Unless the SVG is a box of course!)

<rdar://problem/6942706>
Comment 1 Beth Dakin 2009-10-17 10:30:09 PDT
Created attachment 41361 [details]
Patch

Here is a first-run patch. It adds a property called -webkit-shadow. Maybe we want to re-name that to -webkit-svg-shadow? Not sure.
Comment 2 Dirk Schulze 2009-10-17 11:47:32 PDT
Why do we want this? We have SVG Filters feGaussianBlur and a fast bluring mode for shadows? Isn't it a duplication of functionality?
Comment 3 Dean Jackson 2009-10-17 16:12:47 PDT
I would consider it analogous to the box and text shadow properties in CSS, or the shadow property in the canvas 2d context. Yes, you could use SVG filters, but this seems to be a simple common property that makes sense in CSS.
Comment 4 Dean Jackson 2009-10-17 16:15:00 PDT
Furthermore, the CSS property allows easy authoring of different types of shadows (ie. different offsets, blur radii, etc). With SVG filters this would require multiple filter definitions, each added to the content of the page.
Comment 5 Dirk Schulze 2009-10-18 00:47:42 PDT
Created attachment 41373 [details]
Test for -webkit-box-shadow and SVG Filters

Nevertheless, it would be interesting what css-shadows are doing with the Filter, Masking or Clipping code. Something like <mask style="-webkit-box-shadow" id="mask"> ....

I added An example for Filters as an attachment. This needs a filter enabled build for testing.
Comment 6 Dirk Schulze 2009-10-18 01:15:14 PDT
How does -webkit-box-shadow handles objects in objectBoundingBox mode? Will it scale with increasing the Object size (SVG's can scale width the window-size)?  Or will be a shadow with 3 CSS px radius allways be 3px width, independet of the current size of the object or SVG?
Comment 7 Nikolas Zimmermann 2009-10-18 14:06:39 PDT
I am a bit worried about this patch as it is. I share Dirks opinion that it's duplicating functionality, but I see how it could be useful. Though there need to be way more testcases seeing how it interacts with vital SVG components (masking, clipping, filters, animations, use) etc..

This may take longer than writing the code, I'm aware of that, but we need to be share we don't create problems.
Comment 8 Beth Dakin 2009-10-19 11:52:05 PDT
Dirk, the main reason we wanted to implement a CSS shortcut for this is that we have a feature request for shadows in SVG and the fastest way we could deliver this to them is with this CSS property. We figure filters will take a lot longer to deliver as a solution since it seems it will take a lot of engineering to make them fast. The filters for drop shadow in Firefox right now are pretty chunky, and we assume we'd have the same problem.

Niko, I agree this needs more test cases, but I don't think we need to worry about this patch. It is adding new  opt-in functionality so no existing content will regress. It is common when we add new CSS features that we find refinement-style bugs after the initial implementation is checked in and people start playing with the property.
Comment 9 Dirk Schulze 2009-10-19 12:21:47 PDT
(In reply to comment #8)
> Dirk, the main reason we wanted to implement a CSS shortcut for this is that we
> have a feature request for shadows in SVG and the fastest way we could deliver
> this to them is with this CSS property. We figure filters will take a lot
> longer to deliver as a solution since it seems it will take a lot of
> engineering to make them fast. The filters for drop shadow in Firefox right now
> are pretty chunky, and we assume we'd have the same problem.
> 
> Niko, I agree this needs more test cases, but I don't think we need to worry
> about this patch. It is adding new  opt-in functionality so no existing content
> will regress. It is common when we add new CSS features that we find
> refinement-style bugs after the initial implementation is checked in and people
> start playing with the property.

To add CSS shadows to SVG sounds reasonable to me too now. But I still think that we should take care about some points. Shadows shouldn't be allowed on some SVG elements like mask, clip, clipPath, filter, fe* (maybe as well on the filtered object) and possibly some more. It should work on userSpaceOnUse and objectBoundingBox.

I agree that we won't find all possible problems on implementing a new feature, but it's neccessary to make sure that they won't cause problems on the obvious places. Some simple test cases might be enough.
Comment 10 Beth Dakin 2009-10-19 12:28:42 PDT
Sounds good. I will work on some test cases and post a new patch.
Comment 11 Eric Seidel (no email) 2009-10-19 12:29:51 PDT
I like the idea.  I think it's scary.  And I worry how it will interact with other parts of SVG. :(  I will need to look closer.

So how does this work? Does it work for text elements?  Any arbitrary path?  Does it shadow filtered content?  When is the shadow applied, before or after filtering/masking/clipping?  Likely we're going to need more testing... (which it sounds like Beth is working on).

Neat idea regardless.
Comment 12 Beth Dakin 2009-10-19 12:32:48 PDT
Eric, if you take a look at the patch, you will see it is very simple. Most of the patch is just setting up the CSS property. The part that actually makes it work is just two lined in SVGRenderSupport.cpp. That is literally the only place that we do anything to affect the rendering right now.
Comment 13 Eric Seidel (no email) 2009-10-19 12:38:19 PDT
Crazy what CG gives you for free. :)

 97     if (ShadowData* shadow = svgStyle->shadow())
 98         paintInfo.context->setShadow(IntSize(shadow->x, shadow->y), shadow->blur, shadow->color);

I'll have to stare at it a bit to figure out exactly how the current code will interact with this and if those interactions are what we'd expect.  Thank your the pointer.  In my brief look at the patch before lunch I got a little lost.
Comment 14 Beth Dakin 2009-10-19 12:41:43 PDT
Haha, I know CG is great, and the patch is misleading because you need to do so much just to hook up the CSS side of the property. Anyway, thanks for taking a look. I appreciate your eyes on it because I am very new to the SVG thing. Let me know what you find!
Comment 15 Dirk Schulze 2009-10-19 12:43:59 PDT
(In reply to comment #13)
> Crazy what CG gives you for free. :)
> 
>  97     if (ShadowData* shadow = svgStyle->shadow())
>  98         paintInfo.context->setShadow(IntSize(shadow->x, shadow->y),
> shadow->blur, shadow->color);
> 
> I'll have to stare at it a bit to figure out exactly how the current code will
> interact with this and if those interactions are what we'd expect.  Thank your
> the pointer.  In my brief look at the patch before lunch I got a little lost.

Doesn't Skia do the same?
Comment 16 Dean Jackson 2009-10-20 12:10:24 PDT
I'll have a try at answering various questions.

Eric asked:
> Does it work for text elements?  Any arbitrary path? 

Yes, I believe it should apply.

> Does it shadow filtered content? 

Depends what you mean here. See below.

> When is the shadow applied, before or after filtering/masking/clipping?

I think it should come after fill and stroke, before clipping, masking and filters. 

However, someone asked if the shadow should be included when the object is used as a mask. I think the answer is yes, the same way filters are used.

This is not an issue for clip path, as that is geometry only.

Now, more tricky parts...

What should happen if you shadow a group? Should it act like opacity, where we conceptually render into an offscreen and then composite? I'm pretty sure CG doesn't do that for us (nor any other graphics library used by WebKit). I would like to think that the shadows should work that way though.

About scaling. If the shadow is 3px offset and the object is scaled by 2, then the shadow will appear 6px offset. This is the same as regular SVG transforms on stroke width, and CSS transforms.

How does this sound? I'm talking out of my rear for this because I haven't looked at the code implications in detail.
Comment 17 Eric Seidel (no email) 2009-10-20 12:14:25 PDT
I hope to look at the patch in more detail later today.  Dean's examples at least give us something to test.
Comment 18 Dirk Schulze 2009-10-20 12:38:58 PDT
(In reply to comment #16)
> What should happen if you shadow a group? Should it act like opacity, where we
> conceptually render into an offscreen and then composite? I'm pretty sure CG
> doesn't do that for us (nor any other graphics library used by WebKit). I would
> like to think that the shadows should work that way though.

I also think that WebKit should create a shadow of the group. Does CG render a shadow of a group, if it is placed in a new TransparencyLayer? It would also be possible to draw it into a new ImageBuffer like SVGMaskElement is doing it. But both ways might be expensive.
Comment 19 Beth Dakin 2009-10-20 16:33:18 PDT
Created attachment 41534 [details]
Patch with more tests

Here's a patch with a bunch more tests. I believe I made a test to address each of the concerns that has been expressed.
Comment 20 Beth Dakin 2009-10-22 16:08:14 PDT
Created attachment 41691 [details]
Patch after talking with Dan

Dan and I went over the patch in person, and he caught a few things. Namely, this patch deals with the OwnPtr for the ShadowData much more effectively, and it expressly forbids -webkit-shadow from specifying multiple shadows.
Comment 21 Beth Dakin 2009-10-22 16:36:13 PDT
Committed with r49959.
Comment 22 Eric Seidel (no email) 2009-10-22 16:45:06 PDT
Thank you Dan.

Turns out my (very belated) review submission conflicted with yours, but here are my comments anyway:

Looks like you moved valueForShadow, not sure why.

 70     PassRefPtr<CSSValue> valueForShadow(const ShadowData*, int) const;
int probably needs an arg name.


SVG DocTypes are deprecated these days:
 2 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">

Bunch of extra newlines in:
svg/css/circle-in-mask-with-shadow.svg

I really need to fix bug 29506 so that we could see your images during review. :(

Looks fine to me too.  Thanks for doing this.
Comment 23 Beth Dakin 2009-10-22 16:49:38 PDT
I moved valueForShadow to make it a member function so it could be used within CSSComputerStyleDeclaration and sub-class SVGCSSComputedStyleDeclaration.

Good to know about the DocTypes.

Thanks Eric!
Comment 24 Eric Seidel (no email) 2009-10-22 16:51:48 PDT
http://jwatt.org/svg/authoring/ has more infos re: the doctypes if you're curious.