summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/shapes/RasterShape.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/rendering/shapes/RasterShape.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/rendering/shapes/RasterShape.cpp')
-rw-r--r--Source/WebCore/rendering/shapes/RasterShape.cpp254
1 files changed, 50 insertions, 204 deletions
diff --git a/Source/WebCore/rendering/shapes/RasterShape.cpp b/Source/WebCore/rendering/shapes/RasterShape.cpp
index e6a30e98d..d8aff98bc 100644
--- a/Source/WebCore/rendering/shapes/RasterShape.cpp
+++ b/Source/WebCore/rendering/shapes/RasterShape.cpp
@@ -12,7 +12,7 @@
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@@ -73,195 +73,61 @@ IntShapeInterval MarginIntervalGenerator::intervalAt(int y) const
return IntShapeInterval(m_x1 - dx, m_x2 + dx);
}
-void RasterShapeIntervals::appendInterval(int y, int x1, int x2)
-{
- ASSERT(x2 > x1 && (intervalsAt(y).isEmpty() || x1 > intervalsAt(y).last().x2()));
- m_bounds.unite(IntRect(x1, y, x2 - x1, 1));
- intervalsAt(y).append(IntShapeInterval(x1, x2));
-}
-
-void RasterShapeIntervals::uniteMarginInterval(int y, const IntShapeInterval& interval)
-{
- ASSERT(intervalsAt(y).size() <= 1); // Each m_intervalLists entry has 0 or one interval.
-
- if (intervalsAt(y).isEmpty())
- intervalsAt(y).append(interval);
- else {
- IntShapeInterval& resultInterval = intervalsAt(y)[0];
- resultInterval.set(std::min(resultInterval.x1(), interval.x1()), std::max(resultInterval.x2(), interval.x2()));
- }
-
- m_bounds.unite(IntRect(interval.x1(), y, interval.width(), 1));
-}
-
-static inline bool shapeIntervalsContain(const IntShapeIntervals& intervals, const IntShapeInterval& interval)
-{
- for (unsigned i = 0; i < intervals.size(); i++) {
- if (intervals[i].x1() > interval.x2())
- return false;
- if (intervals[i].contains(interval))
- return true;
- }
-
- return false;
-}
-
-bool RasterShapeIntervals::contains(const IntRect& rect) const
-{
- if (!bounds().contains(rect))
- return false;
-
- const IntShapeInterval& rectInterval = IntShapeInterval(rect.x(), rect.maxX());
- for (int y = rect.y(); y < rect.maxY(); y++) {
- if (!shapeIntervalsContain(intervalsAt(y), rectInterval))
- return false;
- }
-
- return true;
-}
-
-static inline void appendX1Values(const IntShapeIntervals& intervals, int minIntervalWidth, Vector<int>& result)
-{
- for (unsigned i = 0; i < intervals.size(); i++)
- if (intervals[i].width() >= minIntervalWidth)
- result.append(intervals[i].x1());
-}
-
-bool RasterShapeIntervals::getIntervalX1Values(int y1, int y2, int minIntervalWidth, Vector<int>& result) const
-{
- ASSERT(y1 >= 0 && y2 > y1);
-
- for (int y = y1; y < y2; y++) {
- if (intervalsAt(y).isEmpty())
- return false;
- }
-
- appendX1Values(intervalsAt(y1), minIntervalWidth, result);
- for (int y = y1 + 1; y < y2; y++) {
- if (intervalsAt(y) != intervalsAt(y - 1))
- appendX1Values(intervalsAt(y), minIntervalWidth, result);
- }
-
- return true;
-}
-
-bool RasterShapeIntervals::firstIncludedIntervalY(int minY, const IntSize& minSize, LayoutUnit& result) const
-{
- minY = std::max<int>(bounds().y(), minY);
-
- ASSERT(minY >= 0 && minY < size());
-
- if (minSize.isEmpty() || minSize.width() > bounds().width())
- return false;
-
- for (int lineY = minY; lineY <= bounds().maxY() - minSize.height(); lineY++) {
- Vector<int> intervalX1Values;
- if (!getIntervalX1Values(lineY, lineY + minSize.height(), minSize.width(), intervalX1Values))
- continue;
-
- std::sort(intervalX1Values.begin(), intervalX1Values.end());
-
- IntRect firstFitRect(IntPoint(0, 0), minSize);
- for (unsigned i = 0; i < intervalX1Values.size(); i++) {
- int lineX = intervalX1Values[i];
- if (i > 0 && lineX == intervalX1Values[i - 1])
- continue;
- firstFitRect.setLocation(IntPoint(lineX, lineY));
- if (contains(firstFitRect)) {
- result = lineY;
- return true;
- }
- }
- }
-
- return false;
-}
-
-void RasterShapeIntervals::getIncludedIntervals(int y1, int y2, IntShapeIntervals& result) const
-{
- ASSERT(y2 >= y1);
-
- if (y1 < bounds().y() || y2 > bounds().maxY())
- return;
-
- for (int y = y1; y < y2; y++) {
- if (intervalsAt(y).isEmpty())
- return;
- }
-
- result = intervalsAt(y1);
- for (int y = y1 + 1; y < y2 && !result.isEmpty(); y++) {
- IntShapeIntervals intervals;
- IntShapeInterval::intersectShapeIntervals(result, intervalsAt(y), intervals);
- result.swap(intervals);
- }
-}
-
-void RasterShapeIntervals::getExcludedIntervals(int y1, int y2, IntShapeIntervals& result) const
-{
- ASSERT(y2 >= y1);
-
- if (y2 < bounds().y() || y1 >= bounds().maxY())
- return;
-
- y1 = std::max(y1, bounds().y());
- y2 = std::min(y2, bounds().maxY());
-
- result = intervalsAt(y1);
- for (int y = y1 + 1; y < y2; y++) {
- IntShapeIntervals intervals;
- IntShapeInterval::uniteShapeIntervals(result, intervalsAt(y), intervals);
- result.swap(intervals);
- }
-}
-
-// Currently limited to computing the margin boundary for shape-outside for floats, see https://bugs.webkit.org/show_bug.cgi?id=116348.
-
-PassOwnPtr<RasterShapeIntervals> RasterShapeIntervals::computeShapeMarginIntervals(unsigned shapeMargin) const
+std::unique_ptr<RasterShapeIntervals> RasterShapeIntervals::computeShapeMarginIntervals(int shapeMargin) const
{
- OwnPtr<RasterShapeIntervals> result = adoptPtr(new RasterShapeIntervals(size(), shapeMargin));
+ int marginIntervalsSize = (offset() > shapeMargin) ? size() : size() - offset() * 2 + shapeMargin * 2;
+ auto result = std::make_unique<RasterShapeIntervals>(marginIntervalsSize, std::max(shapeMargin, offset()));
MarginIntervalGenerator marginIntervalGenerator(shapeMargin);
- int minY = bounds().y();
- int maxY = bounds().maxY();
-
- for (int y = minY; y < maxY; ++y) {
- const IntShapeInterval& intervalAtY = limitIntervalAt(y);
+ for (int y = bounds().y(); y < bounds().maxY(); ++y) {
+ const IntShapeInterval& intervalAtY = intervalAt(y);
if (intervalAtY.isEmpty())
continue;
marginIntervalGenerator.set(y, intervalAtY);
- int marginY0 = y - clampToInteger(shapeMargin);
- int marginY1 = y + clampToInteger(shapeMargin);
+ int marginY0 = std::max(minY(), y - shapeMargin);
+ int marginY1 = std::min(maxY(), y + shapeMargin + 1);
for (int marginY = y - 1; marginY >= marginY0; --marginY) {
- if (marginY > minY && limitIntervalAt(marginY).contains(intervalAtY))
+ if (marginY > bounds().y() && intervalAt(marginY).contains(intervalAtY))
break;
- result->uniteMarginInterval(marginY, marginIntervalGenerator.intervalAt(marginY));
+ result->intervalAt(marginY).unite(marginIntervalGenerator.intervalAt(marginY));
}
- result->uniteMarginInterval(y, marginIntervalGenerator.intervalAt(y));
+ result->intervalAt(y).unite(marginIntervalGenerator.intervalAt(y));
- for (int marginY = y + 1; marginY <= marginY1; ++marginY) {
- if (marginY < maxY && limitIntervalAt(marginY).contains(intervalAtY))
+ for (int marginY = y + 1; marginY < marginY1; ++marginY) {
+ if (marginY < bounds().maxY() && intervalAt(marginY).contains(intervalAtY))
break;
- result->uniteMarginInterval(marginY, marginIntervalGenerator.intervalAt(marginY));
+ result->intervalAt(marginY).unite(marginIntervalGenerator.intervalAt(marginY));
}
}
- return result.release();
+ result->initializeBounds();
+ return result;
+}
+
+void RasterShapeIntervals::initializeBounds()
+{
+ m_bounds = IntRect();
+ for (int y = minY(); y < maxY(); ++y) {
+ const IntShapeInterval& intervalAtY = intervalAt(y);
+ if (intervalAtY.isEmpty())
+ continue;
+ m_bounds.unite(IntRect(intervalAtY.x1(), y, intervalAtY.width(), 1));
+ }
}
void RasterShapeIntervals::buildBoundsPath(Path& path) const
{
for (int y = bounds().y(); y < bounds().maxY(); y++) {
- if (intervalsAt(y).isEmpty())
+ if (intervalAt(y).isEmpty())
continue;
- IntShapeInterval extent = limitIntervalAt(y);
+ IntShapeInterval extent = intervalAt(y);
int endY = y + 1;
for (; endY < bounds().maxY(); endY++) {
- if (intervalsAt(endY).isEmpty() || limitIntervalAt(endY) != extent)
+ if (intervalAt(endY).isEmpty() || intervalAt(endY) != extent)
break;
}
path.addRect(FloatRect(extent.x1(), y, extent.width(), endY - y));
@@ -275,58 +141,38 @@ const RasterShapeIntervals& RasterShape::marginIntervals() const
if (!shapeMargin())
return *m_intervals;
- unsigned marginBoundaryRadius = std::min(clampToUnsigned(ceil(shapeMargin())), std::max<unsigned>(m_imageSize.width(), m_imageSize.height()));
+ int shapeMarginInt = clampToPositiveInteger(ceil(shapeMargin()));
+ int maxShapeMarginInt = std::max(m_marginRectSize.width(), m_marginRectSize.height()) * sqrt(2);
if (!m_marginIntervals)
- m_marginIntervals = m_intervals->computeShapeMarginIntervals(marginBoundaryRadius);
+ m_marginIntervals = m_intervals->computeShapeMarginIntervals(std::min(shapeMarginInt, maxShapeMarginInt));
return *m_marginIntervals;
}
-const RasterShapeIntervals& RasterShape::paddingIntervals() const
-{
- ASSERT(shapePadding() >= 0);
- if (!shapePadding())
- return *m_intervals;
-
- // FIXME: Add support for non-zero padding, see https://bugs.webkit.org/show_bug.cgi?id=116348.
- return *m_intervals;
-}
-
-static inline void appendLineSegments(const IntShapeIntervals& intervals, SegmentList& result)
-{
- for (unsigned i = 0; i < intervals.size(); i++)
- result.append(LineSegment(intervals[i].x1(), intervals[i].x2() + 1));
-}
-
-void RasterShape::getExcludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList& result) const
+LineSegment RasterShape::getExcludedInterval(LayoutUnit logicalTop, LayoutUnit logicalHeight) const
{
const RasterShapeIntervals& intervals = marginIntervals();
if (intervals.isEmpty())
- return;
+ return LineSegment();
- IntShapeIntervals excludedIntervals;
- intervals.getExcludedIntervals(logicalTop, logicalTop + logicalHeight, excludedIntervals);
- appendLineSegments(excludedIntervals, result);
-}
+ int y1 = logicalTop;
+ int y2 = logicalTop + logicalHeight;
+ ASSERT(y2 >= y1);
+ if (y2 < intervals.bounds().y() || y1 >= intervals.bounds().maxY())
+ return LineSegment();
-void RasterShape::getIncludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList& result) const
-{
- const RasterShapeIntervals& intervals = paddingIntervals();
- if (intervals.isEmpty())
- return;
+ y1 = std::max(y1, intervals.bounds().y());
+ y2 = std::min(y2, intervals.bounds().maxY());
+ IntShapeInterval excludedInterval;
- IntShapeIntervals includedIntervals;
- intervals.getIncludedIntervals(logicalTop, logicalTop + logicalHeight, includedIntervals);
- appendLineSegments(includedIntervals, result);
-}
-
-bool RasterShape::firstIncludedIntervalLogicalTop(LayoutUnit minLogicalIntervalTop, const FloatSize& minLogicalIntervalSize, LayoutUnit& result) const
-{
- const RasterShapeIntervals& intervals = paddingIntervals();
- if (intervals.isEmpty())
- return false;
+ if (y1 == y2)
+ excludedInterval = intervals.intervalAt(y1);
+ else {
+ for (int y = y1; y < y2; y++)
+ excludedInterval.unite(intervals.intervalAt(y));
+ }
- return intervals.firstIncludedIntervalY(minLogicalIntervalTop.floor(), flooredIntSize(minLogicalIntervalSize), result);
+ return LineSegment(excludedInterval.x1(), excludedInterval.x2());
}
} // namespace WebCore