| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. | 2 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above | 8 * 1. Redistributions of source code must retain the above |
| 9 * copyright notice, this list of conditions and the following | 9 * copyright notice, this list of conditions and the following |
| 10 * disclaimer. | 10 * disclaimer. |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 m_x2 = interval.x2(); | 66 m_x2 = interval.x2(); |
| 67 } | 67 } |
| 68 | 68 |
| 69 IntShapeInterval MarginIntervalGenerator::intervalAt(int y) const | 69 IntShapeInterval MarginIntervalGenerator::intervalAt(int y) const |
| 70 { | 70 { |
| 71 unsigned xInterceptsIndex = abs(y - m_y); | 71 unsigned xInterceptsIndex = abs(y - m_y); |
| 72 int dx = (xInterceptsIndex >= m_xIntercepts.size()) ? 0 : m_xIntercepts[xInt
erceptsIndex]; | 72 int dx = (xInterceptsIndex >= m_xIntercepts.size()) ? 0 : m_xIntercepts[xInt
erceptsIndex]; |
| 73 return IntShapeInterval(m_x1 - dx, m_x2 + dx); | 73 return IntShapeInterval(m_x1 - dx, m_x2 + dx); |
| 74 } | 74 } |
| 75 | 75 |
| 76 void RasterShapeIntervals::appendInterval(int y, int x1, int x2) | |
| 77 { | |
| 78 ASSERT(x2 > x1 && (intervalsAt(y).isEmpty() || x1 > intervalsAt(y).last().x2
())); | |
| 79 m_bounds.unite(IntRect(x1, y, x2 - x1, 1)); | |
| 80 intervalsAt(y).append(IntShapeInterval(x1, x2)); | |
| 81 } | |
| 82 | |
| 83 void RasterShapeIntervals::uniteMarginInterval(int y, const IntShapeInterval& in
terval) | |
| 84 { | |
| 85 ASSERT(intervalsAt(y).size() <= 1); // Each m_intervalLists entry has 0 or o
ne interval. | |
| 86 | |
| 87 if (intervalsAt(y).isEmpty()) { | |
| 88 intervalsAt(y).append(interval); | |
| 89 } else { | |
| 90 IntShapeInterval& resultInterval = intervalsAt(y)[0]; | |
| 91 resultInterval.set(std::min(resultInterval.x1(), interval.x1()), std::ma
x(resultInterval.x2(), interval.x2())); | |
| 92 } | |
| 93 | |
| 94 m_bounds.unite(IntRect(interval.x1(), y, interval.width(), 1)); | |
| 95 } | |
| 96 | |
| 97 static inline bool shapeIntervalsContain(const IntShapeIntervals& intervals, con
st IntShapeInterval& interval) | |
| 98 { | |
| 99 for (unsigned i = 0; i < intervals.size(); i++) { | |
| 100 if (intervals[i].x1() > interval.x2()) | |
| 101 return false; | |
| 102 if (intervals[i].contains(interval)) | |
| 103 return true; | |
| 104 } | |
| 105 | |
| 106 return false; | |
| 107 } | |
| 108 | |
| 109 bool RasterShapeIntervals::contains(const IntRect& rect) const | |
| 110 { | |
| 111 if (!bounds().contains(rect)) | |
| 112 return false; | |
| 113 | |
| 114 const IntShapeInterval& rectInterval = IntShapeInterval(rect.x(), rect.maxX(
)); | |
| 115 for (int y = rect.y(); y < rect.maxY(); y++) { | |
| 116 if (!shapeIntervalsContain(intervalsAt(y), rectInterval)) | |
| 117 return false; | |
| 118 } | |
| 119 | |
| 120 return true; | |
| 121 } | |
| 122 | |
| 123 static inline void appendX1Values(const IntShapeIntervals& intervals, int minInt
ervalWidth, Vector<int>& result) | |
| 124 { | |
| 125 for (unsigned i = 0; i < intervals.size(); i++) { | |
| 126 if (intervals[i].width() >= minIntervalWidth) | |
| 127 result.append(intervals[i].x1()); | |
| 128 } | |
| 129 } | |
| 130 | |
| 131 bool RasterShapeIntervals::getIntervalX1Values(int y1, int y2, int minIntervalWi
dth, Vector<int>& result) const | |
| 132 { | |
| 133 ASSERT(y1 >= 0 && y2 > y1); | |
| 134 | |
| 135 for (int y = y1; y < y2; y++) { | |
| 136 if (intervalsAt(y).isEmpty()) | |
| 137 return false; | |
| 138 } | |
| 139 | |
| 140 appendX1Values(intervalsAt(y1), minIntervalWidth, result); | |
| 141 for (int y = y1 + 1; y < y2; y++) { | |
| 142 if (intervalsAt(y) != intervalsAt(y - 1)) | |
| 143 appendX1Values(intervalsAt(y), minIntervalWidth, result); | |
| 144 } | |
| 145 | |
| 146 return true; | |
| 147 } | |
| 148 | |
| 149 void RasterShapeIntervals::getExcludedIntervals(int y1, int y2, IntShapeInterval
s& result) const | |
| 150 { | |
| 151 ASSERT(y2 >= y1); | |
| 152 | |
| 153 if (y2 < bounds().y() || y1 >= bounds().maxY()) | |
| 154 return; | |
| 155 | |
| 156 y1 = std::max(y1, bounds().y()); | |
| 157 y2 = std::min(y2, bounds().maxY()); | |
| 158 | |
| 159 result = intervalsAt(y1); | |
| 160 for (int y = y1 + 1; y < y2; y++) { | |
| 161 IntShapeIntervals intervals; | |
| 162 IntShapeInterval::uniteShapeIntervals(result, intervalsAt(y), intervals)
; | |
| 163 result.swap(intervals); | |
| 164 } | |
| 165 } | |
| 166 | |
| 167 PassOwnPtr<RasterShapeIntervals> RasterShapeIntervals::computeShapeMarginInterva
ls(int shapeMargin) const | 76 PassOwnPtr<RasterShapeIntervals> RasterShapeIntervals::computeShapeMarginInterva
ls(int shapeMargin) const |
| 168 { | 77 { |
| 169 int marginIntervalsSize = (offset() > shapeMargin) ? size() : size() - offse
t() * 2 + shapeMargin * 2; | 78 int marginIntervalsSize = (offset() > shapeMargin) ? size() : size() - offse
t() * 2 + shapeMargin * 2; |
| 170 OwnPtr<RasterShapeIntervals> result = adoptPtr(new RasterShapeIntervals(marg
inIntervalsSize, std::max(shapeMargin, offset()))); | 79 OwnPtr<RasterShapeIntervals> result = adoptPtr(new RasterShapeIntervals(marg
inIntervalsSize, std::max(shapeMargin, offset()))); |
| 171 MarginIntervalGenerator marginIntervalGenerator(shapeMargin); | 80 MarginIntervalGenerator marginIntervalGenerator(shapeMargin); |
| 172 | 81 |
| 173 for (int y = bounds().y(); y < bounds().maxY(); ++y) { | 82 for (int y = bounds().y(); y < bounds().maxY(); ++y) { |
| 174 const IntShapeInterval& intervalAtY = limitIntervalAt(y); | 83 const IntShapeInterval& intervalAtY = intervalAt(y); |
| 175 if (intervalAtY.isEmpty()) | 84 if (intervalAtY.isEmpty()) |
| 176 continue; | 85 continue; |
| 177 | 86 |
| 178 marginIntervalGenerator.set(y, intervalAtY); | 87 marginIntervalGenerator.set(y, intervalAtY); |
| 179 int marginY0 = std::max(minY(), y - shapeMargin); | 88 int marginY0 = std::max(minY(), y - shapeMargin); |
| 180 int marginY1 = std::min(maxY(), y + shapeMargin); | 89 int marginY1 = std::min(maxY(), y + shapeMargin); |
| 181 | 90 |
| 182 for (int marginY = y - 1; marginY >= marginY0; --marginY) { | 91 for (int marginY = y - 1; marginY >= marginY0; --marginY) { |
| 183 if (marginY > bounds().y() && limitIntervalAt(marginY).contains(inte
rvalAtY)) | 92 if (marginY > bounds().y() && intervalAt(marginY).contains(intervalA
tY)) |
| 184 break; | 93 break; |
| 185 result->uniteMarginInterval(marginY, marginIntervalGenerator.interva
lAt(marginY)); | 94 result->intervalAt(marginY).unite(marginIntervalGenerator.intervalAt
(marginY)); |
| 186 } | 95 } |
| 187 | 96 |
| 188 result->uniteMarginInterval(y, marginIntervalGenerator.intervalAt(y)); | 97 result->intervalAt(y).unite(marginIntervalGenerator.intervalAt(y)); |
| 189 | 98 |
| 190 for (int marginY = y + 1; marginY <= marginY1; ++marginY) { | 99 for (int marginY = y + 1; marginY <= marginY1; ++marginY) { |
| 191 if (marginY < bounds().maxY() && limitIntervalAt(marginY).contains(i
ntervalAtY)) | 100 if (marginY < bounds().maxY() && intervalAt(marginY).contains(interv
alAtY)) |
| 192 break; | 101 break; |
| 193 result->uniteMarginInterval(marginY, marginIntervalGenerator.interva
lAt(marginY)); | 102 result->intervalAt(marginY).unite(marginIntervalGenerator.intervalAt
(marginY)); |
| 194 } | 103 } |
| 195 } | 104 } |
| 196 | 105 |
| 106 result->initializeBounds(); |
| 197 return result.release(); | 107 return result.release(); |
| 198 } | 108 } |
| 199 | 109 |
| 110 void RasterShapeIntervals::initializeBounds() |
| 111 { |
| 112 m_bounds = IntRect(); |
| 113 for (int y = minY(); y < maxY(); ++y) { |
| 114 const IntShapeInterval& intervalAtY = intervalAt(y); |
| 115 if (intervalAtY.isEmpty()) |
| 116 continue; |
| 117 m_bounds.unite(IntRect(intervalAtY.x1(), y, intervalAtY.width(), 1)); |
| 118 } |
| 119 } |
| 120 |
| 200 const RasterShapeIntervals& RasterShape::marginIntervals() const | 121 const RasterShapeIntervals& RasterShape::marginIntervals() const |
| 201 { | 122 { |
| 202 ASSERT(shapeMargin() >= 0); | 123 ASSERT(shapeMargin() >= 0); |
| 203 if (!shapeMargin()) | 124 if (!shapeMargin()) |
| 204 return *m_intervals; | 125 return *m_intervals; |
| 205 | 126 |
| 206 int shapeMarginInt = clampToPositiveInteger(ceil(shapeMargin())); | 127 int shapeMarginInt = clampToPositiveInteger(ceil(shapeMargin())); |
| 207 int maxShapeMarginInt = std::max(m_marginRectSize.width(), m_marginRectSize.
height()) * sqrtf(2); | 128 int maxShapeMarginInt = std::max(m_marginRectSize.width(), m_marginRectSize.
height()) * sqrtf(2); |
| 208 if (!m_marginIntervals) | 129 if (!m_marginIntervals) |
| 209 m_marginIntervals = m_intervals->computeShapeMarginIntervals(std::min(sh
apeMarginInt, maxShapeMarginInt)); | 130 m_marginIntervals = m_intervals->computeShapeMarginIntervals(std::min(sh
apeMarginInt, maxShapeMarginInt)); |
| 210 | 131 |
| 211 return *m_marginIntervals; | 132 return *m_marginIntervals; |
| 212 } | 133 } |
| 213 | 134 |
| 214 static inline void appendLineSegments(const IntShapeIntervals& intervals, Segmen
tList& result) | |
| 215 { | |
| 216 for (unsigned i = 0; i < intervals.size(); i++) | |
| 217 result.append(LineSegment(intervals[i].x1(), intervals[i].x2() + 1)); | |
| 218 } | |
| 219 | |
| 220 void RasterShape::getExcludedIntervals(LayoutUnit logicalTop, LayoutUnit logical
Height, SegmentList& result) const | 135 void RasterShape::getExcludedIntervals(LayoutUnit logicalTop, LayoutUnit logical
Height, SegmentList& result) const |
| 221 { | 136 { |
| 222 const RasterShapeIntervals& intervals = marginIntervals(); | 137 const RasterShapeIntervals& intervals = marginIntervals(); |
| 223 if (intervals.isEmpty()) | 138 if (intervals.isEmpty()) |
| 224 return; | 139 return; |
| 225 | 140 |
| 226 IntShapeIntervals excludedIntervals; | 141 int y1 = logicalTop; |
| 227 intervals.getExcludedIntervals(logicalTop, logicalTop + logicalHeight, exclu
dedIntervals); | 142 int y2 = logicalTop + logicalHeight; |
| 228 appendLineSegments(excludedIntervals, result); | 143 ASSERT(y2 >= y1); |
| 144 if (y2 < intervals.bounds().y() || y1 >= intervals.bounds().maxY()) |
| 145 return; |
| 146 |
| 147 y1 = std::max(y1, intervals.bounds().y()); |
| 148 y2 = std::min(y2, intervals.bounds().maxY()); |
| 149 IntShapeInterval excludedInterval; |
| 150 |
| 151 for (int y = y1; y < y2; y++) |
| 152 excludedInterval.unite(intervals.intervalAt(y)); |
| 153 |
| 154 result.append(LineSegment(excludedInterval.x1(), excludedInterval.x2() + 1))
; |
| 229 } | 155 } |
| 230 | 156 |
| 231 } // namespace WebCore | 157 } // namespace WebCore |
| OLD | NEW |