OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkRecordDraw.h" | 8 #include "SkRecordDraw.h" |
9 #include "SkTSort.h" | 9 #include "SkTSort.h" |
10 | 10 |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
238 } | 238 } |
239 | 239 |
240 void updateSaveBounds(const SkIRect& bounds) { | 240 void updateSaveBounds(const SkIRect& bounds) { |
241 // If we're in a Save block, expand its bounds to cover these bounds too . | 241 // If we're in a Save block, expand its bounds to cover these bounds too . |
242 if (!fSaveStack.isEmpty()) { | 242 if (!fSaveStack.isEmpty()) { |
243 fSaveStack.top().bounds.join(bounds); | 243 fSaveStack.top().bounds.join(bounds); |
244 } | 244 } |
245 } | 245 } |
246 | 246 |
247 // TODO: Remove this default when done bounding all ops. | 247 // TODO: Remove this default when done bounding all ops. |
248 template <typename T> SkIRect bounds(const T&) { return fCurrentClipBounds; } | 248 template <typename T> SkIRect bounds(const T&) const { return fCurrentClipBo unds; } |
249 SkIRect bounds(const Clear&) { return SkIRect::MakeLargest(); } // Ignores the clip | 249 SkIRect bounds(const Clear&) const { return SkIRect::MakeLargest(); } // Ig nores the clip |
250 SkIRect bounds(const NoOp&) { return SkIRect::MakeEmpty(); } // NoOps do n't draw anywhere. | 250 SkIRect bounds(const NoOp&) const { return SkIRect::MakeEmpty(); } // No Ops don't draw. |
251 | |
252 // Returns true if rect was meaningfully adjusted for the effects of paint, | |
253 // false if the paint could affect the rect in unknown ways. | |
254 static bool AdjustForPaint(const SkPaint* paint, SkRect* rect) { | |
255 if (paint) { | |
256 if (paint->canComputeFastBounds()) { | |
257 *rect = paint->computeFastBounds(*rect, rect); | |
258 return true; | |
259 } | |
260 return false; | |
261 } | |
262 return true; | |
263 } | |
251 | 264 |
252 // Adjust rect for all paints that may affect its geometry, then map it to d evice space. | 265 // Adjust rect for all paints that may affect its geometry, then map it to d evice space. |
253 SkIRect adjustAndMap(SkRect rect, const SkPaint* paint) { | 266 SkIRect adjustAndMap(SkRect rect, const SkPaint* paint) const { |
254 // Adjust rect for its own paint. | 267 // Inverted rectangles really confuse our BBHs. |
255 if (paint) { | 268 rect.sort(); |
256 if (paint->canComputeFastBounds()) { | 269 |
257 rect = paint->computeFastBounds(rect, &rect); | 270 // Adjust the rect for its own paint. |
258 } else { | 271 if (!AdjustForPaint(paint, &rect)) { |
robertphillips
2014/08/18 13:37:55
I liked the comment that used to go here
mtklein
2014/08/18 15:35:05
Ooh, agreed. Done.
| |
259 // The paint could do anything. The only safe answer is the cur rent clip. | 272 return fCurrentClipBounds; |
273 } | |
274 | |
275 // Adjust rect for all the paints from the SaveLayers we're inside. | |
276 for (int i = fSaveStack.count() - 1; i >= 0; i--) { | |
277 if (!AdjustForPaint(fSaveStack[i].paint, &rect)) { | |
260 return fCurrentClipBounds; | 278 return fCurrentClipBounds; |
261 } | 279 } |
262 } | 280 } |
263 | 281 |
264 // Adjust rect for all the paints from the SaveLayers we're inside. | |
265 // For SaveLayers, only image filters will affect the bounds. | |
266 for (int i = fSaveStack.count() - 1; i >= 0; i--) { | |
267 if (fSaveStack[i].paint && fSaveStack[i].paint->getImageFilter()) { | |
268 if (paint->canComputeFastBounds()) { | |
269 rect = fSaveStack[i].paint->computeFastBounds(rect, &rect); | |
270 } else { | |
271 // Same deal as above. | |
272 return fCurrentClipBounds; | |
273 } | |
274 } | |
275 } | |
276 | |
277 // Map the rect back to device space. | 282 // Map the rect back to device space. |
278 fCTM.mapRect(&rect); | 283 fCTM.mapRect(&rect); |
279 SkIRect devRect; | 284 SkIRect devRect; |
280 rect.roundOut(&devRect); | 285 rect.roundOut(&devRect); |
286 | |
287 // Nothing can draw outside the current clip. | |
robertphillips
2014/08/18 13:37:55
// clears don't matter in this case because ... ?
mtklein
2014/08/18 15:35:05
Done.
| |
288 devRect.intersect(fCurrentClipBounds); | |
289 | |
281 return devRect; | 290 return devRect; |
282 } | 291 } |
283 | 292 |
284 // Conservative device bounds for each op in the SkRecord. | 293 // Conservative device bounds for each op in the SkRecord. |
285 SkAutoTMalloc<SkIRect> fBounds; | 294 SkAutoTMalloc<SkIRect> fBounds; |
286 | 295 |
287 // We walk fCurrentOp through the SkRecord, as we go using updateCTM() | 296 // We walk fCurrentOp through the SkRecord, as we go using updateCTM() |
288 // and updateClipBounds() to maintain the exact CTM (fCTM) and conservative | 297 // and updateClipBounds() to maintain the exact CTM (fCTM) and conservative |
289 // device bounds of the current clip (fCurrentClipBounds). | 298 // device bounds of the current clip (fCurrentClipBounds). |
290 unsigned fCurrentOp; | 299 unsigned fCurrentOp; |
291 SkMatrix fCTM; | 300 SkMatrix fCTM; |
292 SkIRect fCurrentClipBounds; | 301 SkIRect fCurrentClipBounds; |
293 | 302 |
294 // Used to track the bounds of Save/Restore blocks and the control ops insid e them. | 303 // Used to track the bounds of Save/Restore blocks and the control ops insid e them. |
295 SkTDArray<SaveBounds> fSaveStack; | 304 SkTDArray<SaveBounds> fSaveStack; |
296 SkTDArray<unsigned> fControlIndices; | 305 SkTDArray<unsigned> fControlIndices; |
297 }; | 306 }; |
298 | 307 |
299 } // namespace SkRecords | 308 } // namespace SkRecords |
300 | 309 |
301 void SkRecordFillBounds(const SkRecord& record, SkBBoxHierarchy* bbh) { | 310 void SkRecordFillBounds(const SkRecord& record, SkBBoxHierarchy* bbh) { |
302 SkRecords::FillBounds(record, bbh); | 311 SkRecords::FillBounds(record, bbh); |
303 } | 312 } |
OLD | NEW |