RESOLVED FIXED Bug 95625
[CSS Exclusions] add support for a subset of the basic shapes
https://bugs.webkit.org/show_bug.cgi?id=95625
Summary [CSS Exclusions] add support for a subset of the basic shapes
Hans Muller
Reported 2012-08-31 16:52:17 PDT
Initial support for computing line layout within a subset of the shapes listed in the "Basic Shapes" section of the CSS Exclusions spec - http://dev.w3.org/csswg/css3-exclusions/#basic-shapes-from-svg-syntax. To keep the patch smaller and simpler, the support for polygons has been temporarily removed and I've only gone as far as replacing the stub in WrapShapeInfo::computeSegmentsForLine() with a call - XShape::getInsideIntervals() - to the new shape class. Subsequent patches will add tests for circle, ellipse, and rounded rectangle exclusions, and restore the support for XShape polygons, along with appropriate tests.
Attachments
Patch (39.90 KB, patch)
2012-08-31 16:52 PDT, Hans Muller
no flags
Patch (40.28 KB, patch)
2012-09-01 09:39 PDT, Hans Muller
hyatt: review-
Patch (42.39 KB, patch)
2012-09-05 18:45 PDT, Hans Muller
no flags
Patch (42.67 KB, patch)
2012-09-05 21:24 PDT, Hans Muller
hyatt: review-
One shape-outside exclusion shape overlaps elements with different writing-modes. (65.03 KB, image/png)
2012-09-06 11:16 PDT, Hans Muller
no flags
Patch (43.13 KB, patch)
2012-09-07 22:10 PDT, Hans Muller
no flags
Hans Muller
Comment 1 2012-08-31 16:52:46 PDT
Hans Muller
Comment 2 2012-08-31 16:53:19 PDT
*** Bug 95490 has been marked as a duplicate of this bug. ***
WebKit Review Bot
Comment 3 2012-08-31 16:54:52 PDT
Attachment 161791 [details] did not pass style-queue: Failed to run "['Tools/Scripts/check-webkit-style', '--diff-files', u'Source/WebCore/CMakeLists.txt', u'Source/W..." exit_code: 1 Source/WebCore/rendering/WrapShapeInfo.cpp:123: One space before end of line comments [whitespace/comments] [5] Total errors found: 1 in 15 files If any of these errors are false positives, please file a bug against check-webkit-style.
Hans Muller
Comment 4 2012-09-01 09:39:08 PDT
Created attachment 161830 [details] Patch Removed the extra space check-webkit-style was complaining about.
Dave Hyatt
Comment 5 2012-09-05 12:22:21 PDT
Comment on attachment 161830 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=161830&action=review Overall I'm left scratching my head here regarding the mixture of physical and logical terminology. Your platform/graphics additions seem to be using largely physical terminology, but then everything you're doing with them over in the rendering code is in terms of logical coordinates (i.e., line top and line bottom are x values in vertical writing-modes, but you're happily passing those values in to your XShape code, which then calls them "y"). I think you need to have a clear design intent here. Either the shapes are physical, in which case you need to be doing a translation at the WrapShapeInfo level, or the shapes themselves are logical, in which case I don't think you should be using x and y terminology in their implementations. I'm also wondering what the reasoning is behind putting all of the classes into platform/graphics. Especially if they end up being logical, I'm not sure there is any reason to have them over there instead of just putting them in the rendering directory. > Source/WebCore/ChangeLog:8 > + Initial commit of a subset of the Xhapes classes. Typo, should be XShapes. > Source/WebCore/ChangeLog:10 > + This set of classes enables the exclusions layout code to determine how to break up a line into segements Typo, segements should be segments. > Source/WebCore/ChangeLog:11 > + that will fit within or around a shape, given the Y coordinates of the line's top edge and bottom edges. Do you mean logical top rather than Y? > Source/WebCore/platform/graphics/XSRectangle.h:39 > +class XSRectangle : public XShape { I think a comment above this class declaration describing what it represents might be helpful here. > Source/WebCore/platform/graphics/XSRectangle.h:54 > + virtual FloatRect shapeBoundingBox() const { return FloatRect(m_x, m_y, m_width, m_height); } > + virtual void getOutsideIntervals(float y1, float y2, Vector<XSInterval>&) const; > + virtual void getInsideIntervals(float y1, float y2, Vector<XSInterval>&) const; You're missing OVERRIDEs on these three functions > Source/WebCore/platform/graphics/XSRectangle.h:62 > + float m_rx; > + float m_ry; I would add a comment here explaining what these are. A person who isn't familiar with this code will see x,y,width,height and understand those, but may be left scratching their head wondering what m_rx and m_ry are here. > Source/WebCore/platform/graphics/XShape.h:43 > + static PassOwnPtr<XShape> createXShape(const BasicShape*, float borderBoxWidth, float borderBoxHeight); borderBoxWidth and borderBoxHeight are physical terminology. Is this physical or logical? I'm confused about this. > Source/WebCore/rendering/WrapShapeInfo.cpp:110 > + m_xshape = XShape::createXShape(shape, logicalWidth, logicalHeight); Here you're passing in logical values to a function whose (see my comment above) arguments had physical names. Which is correct? > Source/WebCore/rendering/WrapShapeInfo.h:70 > + LayoutUnit shapeTop() const Is this logical or physical? If it's supposed to be a value that is compared with a line top or bottom, then this should be renamed to shapeLogicalTop(). > Source/WebCore/rendering/WrapShapeInfo.h:103 > + FloatRect shapeBounds = m_xshape->shapeBoundingBox(); This appears to be logical. Is that the intent?
Dave Hyatt
Comment 6 2012-09-05 12:38:48 PDT
Oh, I mentioned this on IRC, but I would just put the XShape classes in rendering/ and rename them to ExclusionShape, ExclusionRectangle, etc. I don't think these classes are going to end up being anything generically reusable, so they should just be closer to the Exclusion implementation. Is there any particular reason why WrapShape info isn't just called ExclusionShapeInfo?
Alan Stearns
Comment 7 2012-09-05 12:56:04 PDT
(In reply to comment #6) Dave, The intent is to use Shapes both with exclusions and with floats (and eventually with masks or anything else that needs a shape). Do you have any suggestions on how to make these classes generically reusable?
Hans Muller
Comment 8 2012-09-05 18:45:04 PDT
Created attachment 162390 [details] Patch Just the XS => ExclusionShape relocation/rename. Moved the classes from platform/graphics to rendering and renamed the classes: XSInterval => ExclusionInterval XSRectangle = >ExclusionRectangle XSShape => ExclusionShape This patch is just to shakeout rename related build problems on the EWS bots.
WebKit Review Bot
Comment 9 2012-09-05 18:46:48 PDT
Attachment 162390 [details] did not pass style-queue: Failed to run "['Tools/Scripts/check-webkit-style', '--diff-files', u'Source/WebCore/CMakeLists.txt', u'Source/W..." exit_code: 1 Source/WebCore/rendering/WrapShapeInfo.h:37: Alphabetical sorting problem. [build/include_order] [4] Total errors found: 1 in 15 files If any of these errors are false positives, please file a bug against check-webkit-style.
Hans Muller
Comment 10 2012-09-05 21:24:52 PDT
Created attachment 162408 [details] Patch Fixed the style-checker problem (alphabetized WrapInfo include files, and update the XCode project.
Hans Muller
Comment 11 2012-09-06 11:16:54 PDT
Created attachment 162542 [details] One shape-outside exclusion shape overlaps elements with different writing-modes.
Hans Muller
Comment 12 2012-09-06 11:24:16 PDT
(In reply to comment #5) > (From update of attachment 161830 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=161830&action=review > > Overall I'm left scratching my head here regarding the mixture of physical and logical terminology. Your platform/graphics additions seem to be using largely physical terminology, but then everything you're doing with them over in the rendering code is in terms of logical coordinates (i.e., line top and line bottom are x values in vertical writing-modes, but you're happily passing those values in to your XShape code, which then calls them "y"). Here's a proposal that I hope addresses the problem you've brought up. I think the ExclusionShape API should use logical coordinates for the incoming top/bottom line edges and similarly it should report line segments' start/stops with logical X coordinates. The incoming BasicShape, which is just an encoding of the CSS shape, is defined with physical coordinates. That means that createExclusionShape() method will need an additional parameter, so that it can transform the BasicShape's physical coordinates when the writing-mode is vertical. It also means that an ExclusionShape will be specific to a writing-mode, so in a shape-outside case like this: https://bug-95625-attachments.webkit.org/attachment.cgi?id=162542, two ExclusionShape objects will be used to compute the layouts. Internally, the ExclusionShapes classes (just ExclusionRectangle for the moment) do their computations as if the writing-mode was horizontal. I don't think this needs to change, although the ExclusionInterval class, which is used to report line segment endpoints, should use logical names for the X coordinates, start and end instead of x1 and x2. Here's what the ExclusionShape API would become: // A representation of a BasicShape that enables layout code to determine how to break a line up into segments // that will fit within or around a shape. The line is defined by a pair of logical Y coordinates and the // computed segments are returned as pairs of logical X coordinates (ExclusionIntervals). class ExclusionShape { public: static PassOwnPtr<ExclusionShape> createExclusionShape(const BasicShape*, float borderBoxWidth, float borderBoxHeight, WritingMode); virtual ~ExclusionShape() { } virtual LayouRect shapeBoundingBox() const = 0; virtual void getInsideIntervals(float logicalTop, float logicalBottom, Vector<ExclusionInterval>&) const = 0; virtual void getOutsideIntervals(float logicalTop, float logicalBottom, Vector<ExclusionInterval>&) const = 0; }; } // namespace WebCore The shapeBoundingBox() would return the logical bounds of the exclusion shape. I've changed the return type from FloatRect to LayoutRect. Currently the exclusion layout code only supports shape-inside (so an exclusion shape only affects one element's contents) and it explicitly ignores exclusions defined for vertical content (see WrapShapeInfo::isWrapShapeInfoEnabledForRenderBlock). If possible, I'd like to file a bug about the lack of writing-mode support in ExclusionShape, rather than making the changes now.
Hans Muller
Comment 13 2012-09-06 11:27:33 PDT
(In reply to comment #6) > Oh, I mentioned this on IRC, but I would just put the XShape classes in rendering/ and rename them to ExclusionShape, ExclusionRectangle, etc. I don't think these classes are going to end up being anything generically reusable, so they should just be closer to the Exclusion implementation. I have moved and renamed the XS classes. > Is there any particular reason why WrapShape info isn't just called ExclusionShapeInfo? The current name is (now) largely historical, and I'd be happy to change it. OK, if I file a separate bug for that?
Hans Muller
Comment 14 2012-09-06 11:33:44 PDT
(In reply to comment #5) > (From update of attachment 161830 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=161830&action=review > > Source/WebCore/ChangeLog:8 > > + Initial commit of a subset of the Xhapes classes. > > Typo, should be XShapes. > > > Source/WebCore/ChangeLog:10 > > + This set of classes enables the exclusions layout code to determine how to break up a line into segements > > Typo, segements should be segments. I have fixed these typos. > > Source/WebCore/platform/graphics/XSRectangle.h:54 > > + virtual FloatRect shapeBoundingBox() const { return FloatRect(m_x, m_y, m_width, m_height); } > > + virtual void getOutsideIntervals(float y1, float y2, Vector<XSInterval>&) const; > > + virtual void getInsideIntervals(float y1, float y2, Vector<XSInterval>&) const; > > You're missing OVERRIDEs on these three functions Added the OVERRIDES. > > > Source/WebCore/platform/graphics/XSRectangle.h:62 > > + float m_rx; > > + float m_ry; > > I would add a comment here explaining what these are. A person who isn't familiar with this code will see x,y,width,height and understand those, but may be left scratching their head wondering what m_rx and m_ry are here. Added comments.
Hans Muller
Comment 15 2012-09-06 11:38:13 PDT
(In reply to comment #5) > (From update of attachment 161830 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=161830&action=review If, per comment #10, it's OK to make the changes vis logical vs physical geometry in a separate bug fix, I'd like to address the following then: > Do you mean logical top rather than Y? > > > Source/WebCore/platform/graphics/XSRectangle.h:39 > > +class XSRectangle : public XShape { > > I think a comment above this class declaration describing what it represents might be helpful here. [I've proposed such a comment in #10. Since it depends on resolving logical vs physical geometry, I'd like to include with that TBD patch] > > Source/WebCore/platform/graphics/XShape.h:43 > > + static PassOwnPtr<XShape> createXShape(const BasicShape*, float borderBoxWidth, float borderBoxHeight); > > borderBoxWidth and borderBoxHeight are physical terminology. Is this physical or logical? I'm confused about this. > > > Source/WebCore/rendering/WrapShapeInfo.cpp:110 > > + m_xshape = XShape::createXShape(shape, logicalWidth, logicalHeight); > > Here you're passing in logical values to a function whose (see my comment above) arguments had physical names. Which is correct? > > > Source/WebCore/rendering/WrapShapeInfo.h:70 > > + LayoutUnit shapeTop() const > > Is this logical or physical? If it's supposed to be a value that is compared with a line top or bottom, then this should be renamed to shapeLogicalTop(). > > > Source/WebCore/rendering/WrapShapeInfo.h:103 > > + FloatRect shapeBounds = m_xshape->shapeBoundingBox(); > > This appears to be logical. Is that the intent?
Dave Hyatt
Comment 16 2012-09-07 15:33:09 PDT
Comment on attachment 162408 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=162408&action=review Looks pretty good. Just minor comments. > Source/WebCore/ChangeLog:499 > - * platform/graphics/harfbuzz/FontPlatformDataHarfBuzz.cpp: > + * rendering/harfbuzz/FontPlatformDataHarfBuzz.cpp: Not sure what this is about? I don't see this code in the patch. > Source/WebCore/ChangeLog:504 > - * platform/graphics/harfbuzz/FontPlatformDataHarfBuzz.h: > + * rendering/harfbuzz/FontPlatformDataHarfBuzz.h: Ditto. > Source/WebCore/rendering/ExclusionShape.h:43 > + static PassOwnPtr<ExclusionShape> createExclusionShape(const BasicShape*, float borderBoxWidth, float borderBoxHeight); Rename borderBoxWidth and borderBoxHeight to borderBoxLogicalWidth and borderBoxLogicalHeight, since right now at least, your shapes are clearly logical. > Source/WebCore/rendering/WrapShapeInfo.cpp:110 > + m_xshape = ExclusionShape::createExclusionShape(shape, logicalWidth, logicalHeight); I'd just drop the x here. At this point, inside this class, it's pretty obvious what we're dealing with, so I would just call this m_shape. > Source/WebCore/rendering/WrapShapeInfo.h:70 > + LayoutUnit shapeTop() const Rename this to shapeLogicalTop(), since right now at least, it's clearly logical. > Source/WebCore/rendering/WrapShapeInfo.h:103 > + FloatRect shapeBounds = m_xshape->shapeBoundingBox(); Let's call the local shapeLogicalBoundingBox to help clarify it is logical in nature.
Dave Hyatt
Comment 17 2012-09-07 15:35:37 PDT
One more comment: virtual void getInsideIntervals(float logicalTop, float logicalBottom, Vector<ExclusionInterval>&) const = 0; virtual void getOutsideIntervals(float logicalTop, float logicalBottom, Vector<ExclusionInterval>&) const = 0; You should go ahead and do those renames to logicalTop and logicalBottom in the headers at least, instead of still using y1 and y2.
Dave Hyatt
Comment 18 2012-09-07 15:36:06 PDT
I mean minY / maxY.
Hans Muller
Comment 19 2012-09-07 22:10:27 PDT
Created attachment 162938 [details] Patch I've made the suggested changes.
Hans Muller
Comment 20 2012-09-08 07:55:17 PDT
Comment on attachment 162938 [details] Patch I've created the following bugs per the additional work noted previously: ExclusionShape API should use logical coordinates for input/output - https://bugs.webkit.org/show_bug.cgi?id=96156 Rename WrapShapeInfo to ExclusionShapeInfo - https://bugs.webkit.org/show_bug.cgi?id=96157
Dave Hyatt
Comment 21 2012-09-10 10:56:42 PDT
Comment on attachment 162938 [details] Patch r=me
WebKit Review Bot
Comment 22 2012-09-10 11:24:13 PDT
Comment on attachment 162938 [details] Patch Clearing flags on attachment: 162938 Committed r128083: <http://trac.webkit.org/changeset/128083>
WebKit Review Bot
Comment 23 2012-09-10 11:24:18 PDT
All reviewed patches have been landed. Closing bug.
Note You need to log in before you can comment on or make changes to this bug.