Changeset 154349 in webkit


Ignore:
Timestamp:
Aug 20, 2013 12:21:36 PM (11 years ago)
Author:
hmuller@adobe.com
Message:

<https://webkit.org/b/119849> [CSS Shapes] Complete RasterShape::firstIncludedIntervalLogicalTop()

Reviewed by Alexandru Chiculita.

Source/WebCore:

Completed the implementation of RasterShape::firstIncludedIntervalLogicalTop(). The
method now computes first logical top location where a line segment can be laid
out within a RasterShape, i.e. a shape derived from an image valued URL resource.

A detailed description of the algorithm can be found in
http://hansmuller-webkit.blogspot.com/2013/08/first-fit-location-for-image-shapes.html.

The new tests exposed a bug in the existing getIncludedIntervals() method. A shape
with a vertical gap that spans the entire line now causes the method to short circuit
and return an empty interval list.

Tests: fast/shapes/shape-inside/shape-inside-image-003.html

fast/shapes/shape-inside/shape-inside-image-004.html
fast/shapes/shape-inside/shape-inside-image-005.html

  • rendering/shapes/RasterShape.cpp:

(WebCore::RasterShapeIntervals::firstIncludedIntervalY):
(WebCore::RasterShapeIntervals::getIncludedIntervals):
(WebCore::RasterShape::firstIncludedIntervalLogicalTop):

  • rendering/shapes/RasterShape.h:

LayoutTests:

Verify that the first fit algorithm works correctly for complex image shapes.
For this set of tests the image is specified with an SVG file.

  • fast/shapes/resources/svg-shape-001.svg: Added.
  • fast/shapes/shape-inside/shape-inside-image-003-expected.html: Added.
  • fast/shapes/shape-inside/shape-inside-image-003.html: Added.
  • fast/shapes/shape-inside/shape-inside-image-004-expected.html: Added.
  • fast/shapes/shape-inside/shape-inside-image-004.html: Added.
  • fast/shapes/shape-inside/shape-inside-image-005-expected.html: Added.
  • fast/shapes/shape-inside/shape-inside-image-005.html: Added.
