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 |