I would lean towards using the stroke bounds for both. Those being the "real" bounds, and resulting in less mis-aligned gradients. Always calculate the stroke bounds as if the shape will be stroked, so it doesn't affect Canvas. If you don't want that to affect the bounds used for a gradient fill when you aren't stroking, set the stoke width to 0.
Scott > On Nov 18, 2013, at 5:58 PM, Jim Graham <james.gra...@oracle.com> wrote: > > Felipe mentioned recently that we encountered some issues in fixing a bug > with SVGPath. > > The outcome of this fix could be a significant change in how your > proportional gradient fills look and so we'd like to get feedback on the > various ideas. You can read about them in that Jira issue, but I'll also > summarize below. Discussion would probably be better on the mailing list, > but we eventually need to work the salient points back into the Jira issue > for future maintenance. > > The basic issue is that we had a disagreement between the way that the shape > caching code worked and the way that uncached shapes were filled with > proportional paints. > > First, there is the concept of tight and loose bounds. Loose bounds are very > cheap to calculate, but can contain area not strictly inside the shape. > Tight bounds are more careful to figure out exactly how far curved sections > of the shape reach, but a fair number of calculations and recursions are > needed to accurately calculate those extents. > > Our current code will use loose bounds of the basic shape (i.e. the part that > is filled) to calculate the bounds for proportional paints when you first > paint a shape - whether you stroke it, fill it, or both. > > But, if you ran with shape mask caching (the default mode) then after a > rendering or 2 we would decide to cache the antialias coverage mask and we > would then use the node's content bounds to figure the bounds for the > proportional paint. The content bounds are calculated more precisely as > tight bounds, though, so they didn't always agree with the bounds used in > those first few uncached renderings. > > The net result is that the proportional paint would shift after the first > couple of frames unless you animated the shape and then it would revert while > you were animating and then shift back when it was stable. > > There is also the Canvas object that can also render proportional paints, and > it does so using the same code that the shape nodes use when they don't have > their coverage mask cached (i.e. loose fill bounds). > > We'd like to make all of this as consistent as possible. Here are the > various decisions and how they'd impact code: > > - Loose bounds are faster to calculate for shapes that aren't likely to be > reused. The uncached shape rendering used them because the shapes may change > before we need the bounds again. Canvas uses it because it is an immediate > mode API with no input on how often it may see a particular shape again. > > - Tight bounds would likely be less suprising to developers and users, > though. They are better for hit testing and damage management because they > generate fewer false positive hits. They are also fairly fast to calculate > for most shapes and it is a rare shape that we'd have to recurse much to get > it right. Also, for straight edges there is no difference in performance to > calculate tight or loose bounds. > > All in all, it would probably be better for the FX API to standardize on > tight bounds and treat any cases where we noticeably affect performance > (which should be very rare) as opportunities for tuning. This may not be > compatible with the first rendering of current Shape nodes, but they would > shift back and forth anyway so we aren't worried about incompatibility with > an inconsistent system. > > The other part of the decision is which bounds to use. > > Currently uncached rendering uses fill bounds, and mask-cached rendering uses > the content bounds which depends on whether you supply a stroke or a fill > paint so it could be either fill bounds or stroke bounds. > > - For filled-only shapes we obviously want to use the "fill bounds". > > - For stroked and filled shapes, we have 3 choices: > > - - use fill bounds for both paints so that the geometry used for > proportional stroke and fill paints are similar for both parts of those > nodes. This helps line up any color discontinuities or highlights between > the two. > > - - use stroke bounds for both which also means the two are consistent, but > Canvas can't really do this because it doesn't know if you are filling and > stroking until it sees the latter operation > > - - use fill bounds for fill and stroke bounds for stroke which means the > geometries of the two are different and it makes it harder to line up the > transitions of proportional stroke+fill shapes, but Canvas can do this so > Canvas vs. Shape node remain consistent > > I'm not sure which of the above is the best, but I lean towards "fill bounds > for both" because it allows consistent geometry for stroke+fill and it allows > consistent behavior between Canvas and Shape node, at the possible expense of > "0% on a stroke isn't at the edge of the stroke". > > Thoughts? > > ...jim