Location:
trunk
Files:
7 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r154346 r154349  
     12013-08-20  Hans Muller  <hmuller@adobe.com>
     2        <https://webkit.org/b/119849> [CSS Shapes] Complete RasterShape::firstIncludedIntervalLogicalTop()
     3
     4        Reviewed by Alexandru Chiculita.
     5
     6        Verify that the first fit algorithm works correctly for complex image shapes.
     7        For this set of tests the image is specified with an SVG file.
     8
     9        * fast/shapes/resources/svg-shape-001.svg: Added.
     10        * fast/shapes/shape-inside/shape-inside-image-003-expected.html: Added.
     11        * fast/shapes/shape-inside/shape-inside-image-003.html: Added.
     12        * fast/shapes/shape-inside/shape-inside-image-004-expected.html: Added.
     13        * fast/shapes/shape-inside/shape-inside-image-004.html: Added.
     14        * fast/shapes/shape-inside/shape-inside-image-005-expected.html: Added.
     15        * fast/shapes/shape-inside/shape-inside-image-005.html: Added.
     16
    1172013-08-20  Michael Saboff  <msaboff@apple.com>
    218
  • trunk/Source/WebCore/ChangeLog

    r154348 r154349  
     12013-08-20  Hans Muller  <hmuller@adobe.com>
     2
     3        <https://webkit.org/b/119849> [CSS Shapes] Complete RasterShape::firstIncludedIntervalLogicalTop()
     4
     5        Reviewed by Alexandru Chiculita.
     6
     7        Completed the implementation of RasterShape::firstIncludedIntervalLogicalTop(). The
     8        method now computes first logical top location where a line segment can be laid
     9        out within a RasterShape, i.e. a shape derived from an image valued URL resource.
     10
     11        A detailed description of the algorithm can be found in
     12        http://hansmuller-webkit.blogspot.com/2013/08/first-fit-location-for-image-shapes.html.
     13
     14        The new tests exposed a bug in the existing getIncludedIntervals() method. A shape
     15        with a vertical gap that spans the entire line now causes the method to short circuit
     16        and return an empty interval list.
     17
     18        Tests: fast/shapes/shape-inside/shape-inside-image-003.html
     19               fast/shapes/shape-inside/shape-inside-image-004.html
     20               fast/shapes/shape-inside/shape-inside-image-005.html
     21
     22        * rendering/shapes/RasterShape.cpp:
     23        (WebCore::RasterShapeIntervals::firstIncludedIntervalY):
     24        (WebCore::RasterShapeIntervals::getIncludedIntervals):
     25        (WebCore::RasterShape::firstIncludedIntervalLogicalTop):
     26        * rendering/shapes/RasterShape.h:
     27
    1282013-08-20  Pratik Solanki  <psolanki@apple.com>
    229
  • trunk/Source/WebCore/rendering/shapes/RasterShape.cpp

    r154152 r154349  
    4949}
    5050
     51bool RasterShapeIntervals::firstIncludedIntervalY(int minY, const IntSize& minSize, LayoutUnit& result) const
     52{
     53    for (int y = minY; y <= bounds().maxY() - minSize.height(); y++) {
     54        Region lineRegion(IntRect(bounds().x(), y, bounds().width(), minSize.height()));
     55        lineRegion.intersect(m_region);
     56        if (lineRegion.isEmpty())
     57            continue;
     58
     59        const Vector<IntRect>& lineRects = lineRegion.rects();
     60        ASSERT(lineRects.size() > 0);
     61
     62        for (unsigned i = 0; i < lineRects.size(); i++) {
     63            IntRect rect = lineRects[i];
     64            if (rect.width() >= minSize.width() && lineRegion.contains(Region(IntRect(IntPoint(rect.x(), y), minSize)))) {
     65                result = y;
     66                return true;
     67            }
     68        }
     69    }
     70    return false;
     71}
     72
    5173static inline IntRect alignedRect(IntRect r, int y1, int y2)
    5274{
     
    6486        return;
    6587
    66     Vector<IntRect> lineRects = lineRegion.rects();
     88    const Vector<IntRect>& lineRects = lineRegion.rects();
    6789    ASSERT(lineRects.size() > 0);
    6890
     
    7294    // The loop below uses Regions to compute the intersection of the horizontal
    7395    // shape intervals that fall within the line's box.
    74     int lineY = lineRects[0].y();
     96    int currentLineY = lineRects[0].y();
     97    int currentLineMaxY = lineRects[0].maxY();
    7598    for (unsigned i = 0; i < lineRects.size(); ++i) {
    76         if (lineRects[i].y() != lineY) {
     99        int lineY = lineRects[i].y();
     100        ASSERT(lineY >= currentLineY);
     101        if (lineY > currentLineMaxY) {
     102            // We've encountered a vertical gap in lineRects, there are no included intervals.
     103            return;
     104        }
     105        if (lineY > currentLineY) {
     106            currentLineY = lineY;
     107            currentLineMaxY = lineRects[i].maxY();
    77108            segmentsRegion.intersect(intervalsRegion);
    78109            intervalsRegion = Region();
    79         }
     110        } else
     111            currentLineMaxY = std::max<int>(currentLineMaxY, lineRects[i].maxY());
    80112        intervalsRegion.unite(Region(alignedRect(lineRects[i], y1, y2)));
    81         lineY = lineRects[i].y();
    82113    }
    83114    if (!intervalsRegion.isEmpty())
    84115        segmentsRegion.intersect(intervalsRegion);
    85116
    86     Vector<IntRect> segmentRects = segmentsRegion.rects();
     117    const Vector<IntRect>& segmentRects = segmentsRegion.rects();
    87118    for (unsigned i = 0; i < segmentRects.size(); ++i)
    88119        result.append(LineSegment(segmentRects[i].x(), segmentRects[i].maxX()));
     
    99130        return;
    100131
    101     Vector<IntRect> lineRects = lineRegion.rects();
     132    const Vector<IntRect>& lineRects = lineRegion.rects();
    102133    ASSERT(lineRects.size() > 0);
    103134
     
    106137        segmentsRegion.unite(Region(alignedRect(lineRects[i], y1, y2)));
    107138
    108     Vector<IntRect> segmentRects = segmentsRegion.rects();
     139    const Vector<IntRect>& segmentRects = segmentsRegion.rects();
    109140    for (unsigned i = 0; i < segmentRects.size(); i++)
    110141        result.append(LineSegment(segmentRects[i].x(), segmentRects[i].maxX() + 1));
     
    173204    float minY = std::max<float>(intervals.bounds().y(), minIntervalTop);
    174205    float maxY = minY + minIntervalHeight;
    175 
    176206    if (maxY > intervals.bounds().maxY())
    177207        return false;
    178208
    179     // FIXME: Complete this method, see https://bugs.webkit.org/show_bug.cgi?id=116348.
    180     result = minY;
    181     return true;
     209    return intervals.firstIncludedIntervalY(minY, flooredIntSize(minLogicalIntervalSize), result);
    182210}
    183211
  • trunk/Source/WebCore/rendering/shapes/RasterShape.h

    r154152 r154349  
    4848    void getIncludedIntervals(int y1, int y2, SegmentList&) const;
    4949    void getExcludedIntervals(int y1, int y2, SegmentList&) const;
     50    bool firstIncludedIntervalY(int minY, const IntSize& minIntervalSize, LayoutUnit&) const;
    5051
    5152private:
Note: See TracChangeset for help on using the changeset viewer.