Chromium Code Reviews| 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 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 231 fControlIndices.pop(); | 231 fControlIndices.pop(); |
| 232 } | 232 } |
| 233 | 233 |
| 234 void updateSaveBounds(const SkIRect& bounds) { | 234 void updateSaveBounds(const SkIRect& bounds) { |
| 235 // If we're in a Save block, expand its bounds to cover these bounds too . | 235 // If we're in a Save block, expand its bounds to cover these bounds too . |
| 236 if (!fSaveStack.isEmpty()) { | 236 if (!fSaveStack.isEmpty()) { |
| 237 fSaveStack.top().bounds.join(bounds); | 237 fSaveStack.top().bounds.join(bounds); |
| 238 } | 238 } |
| 239 } | 239 } |
| 240 | 240 |
| 241 // TODO: Remove this default when done bounding all ops. | 241 // TODO(mtklein): Remove this default when done bounding all ops. |
| 242 template <typename T> SkIRect bounds(const T&) const { return fCurrentClipBo unds; } | 242 template <typename T> SkIRect bounds(const T&) const { return fCurrentClipBo unds; } |
| 243 SkIRect bounds(const Clear&) const { return SkIRect::MakeLargest(); } // Ig nores the clip | 243 SkIRect bounds(const Clear&) const { return SkIRect::MakeLargest(); } // Ig nores the clip |
| 244 SkIRect bounds(const NoOp&) const { return SkIRect::MakeEmpty(); } // No Ops don't draw. | 244 SkIRect bounds(const NoOp&) const { return SkIRect::MakeEmpty(); } // No Ops don't draw. |
| 245 | 245 |
| 246 SkIRect bounds(const DrawRect& op) const { return this->adjustAndMap(op.rect , &op.paint); } | |
| 247 SkIRect bounds(const DrawOval& op) const { return this->adjustAndMap(op.oval , &op.paint); } | |
| 248 SkIRect bounds(const DrawRRect& op) const { | |
| 249 return this->adjustAndMap(op.rrect.rect(), &op.paint); | |
| 250 } | |
| 251 SkIRect bounds(const DrawDRRect& op) const { | |
| 252 return this->adjustAndMap(op.outer.rect(), &op.paint); | |
| 253 } | |
| 254 | |
| 255 SkIRect bounds(const DrawBitmapRectToRect& op) const { | |
| 256 return this->adjustAndMap(op.dst, op.paint); | |
| 257 } | |
| 258 SkIRect bounds(const DrawBitmapNine& op) const { | |
| 259 return this->adjustAndMap(op.dst, op.paint); | |
| 260 } | |
| 261 SkIRect bounds(const DrawBitmap& op) const { | |
| 262 const SkBitmap& bm = op.bitmap; | |
| 263 return this->adjustAndMap(SkRect::MakeXYWH(op.left, op.top, bm.width(), bm.height()), | |
| 264 op.paint); | |
| 265 } | |
| 266 SkIRect bounds(const DrawBitmapMatrix& op) const { | |
| 267 const SkBitmap& bm = op.bitmap; | |
| 268 SkRect dst = SkRect::MakeWH(bm.width(), bm.height()); | |
| 269 op.matrix.mapRect(&dst); | |
| 270 return this->adjustAndMap(dst, op.paint); | |
| 271 } | |
| 272 | |
| 273 SkIRect bounds(const DrawPath& op) const { | |
| 274 return op.path.isInverseFillType() ? fCurrentClipBounds | |
| 275 : this->adjustAndMap(op.path.getBound s(), &op.paint); | |
| 276 } | |
| 277 SkIRect bounds(const DrawPoints& op) const { | |
| 278 SkRect dst; | |
| 279 dst.set(op.pts, op.count); | |
| 280 | |
| 281 // Pad the bounding box a little to make sure hairline points' bounds ar en't empty. | |
| 282 SkScalar stroke = SkMaxScalar(op.paint.getStrokeWidth(), 0.01f); | |
| 283 dst.outset(stroke/2, stroke/2); | |
| 284 | |
| 285 return this->adjustAndMap(dst, &op.paint); | |
| 286 } | |
| 287 | |
| 288 SkIRect bounds(const DrawPosText& op) const { | |
| 289 SkRect dst; | |
|
robertphillips
2014/08/18 17:48:39
If there are no chars we probably want an empty bb
| |
| 290 dst.set(op.pos, op.paint.countText(op.text, op.byteLength)); | |
| 291 AdjustTextForFontMetrics(&dst, op.paint); | |
| 292 return this->adjustAndMap(dst, &op.paint); | |
| 293 } | |
| 294 SkIRect bounds(const DrawPosTextH& op) const { | |
| 295 const int N = op.paint.countText(op.text, op.byteLength); | |
| 296 if (N == 0) { | |
| 297 return SkIRect::MakeEmpty(); | |
| 298 } | |
| 299 | |
| 300 SkScalar left = op.xpos[0], right = op.xpos[0]; | |
| 301 for (int i = 1; i < N; i++) { | |
| 302 left = SkMinScalar(left, op.xpos[i]); | |
| 303 right = SkMaxScalar(right, op.xpos[i]); | |
| 304 } | |
| 305 SkRect dst = { left, op.y, right, op.y }; | |
| 306 AdjustTextForFontMetrics(&dst, op.paint); | |
| 307 return this->adjustAndMap(dst, &op.paint); | |
| 308 } | |
| 309 | |
| 310 static void AdjustTextForFontMetrics(SkRect* rect, const SkPaint& paint) { | |
| 311 // FIXME: These bounds should be tight (and correct), but reading SkFont Metrics is likely | |
|
robertphillips
2014/08/18 17:48:39
Double e.g.'s
| |
| 312 // a performance bottleneck. It's safe to overapproximate these metrics for speed. E.g. | |
| 313 // e.g. fTop <= 1.5 * paint.getTextSize(), fXMax <= 8 * fTop, etc. | |
| 314 SkPaint::FontMetrics metrics; | |
| 315 paint.getFontMetrics(&metrics); | |
| 316 rect->fLeft += metrics.fXMin; | |
| 317 rect->fTop += metrics.fTop; | |
| 318 rect->fRight += metrics.fXMax; | |
| 319 rect->fBottom += metrics.fBottom; | |
| 320 } | |
| 321 | |
| 246 // Returns true if rect was meaningfully adjusted for the effects of paint, | 322 // Returns true if rect was meaningfully adjusted for the effects of paint, |
| 247 // false if the paint could affect the rect in unknown ways. | 323 // false if the paint could affect the rect in unknown ways. |
| 248 static bool AdjustForPaint(const SkPaint* paint, SkRect* rect) { | 324 static bool AdjustForPaint(const SkPaint* paint, SkRect* rect) { |
| 249 if (paint) { | 325 if (paint) { |
| 250 if (paint->canComputeFastBounds()) { | 326 if (paint->canComputeFastBounds()) { |
| 251 *rect = paint->computeFastBounds(*rect, rect); | 327 *rect = paint->computeFastBounds(*rect, rect); |
| 252 return true; | 328 return true; |
| 253 } | 329 } |
| 254 return false; | 330 return false; |
| 255 } | 331 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 299 // Used to track the bounds of Save/Restore blocks and the control ops insid e them. | 375 // Used to track the bounds of Save/Restore blocks and the control ops insid e them. |
| 300 SkTDArray<SaveBounds> fSaveStack; | 376 SkTDArray<SaveBounds> fSaveStack; |
| 301 SkTDArray<unsigned> fControlIndices; | 377 SkTDArray<unsigned> fControlIndices; |
| 302 }; | 378 }; |
| 303 | 379 |
| 304 } // namespace SkRecords | 380 } // namespace SkRecords |
| 305 | 381 |
| 306 void SkRecordFillBounds(const SkRecord& record, SkBBoxHierarchy* bbh) { | 382 void SkRecordFillBounds(const SkRecord& record, SkBBoxHierarchy* bbh) { |
| 307 SkRecords::FillBounds(record, bbh); | 383 SkRecords::FillBounds(record, bbh); |
| 308 } | 384 } |
| OLD | NEW |