Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 #include "SkPictureRecord.h" | 8 #include "SkPictureRecord.h" |
| 9 #include "SkTSearch.h" | 9 #include "SkTSearch.h" |
| 10 #include "SkPixelRef.h" | 10 #include "SkPixelRef.h" |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 // A lot of basic types get stored as a uint32_t: bools, ints, paint indices, et c. | 23 // A lot of basic types get stored as a uint32_t: bools, ints, paint indices, et c. |
| 24 static int const kUInt32Size = 4; | 24 static int const kUInt32Size = 4; |
| 25 | 25 |
| 26 static const uint32_t kSaveLayerNoBoundsSize = 4 * kUInt32Size; | 26 static const uint32_t kSaveLayerNoBoundsSize = 4 * kUInt32Size; |
| 27 static const uint32_t kSaveLayerWithBoundsSize = 4 * kUInt32Size + sizeof(SkRect ); | 27 static const uint32_t kSaveLayerWithBoundsSize = 4 * kUInt32Size + sizeof(SkRect ); |
| 28 | 28 |
| 29 SkPictureRecord::SkPictureRecord(uint32_t flags, SkDevice* device) : | 29 SkPictureRecord::SkPictureRecord(uint32_t flags, SkDevice* device) : |
| 30 INHERITED(device), | 30 INHERITED(device), |
| 31 fBoundingHierarchy(NULL), | 31 fBoundingHierarchy(NULL), |
| 32 fStateTree(NULL), | 32 fStateTree(NULL), |
| 33 fLastDrawRejected(false), | |
| 33 fFlattenableHeap(HEAP_BLOCK_SIZE), | 34 fFlattenableHeap(HEAP_BLOCK_SIZE), |
| 34 fMatrices(&fFlattenableHeap), | 35 fMatrices(&fFlattenableHeap), |
| 35 fPaints(&fFlattenableHeap), | 36 fPaints(&fFlattenableHeap), |
| 36 fRegions(&fFlattenableHeap), | 37 fRegions(&fFlattenableHeap), |
| 37 fWriter(MIN_WRITER_SIZE), | 38 fWriter(MIN_WRITER_SIZE), |
| 38 fRecordFlags(flags) { | 39 fRecordFlags(flags) { |
| 39 #ifdef SK_DEBUG_SIZE | 40 #ifdef SK_DEBUG_SIZE |
| 40 fPointBytes = fRectBytes = fTextBytes = 0; | 41 fPointBytes = fRectBytes = fTextBytes = 0; |
| 41 fPointWrites = fRectWrites = fTextWrites = 0; | 42 fPointWrites = fRectWrites = fTextWrites = 0; |
| 42 #endif | 43 #endif |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 55 SkSafeUnref(fBitmapHeap); | 56 SkSafeUnref(fBitmapHeap); |
| 56 SkSafeUnref(fPathHeap); | 57 SkSafeUnref(fPathHeap); |
| 57 SkSafeUnref(fBoundingHierarchy); | 58 SkSafeUnref(fBoundingHierarchy); |
| 58 SkSafeUnref(fStateTree); | 59 SkSafeUnref(fStateTree); |
| 59 fFlattenableHeap.setBitmapStorage(NULL); | 60 fFlattenableHeap.setBitmapStorage(NULL); |
| 60 fPictureRefs.unrefAll(); | 61 fPictureRefs.unrefAll(); |
| 61 } | 62 } |
| 62 | 63 |
| 63 /////////////////////////////////////////////////////////////////////////////// | 64 /////////////////////////////////////////////////////////////////////////////// |
| 64 | 65 |
| 66 bool SkPictureRecord::canRecordBounds(DrawType op) { | |
| 67 SkASSERT(op != DRAW_POS_TEXT_TOP_BOTTOM); // Should never be used when enco ding bounds | |
| 68 SkASSERT(op != DRAW_POS_TEXT_H_TOP_BOTTOM); | |
| 69 return | |
| 70 op == DRAW_BITMAP || | |
| 71 op == DRAW_BITMAP_MATRIX || | |
| 72 op == DRAW_BITMAP_NINE || | |
| 73 op == DRAW_BITMAP_RECT_TO_RECT || | |
| 74 op == DRAW_OVAL || | |
| 75 op == DRAW_PATH || | |
| 76 op == DRAW_POINTS || | |
| 77 op == DRAW_POS_TEXT || | |
| 78 op == DRAW_POS_TEXT_H || | |
| 79 op == DRAW_RECT || | |
| 80 op == DRAW_RRECT || | |
| 81 op == DRAW_TEXT || | |
| 82 op == DRAW_TEXT_ON_PATH || | |
| 83 op == DRAW_VERTICES; | |
| 84 } | |
| 85 | |
| 65 // Return the offset of the paint inside a given op's byte stream. A zero | 86 // Return the offset of the paint inside a given op's byte stream. A zero |
| 66 // return value means there is no paint (and you really shouldn't be calling | 87 // return value means there is no paint (and you really shouldn't be calling |
| 67 // this method) | 88 // this method) |
| 68 static inline uint32_t getPaintOffset(DrawType op, uint32_t opSize) { | 89 static inline uint32_t getPaintOffset(DrawType op, uint32_t opSize, bool recordB ounds) { |
| 69 // These offsets are where the paint would be if the op size doesn't overflo w | 90 // These offsets are where the paint would be if the op size doesn't overflo w |
| 70 static const uint8_t gPaintOffsets[LAST_DRAWTYPE_ENUM + 1] = { | 91 static const uint8_t gPaintOffsets[LAST_DRAWTYPE_ENUM + 1] = { |
| 71 0, // UNUSED - no paint | 92 0, // UNUSED - no paint |
| 72 0, // CLIP_PATH - no paint | 93 0, // CLIP_PATH - no paint |
| 73 0, // CLIP_REGION - no paint | 94 0, // CLIP_REGION - no paint |
| 74 0, // CLIP_RECT - no paint | 95 0, // CLIP_RECT - no paint |
| 75 0, // CLIP_RRECT - no paint | 96 0, // CLIP_RRECT - no paint |
| 76 0, // CONCAT - no paint | 97 0, // CONCAT - no paint |
| 77 1, // DRAW_BITMAP - right after op code | 98 1, // DRAW_BITMAP - right after op code |
| 78 1, // DRAW_BITMAP_MATRIX - right after op code | 99 1, // DRAW_BITMAP_MATRIX - right after op code |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 109 | 130 |
| 110 SkASSERT(sizeof(gPaintOffsets) == LAST_DRAWTYPE_ENUM + 1); | 131 SkASSERT(sizeof(gPaintOffsets) == LAST_DRAWTYPE_ENUM + 1); |
| 111 SkASSERT((unsigned)op <= (unsigned)LAST_DRAWTYPE_ENUM); | 132 SkASSERT((unsigned)op <= (unsigned)LAST_DRAWTYPE_ENUM); |
| 112 | 133 |
| 113 int overflow = 0; | 134 int overflow = 0; |
| 114 if (0 != (opSize & ~MASK_24) || opSize == MASK_24) { | 135 if (0 != (opSize & ~MASK_24) || opSize == MASK_24) { |
| 115 // This op's size overflows so an extra uint32_t will be written | 136 // This op's size overflows so an extra uint32_t will be written |
| 116 // after the op code | 137 // after the op code |
| 117 overflow = sizeof(uint32_t); | 138 overflow = sizeof(uint32_t); |
| 118 } | 139 } |
| 140 if (recordBounds && SkPictureRecord::canRecordBounds(op)) { | |
| 141 overflow += sizeof(SkIRect); | |
| 142 } | |
| 119 | 143 |
| 120 if (SAVE_LAYER == op) { | 144 if (SAVE_LAYER == op) { |
| 121 static const uint32_t kSaveLayerNoBoundsPaintOffset = 2 * kUInt32Size; | 145 static const uint32_t kSaveLayerNoBoundsPaintOffset = 2 * kUInt32Size; |
| 122 static const uint32_t kSaveLayerWithBoundsPaintOffset = 2 * kUInt32Size + sizeof(SkRect); | 146 static const uint32_t kSaveLayerWithBoundsPaintOffset = 2 * kUInt32Size + sizeof(SkRect); |
| 123 | 147 |
| 124 if (kSaveLayerNoBoundsSize == opSize) { | 148 if (kSaveLayerNoBoundsSize == opSize) { |
| 125 return kSaveLayerNoBoundsPaintOffset + overflow; | 149 return kSaveLayerNoBoundsPaintOffset + overflow; |
| 126 } else { | 150 } else { |
| 127 SkASSERT(kSaveLayerWithBoundsSize == opSize); | 151 SkASSERT(kSaveLayerWithBoundsSize == opSize); |
| 128 return kSaveLayerWithBoundsPaintOffset + overflow; | 152 return kSaveLayerWithBoundsPaintOffset + overflow; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 139 } | 163 } |
| 140 | 164 |
| 141 int SkPictureRecord::save(SaveFlags flags) { | 165 int SkPictureRecord::save(SaveFlags flags) { |
| 142 // record the offset to us, making it non-positive to distinguish a save | 166 // record the offset to us, making it non-positive to distinguish a save |
| 143 // from a clip entry. | 167 // from a clip entry. |
| 144 fRestoreOffsetStack.push(-(int32_t)fWriter.size()); | 168 fRestoreOffsetStack.push(-(int32_t)fWriter.size()); |
| 145 | 169 |
| 146 // op + flags | 170 // op + flags |
| 147 uint32_t size = 2 * kUInt32Size; | 171 uint32_t size = 2 * kUInt32Size; |
| 148 uint32_t initialOffset = this->addDraw(SAVE, &size); | 172 uint32_t initialOffset = this->addDraw(SAVE, &size); |
| 173 SkASSERT(kInvalidOffset != initialOffset); | |
| 149 addInt(flags); | 174 addInt(flags); |
| 150 | 175 |
| 151 validate(initialOffset, size); | 176 validate(initialOffset, size); |
| 152 return this->INHERITED::save(flags); | 177 return this->INHERITED::save(flags); |
| 153 } | 178 } |
| 154 | 179 |
| 155 int SkPictureRecord::saveLayer(const SkRect* bounds, const SkPaint* paint, | 180 int SkPictureRecord::saveLayer(const SkRect* bounds, const SkPaint* paint, |
| 156 SaveFlags flags) { | 181 SaveFlags flags) { |
| 157 // record the offset to us, making it non-positive to distinguish a save | 182 // record the offset to us, making it non-positive to distinguish a save |
| 158 // from a clip entry. | 183 // from a clip entry. |
| 159 fRestoreOffsetStack.push(-(int32_t)fWriter.size()); | 184 fRestoreOffsetStack.push(-(int32_t)fWriter.size()); |
| 160 | 185 |
| 161 // op + bool for 'bounds' | 186 // op + bool for 'bounds' |
| 162 uint32_t size = 2 * kUInt32Size; | 187 uint32_t size = 2 * kUInt32Size; |
| 163 if (NULL != bounds) { | 188 if (NULL != bounds) { |
| 164 size += sizeof(*bounds); // + rect | 189 size += sizeof(*bounds); // + rect |
| 165 } | 190 } |
| 166 // + paint index + flags | 191 // + paint index + flags |
| 167 size += 2 * kUInt32Size; | 192 size += 2 * kUInt32Size; |
| 168 | 193 |
| 169 SkASSERT(kSaveLayerNoBoundsSize == size || kSaveLayerWithBoundsSize == size) ; | 194 SkASSERT(kSaveLayerNoBoundsSize == size || kSaveLayerWithBoundsSize == size) ; |
| 170 | 195 |
| 171 uint32_t initialOffset = this->addDraw(SAVE_LAYER, &size); | 196 uint32_t initialOffset = this->addDraw(SAVE_LAYER, &size); |
| 197 SkASSERT(kInvalidOffset != initialOffset); | |
| 172 addRectPtr(bounds); | 198 addRectPtr(bounds); |
| 173 SkASSERT(initialOffset+getPaintOffset(SAVE_LAYER, size) == fWriter.size()); | 199 SkASSERT(initialOffset + getPaintOffset(SAVE_LAYER, size, false) == fWriter. size()); |
| 174 addPaintPtr(paint); | 200 addPaintPtr(paint); |
| 175 addInt(flags); | 201 addInt(flags); |
| 176 | 202 |
| 177 if (kNoSavedLayerIndex == fFirstSavedLayerIndex) { | 203 if (kNoSavedLayerIndex == fFirstSavedLayerIndex) { |
| 178 fFirstSavedLayerIndex = fRestoreOffsetStack.count(); | 204 fFirstSavedLayerIndex = fRestoreOffsetStack.count(); |
| 179 } | 205 } |
| 180 | 206 |
| 181 validate(initialOffset, size); | 207 validate(initialOffset, size); |
| 182 /* Don't actually call saveLayer, because that will try to allocate an | 208 /* Don't actually call saveLayer, because that will try to allocate an |
| 183 offscreen device (potentially very big) which we don't actually need | 209 offscreen device (potentially very big) which we don't actually need |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 228 | 254 |
| 229 /* | 255 /* |
| 230 * Restore has just been called (but not recorded), look back at the | 256 * Restore has just been called (but not recorded), look back at the |
| 231 * matching save* and see if we are in the configuration: | 257 * matching save* and see if we are in the configuration: |
| 232 * SAVE_LAYER | 258 * SAVE_LAYER |
| 233 * DRAW_BITMAP|DRAW_BITMAP_MATRIX|DRAW_BITMAP_NINE|DRAW_BITMAP_RECT_TO_REC T | 259 * DRAW_BITMAP|DRAW_BITMAP_MATRIX|DRAW_BITMAP_NINE|DRAW_BITMAP_RECT_TO_REC T |
| 234 * RESTORE | 260 * RESTORE |
| 235 * where the saveLayer's color can be moved into the drawBitmap*'s paint | 261 * where the saveLayer's color can be moved into the drawBitmap*'s paint |
| 236 */ | 262 */ |
| 237 static bool remove_save_layer1(SkWriter32* writer, int32_t offset, | 263 static bool remove_save_layer1(SkWriter32* writer, int32_t offset, |
| 238 SkPaintDictionary* paintDict) { | 264 SkPaintDictionary* paintDict, bool recordBounds) { |
| 239 | 265 |
| 240 #ifdef SK_IGNORE_PICTURE_RECORD_SAVE_LAYER_OPT | 266 #ifdef SK_IGNORE_PICTURE_RECORD_SAVE_LAYER_OPT |
| 241 return false; | 267 return false; |
| 242 #endif | 268 #endif |
| 243 | 269 |
| 244 int32_t restoreOffset = (int32_t)writer->size(); | 270 int32_t restoreOffset = (int32_t)writer->size(); |
| 245 | 271 |
| 246 // back up to the save block | 272 // back up to the save block |
| 247 // TODO: add a stack to track save*/restore offsets rather than searching ba ckwards | 273 // TODO: add a stack to track save*/restore offsets rather than searching ba ckwards |
| 248 while (offset > 0) { | 274 while (offset > 0) { |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 276 if (DRAW_BITMAP != op && DRAW_BITMAP_MATRIX != op && | 302 if (DRAW_BITMAP != op && DRAW_BITMAP_MATRIX != op && |
| 277 DRAW_BITMAP_NINE != op && DRAW_BITMAP_RECT_TO_RECT != op) { | 303 DRAW_BITMAP_NINE != op && DRAW_BITMAP_RECT_TO_RECT != op) { |
| 278 return false; // not a match | 304 return false; // not a match |
| 279 } | 305 } |
| 280 | 306 |
| 281 offset = dbmOffset + dbmSize; | 307 offset = dbmOffset + dbmSize; |
| 282 if (offset < restoreOffset) { | 308 if (offset < restoreOffset) { |
| 283 return false; // something else between the dbm* and the restore | 309 return false; // something else between the dbm* and the restore |
| 284 } | 310 } |
| 285 | 311 |
| 286 uint32_t dbmPaintOffset = getPaintOffset(op, dbmSize); | 312 uint32_t dbmPaintOffset = getPaintOffset(op, dbmSize, recordBounds); |
| 287 uint32_t slPaintOffset = getPaintOffset(SAVE_LAYER, saveLayerSize); | 313 uint32_t slPaintOffset = getPaintOffset(SAVE_LAYER, saveLayerSize, false); |
| 288 | 314 |
| 289 // we have a match, now we need to get the paints involved | 315 // we have a match, now we need to get the paints involved |
| 290 int dbmPaintId = *((int32_t*)writer->peek32(dbmOffset+dbmPaintOffset)); | 316 int dbmPaintId = *((int32_t*)writer->peek32(dbmOffset+dbmPaintOffset)); |
| 291 int saveLayerPaintId = *((int32_t*)writer->peek32(saveLayerOffset+slPaintOff set)); | 317 int saveLayerPaintId = *((int32_t*)writer->peek32(saveLayerOffset+slPaintOff set)); |
| 292 | 318 |
| 293 if (0 == saveLayerPaintId) { | 319 if (0 == saveLayerPaintId) { |
| 294 // In this case the saveLayer/restore isn't needed at all - just kill th e saveLayer | 320 // In this case the saveLayer/restore isn't needed at all - just kill th e saveLayer |
| 295 // and signal the caller (by returning true) to not add the RESTORE op | 321 // and signal the caller (by returning true) to not add the RESTORE op |
| 296 uint32_t* ptr = writer->peek32(saveLayerOffset); | 322 uint32_t* ptr = writer->peek32(saveLayerOffset); |
| 297 *ptr = (*ptr & MASK_24) | (NOOP << 24); | 323 *ptr = (*ptr & MASK_24) | (NOOP << 24); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 411 if (fRestoreOffsetStack.count() == 0) { | 437 if (fRestoreOffsetStack.count() == 0) { |
| 412 return; | 438 return; |
| 413 } | 439 } |
| 414 | 440 |
| 415 if (fRestoreOffsetStack.count() == fFirstSavedLayerIndex) { | 441 if (fRestoreOffsetStack.count() == fFirstSavedLayerIndex) { |
| 416 fFirstSavedLayerIndex = kNoSavedLayerIndex; | 442 fFirstSavedLayerIndex = kNoSavedLayerIndex; |
| 417 } | 443 } |
| 418 | 444 |
| 419 uint32_t initialOffset, size; | 445 uint32_t initialOffset, size; |
| 420 if (!collapseSaveClipRestore(&fWriter, fRestoreOffsetStack.top()) && | 446 if (!collapseSaveClipRestore(&fWriter, fRestoreOffsetStack.top()) && |
| 421 !remove_save_layer1(&fWriter, fRestoreOffsetStack.top(), &fPaints)) { | 447 !remove_save_layer1(&fWriter, fRestoreOffsetStack.top(), &fPaints, |
|
robertphillips
2013/03/06 23:02:02
SkToBool?
| |
| 448 0 != (fRecordFlags & SkPicture::kRecordBounds_RecordingFlag))) { | |
| 422 fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.size ()); | 449 fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.size ()); |
| 423 // op | 450 // op |
| 424 size = 1 * kUInt32Size; | 451 size = 1 * kUInt32Size; |
| 425 initialOffset = this->addDraw(RESTORE, &size); | 452 initialOffset = this->addDraw(RESTORE, &size); |
| 426 } else { | 453 } else { |
| 427 size = 0; | 454 size = 0; |
| 428 initialOffset = fWriter.size(); | 455 initialOffset = fWriter.size(); |
| 429 } | 456 } |
| 430 | 457 |
| 431 fRestoreOffsetStack.pop(); | 458 fRestoreOffsetStack.pop(); |
| 432 | 459 |
| 433 validate(initialOffset, size); | 460 validate(initialOffset, size); |
| 434 return this->INHERITED::restore(); | 461 return this->INHERITED::restore(); |
| 435 } | 462 } |
| 436 | 463 |
| 464 uint32_t SkPictureRecord::addDrawWithBounds(DrawType drawType, uint32_t* size, | |
| 465 const SkPaint* paint, const SkRect* localBounds) { | |
| 466 SkASSERT(canRecordBounds(drawType)); | |
| 467 | |
| 468 SkIRect clippedDevBounds; | |
| 469 if (recordBounds()) { | |
| 470 SkIRect devClipBounds; | |
| 471 if (!this->getClipDeviceBounds(&devClipBounds)) { | |
|
robertphillips
2013/03/06 23:02:02
Comment here about this optimization and why it is
| |
| 472 fLastDrawRejected = true; | |
| 473 return 0; | |
| 474 } | |
| 475 if (NULL == localBounds || (NULL != paint && !paint->canComputeFastBound s())) { | |
| 476 clippedDevBounds = devClipBounds; | |
| 477 } else { | |
| 478 SkRect paintBounds; | |
| 479 SkRect rectifiedBounds = *localBounds; | |
| 480 rectifiedBounds.sort(); | |
| 481 if (NULL != paint) { | |
| 482 if (drawType == DRAW_POINTS) { | |
| 483 paintBounds = paint->computeFastStrokeBounds(rectifiedBounds , &paintBounds); | |
| 484 } else { | |
| 485 paintBounds = paint->computeFastBounds(rectifiedBounds, &pai ntBounds); | |
| 486 } | |
| 487 } else { | |
| 488 paintBounds = *localBounds; | |
| 489 } | |
| 490 if (paintBounds.isEmpty()) { | |
| 491 fLastDrawRejected = true; | |
| 492 return 0; | |
| 493 } | |
| 494 SkRect devBounds; | |
| 495 this->getTotalMatrix().mapRect(&devBounds, paintBounds); | |
| 496 devBounds.roundOut(&clippedDevBounds); | |
| 497 if (!clippedDevBounds.intersect(devClipBounds)) { | |
| 498 fLastDrawRejected = true; | |
| 499 return 0; | |
| 500 } | |
| 501 } | |
| 502 *size += sizeof(SkIRect); | |
| 503 } | |
| 504 | |
| 505 uint32_t offset = addDraw(drawType, size); | |
| 506 | |
| 507 if (recordBounds()) { | |
| 508 fWriter.write(&clippedDevBounds, sizeof(clippedDevBounds)); | |
| 509 } | |
| 510 return offset; | |
| 511 } | |
| 512 | |
| 437 bool SkPictureRecord::translate(SkScalar dx, SkScalar dy) { | 513 bool SkPictureRecord::translate(SkScalar dx, SkScalar dy) { |
| 438 // op + dx + dy | 514 // op + dx + dy |
| 439 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); | 515 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); |
| 440 uint32_t initialOffset = this->addDraw(TRANSLATE, &size); | 516 uint32_t initialOffset = this->addDraw(TRANSLATE, &size); |
| 441 addScalar(dx); | 517 addScalar(dx); |
| 442 addScalar(dy); | 518 addScalar(dy); |
| 443 validate(initialOffset, size); | 519 validate(initialOffset, size); |
| 444 return this->INHERITED::translate(dx, dy); | 520 return this->INHERITED::translate(dx, dy); |
| 445 } | 521 } |
| 446 | 522 |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 653 uint32_t size = 2 * kUInt32Size; | 729 uint32_t size = 2 * kUInt32Size; |
| 654 uint32_t initialOffset = this->addDraw(DRAW_CLEAR, &size); | 730 uint32_t initialOffset = this->addDraw(DRAW_CLEAR, &size); |
| 655 addInt(color); | 731 addInt(color); |
| 656 validate(initialOffset, size); | 732 validate(initialOffset, size); |
| 657 } | 733 } |
| 658 | 734 |
| 659 void SkPictureRecord::drawPaint(const SkPaint& paint) { | 735 void SkPictureRecord::drawPaint(const SkPaint& paint) { |
| 660 // op + paint index | 736 // op + paint index |
| 661 uint32_t size = 2 * kUInt32Size; | 737 uint32_t size = 2 * kUInt32Size; |
| 662 uint32_t initialOffset = this->addDraw(DRAW_PAINT, &size); | 738 uint32_t initialOffset = this->addDraw(DRAW_PAINT, &size); |
| 663 SkASSERT(initialOffset+getPaintOffset(DRAW_PAINT, size) == fWriter.size()); | 739 SkASSERT(initialOffset + getPaintOffset(DRAW_PAINT, size, false) == fWriter. size()); |
| 664 addPaint(paint); | 740 addPaint(paint); |
| 665 validate(initialOffset, size); | 741 validate(initialOffset, size); |
| 666 } | 742 } |
| 667 | 743 |
| 668 void SkPictureRecord::drawPoints(PointMode mode, size_t count, const SkPoint pts [], | 744 void SkPictureRecord::drawPoints(PointMode mode, size_t count, const SkPoint pts [], |
| 669 const SkPaint& paint) { | 745 const SkPaint& paint) { |
| 670 // op + paint index + mode + count + point data | 746 // op + paint index + mode + count + point data |
| 671 uint32_t size = 4 * kUInt32Size + count * sizeof(SkPoint); | 747 uint32_t size = 4 * kUInt32Size + count * sizeof(SkPoint); |
| 672 uint32_t initialOffset = this->addDraw(DRAW_POINTS, &size); | 748 uint32_t initialOffset; |
| 673 SkASSERT(initialOffset+getPaintOffset(DRAW_POINTS, size) == fWriter.size()); | 749 if (recordBounds()) { |
| 750 SkRect bbox; | |
| 751 bbox.set(pts, count); | |
| 752 initialOffset = this->addDrawWithBounds(DRAW_POINTS, &size, &paint, &bbo x); | |
|
robertphillips
2013/03/06 23:02:02
Could fLastDrawRejected be passed in as a paramete
Justin Novosad
2013/03/07 14:41:42
It could, but I need to have as a member anyways b
| |
| 753 if (fLastDrawRejected) { | |
| 754 return; | |
| 755 } | |
| 756 } else { | |
| 757 initialOffset = this->addDraw(DRAW_POINTS, &size); | |
| 758 } | |
|
robertphillips
2013/03/06 23:02:02
this->recordBounds()? Also in following changes to
| |
| 759 SkASSERT(initialOffset + getPaintOffset(DRAW_POINTS, size, recordBounds()) = = fWriter.size()); | |
| 674 addPaint(paint); | 760 addPaint(paint); |
| 675 addInt(mode); | 761 addInt(mode); |
| 676 addInt(count); | 762 addInt(count); |
| 677 fWriter.writeMul4(pts, count * sizeof(SkPoint)); | 763 fWriter.writeMul4(pts, count * sizeof(SkPoint)); |
| 678 validate(initialOffset, size); | 764 validate(initialOffset, size); |
| 679 } | 765 } |
| 680 | 766 |
| 681 void SkPictureRecord::drawOval(const SkRect& oval, const SkPaint& paint) { | 767 void SkPictureRecord::drawOval(const SkRect& oval, const SkPaint& paint) { |
| 682 // op + paint index + rect | 768 // op + paint index + rect |
| 683 uint32_t size = 2 * kUInt32Size + sizeof(oval); | 769 uint32_t size = 2 * kUInt32Size + sizeof(oval); |
| 684 uint32_t initialOffset = this->addDraw(DRAW_OVAL, &size); | 770 uint32_t initialOffset; |
| 685 SkASSERT(initialOffset+getPaintOffset(DRAW_OVAL, size) == fWriter.size()); | 771 if (recordBounds()) { |
| 772 initialOffset = this->addDrawWithBounds(DRAW_OVAL, &size, &paint, &oval) ; | |
| 773 if (fLastDrawRejected) { | |
| 774 return; | |
| 775 } | |
| 776 } else { | |
| 777 initialOffset = this->addDraw(DRAW_OVAL, &size); | |
| 778 } | |
| 779 SkASSERT(initialOffset + getPaintOffset(DRAW_OVAL, size, recordBounds()) == fWriter.size()); | |
| 686 addPaint(paint); | 780 addPaint(paint); |
| 687 addRect(oval); | 781 addRect(oval); |
| 688 validate(initialOffset, size); | 782 validate(initialOffset, size); |
| 689 } | 783 } |
| 690 | 784 |
| 691 void SkPictureRecord::drawRect(const SkRect& rect, const SkPaint& paint) { | 785 void SkPictureRecord::drawRect(const SkRect& rect, const SkPaint& paint) { |
| 692 // op + paint index + rect | 786 // op + paint index + rect |
| 693 uint32_t size = 2 * kUInt32Size + sizeof(rect); | 787 uint32_t size = 2 * kUInt32Size + sizeof(rect); |
| 694 uint32_t initialOffset = this->addDraw(DRAW_RECT, &size); | 788 uint32_t initialOffset; |
| 695 SkASSERT(initialOffset+getPaintOffset(DRAW_RECT, size) == fWriter.size()); | 789 if (recordBounds()) { |
| 790 initialOffset = this->addDrawWithBounds(DRAW_RECT, &size, &paint, &rect) ; | |
| 791 if (fLastDrawRejected) { | |
| 792 return; | |
| 793 } | |
| 794 } else { | |
| 795 initialOffset = this->addDraw(DRAW_RECT, &size); | |
| 796 } | |
| 797 SkASSERT(initialOffset + getPaintOffset(DRAW_RECT, size, recordBounds()) == fWriter.size()); | |
| 696 addPaint(paint); | 798 addPaint(paint); |
| 697 addRect(rect); | 799 addRect(rect); |
| 698 validate(initialOffset, size); | 800 validate(initialOffset, size); |
| 699 } | 801 } |
| 700 | 802 |
| 701 void SkPictureRecord::drawRRect(const SkRRect& rrect, const SkPaint& paint) { | 803 void SkPictureRecord::drawRRect(const SkRRect& rrect, const SkPaint& paint) { |
| 702 uint32_t initialOffset, size; | |
| 703 if (rrect.isRect()) { | 804 if (rrect.isRect()) { |
| 704 // op + paint index + rect | 805 this->drawRect(rrect.getBounds(), paint); |
| 705 size = 2 * kUInt32Size + sizeof(SkRect); | |
| 706 initialOffset = this->addDraw(DRAW_RECT, &size); | |
| 707 SkASSERT(initialOffset+getPaintOffset(DRAW_RECT, size) == fWriter.size() ); | |
| 708 addPaint(paint); | |
| 709 addRect(rrect.getBounds()); | |
| 710 } else if (rrect.isOval()) { | 806 } else if (rrect.isOval()) { |
| 711 // op + paint index + rect | 807 this->drawOval(rrect.getBounds(), paint); |
| 712 size = 2 * kUInt32Size + sizeof(SkRect); | |
| 713 initialOffset = this->addDraw(DRAW_OVAL, &size); | |
| 714 SkASSERT(initialOffset+getPaintOffset(DRAW_OVAL, size) == fWriter.size() ); | |
| 715 addPaint(paint); | |
| 716 addRect(rrect.getBounds()); | |
| 717 } else { | 808 } else { |
| 718 // op + paint index + rrect | 809 // op + paint index + rrect |
| 810 uint32_t initialOffset, size; | |
| 719 size = 2 * kUInt32Size + SkRRect::kSizeInMemory; | 811 size = 2 * kUInt32Size + SkRRect::kSizeInMemory; |
| 720 initialOffset = this->addDraw(DRAW_RRECT, &size); | 812 if (recordBounds()) { |
|
robertphillips
2013/03/06 23:02:02
What do you think about modifying addDraw to alway
Justin Novosad
2013/03/07 14:41:42
Well, I also want to avoid computing the bounds th
| |
| 721 SkASSERT(initialOffset+getPaintOffset(DRAW_RRECT, size) == fWriter.size( )); | 813 initialOffset = this->addDrawWithBounds(DRAW_RRECT, &size, &paint, & rrect.getBounds()); |
| 814 if (fLastDrawRejected) { | |
| 815 return; | |
| 816 } | |
| 817 } else { | |
| 818 initialOffset = this->addDraw(DRAW_RRECT, &size); | |
| 819 } | |
| 820 SkASSERT(initialOffset + getPaintOffset(DRAW_RRECT, size, recordBounds() ) \ | |
| 821 == fWriter.size()); | |
| 722 addPaint(paint); | 822 addPaint(paint); |
| 723 addRRect(rrect); | 823 addRRect(rrect); |
| 824 validate(initialOffset, size); | |
| 724 } | 825 } |
| 725 validate(initialOffset, size); | |
| 726 } | 826 } |
| 727 | 827 |
| 728 void SkPictureRecord::drawPath(const SkPath& path, const SkPaint& paint) { | 828 void SkPictureRecord::drawPath(const SkPath& path, const SkPaint& paint) { |
| 729 // op + paint index + path index | 829 // op + paint index + path index |
| 730 uint32_t size = 3 * kUInt32Size; | 830 uint32_t size = 3 * kUInt32Size; |
| 731 uint32_t initialOffset = this->addDraw(DRAW_PATH, &size); | 831 const SkRect* bounds = path.isInverseFillType() ? NULL : &path.getBounds(); |
| 732 SkASSERT(initialOffset+getPaintOffset(DRAW_PATH, size) == fWriter.size()); | 832 uint32_t initialOffset; |
| 833 if (recordBounds()) { | |
| 834 initialOffset = this->addDrawWithBounds(DRAW_PATH, &size, &paint, bounds ); | |
| 835 if (fLastDrawRejected) { | |
| 836 return; | |
| 837 } | |
| 838 } else { | |
| 839 initialOffset = this->addDraw(DRAW_PATH, &size); | |
| 840 } | |
| 841 SkASSERT(initialOffset + getPaintOffset(DRAW_PATH, size, recordBounds()) == fWriter.size()); | |
| 733 addPaint(paint); | 842 addPaint(paint); |
| 734 addPath(path); | 843 addPath(path); |
| 735 validate(initialOffset, size); | 844 validate(initialOffset, size); |
| 736 } | 845 } |
| 737 | 846 |
| 738 void SkPictureRecord::drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, | 847 void SkPictureRecord::drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, |
| 739 const SkPaint* paint = NULL) { | 848 const SkPaint* paint = NULL) { |
| 740 // op + paint index + bitmap index + left + top | 849 // op + paint index + bitmap index + left + top |
| 741 uint32_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar); | 850 uint32_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar); |
| 742 uint32_t initialOffset = this->addDraw(DRAW_BITMAP, &size); | 851 SkRect bounds = SkRect::MakeXYWH(left, top, bitmap.width(), bitmap.height()) ; |
| 743 SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP, size) == fWriter.size()); | 852 uint32_t initialOffset; |
| 853 if (recordBounds()) { | |
| 854 initialOffset = this->addDrawWithBounds(DRAW_BITMAP, &size, paint, &boun ds); | |
| 855 if (fLastDrawRejected) { | |
| 856 return; | |
| 857 } | |
| 858 } else { | |
| 859 initialOffset = this->addDraw(DRAW_BITMAP, &size); | |
| 860 } | |
| 861 SkASSERT(initialOffset + getPaintOffset(DRAW_BITMAP, size, recordBounds()) = = fWriter.size()); | |
| 744 addPaintPtr(paint); | 862 addPaintPtr(paint); |
| 745 addBitmap(bitmap); | 863 addBitmap(bitmap); |
| 746 addScalar(left); | 864 addScalar(left); |
| 747 addScalar(top); | 865 addScalar(top); |
| 748 validate(initialOffset, size); | 866 validate(initialOffset, size); |
| 749 } | 867 } |
| 750 | 868 |
| 751 void SkPictureRecord::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, | 869 void SkPictureRecord::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, |
| 752 const SkRect& dst, const SkPaint* paint) { | 870 const SkRect& dst, const SkPaint* paint) { |
| 753 // id + paint index + bitmap index + bool for 'src' | 871 // id + paint index + bitmap index + bool for 'src' |
| 754 uint32_t size = 4 * kUInt32Size; | 872 uint32_t size = 4 * kUInt32Size; |
| 755 if (NULL != src) { | 873 if (NULL != src) { |
| 756 size += sizeof(*src); // + rect | 874 size += sizeof(*src); // + rect |
| 757 } | 875 } |
| 758 size += sizeof(dst); // + rect | 876 size += sizeof(dst); // + rect |
| 759 | 877 |
| 760 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_RECT_TO_RECT, &size); | 878 uint32_t initialOffset; |
| 761 SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP_RECT_TO_RECT, size) == fWr iter.size()); | 879 if (recordBounds()) { |
| 880 initialOffset = this->addDrawWithBounds(DRAW_BITMAP_RECT_TO_RECT, &size, paint, &dst); | |
| 881 if (fLastDrawRejected) { | |
| 882 return; | |
| 883 } | |
| 884 } else { | |
| 885 initialOffset = this->addDraw(DRAW_BITMAP_RECT_TO_RECT, &size); | |
| 886 } | |
| 887 SkASSERT(initialOffset + getPaintOffset(DRAW_BITMAP_RECT_TO_RECT, size, reco rdBounds()) \ | |
| 888 == fWriter.size()); | |
| 762 addPaintPtr(paint); | 889 addPaintPtr(paint); |
| 763 addBitmap(bitmap); | 890 addBitmap(bitmap); |
| 764 addRectPtr(src); // may be null | 891 addRectPtr(src); // may be null |
| 765 addRect(dst); | 892 addRect(dst); |
| 766 validate(initialOffset, size); | 893 validate(initialOffset, size); |
| 767 } | 894 } |
| 768 | 895 |
| 769 void SkPictureRecord::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m atrix, | 896 void SkPictureRecord::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m atrix, |
| 770 const SkPaint* paint) { | 897 const SkPaint* paint) { |
| 771 // id + paint index + bitmap index + matrix index | 898 // id + paint index + bitmap index + matrix index |
| 772 uint32_t size = 4 * kUInt32Size; | 899 uint32_t size = 4 * kUInt32Size; |
| 773 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_MATRIX, &size); | 900 uint32_t initialOffset; |
| 774 SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP_MATRIX, size) == fWriter.s ize()); | 901 if (recordBounds()) { |
| 902 SkRect bounds = SkRect::MakeWH(bitmap.width(), bitmap.height()); | |
| 903 matrix.mapRect(&bounds); | |
| 904 initialOffset = this->addDrawWithBounds(DRAW_BITMAP_MATRIX, &size, paint , &bounds); | |
| 905 if (fLastDrawRejected) { | |
| 906 return; | |
| 907 } | |
| 908 } else { | |
| 909 initialOffset = this->addDraw(DRAW_BITMAP_MATRIX, &size); | |
| 910 } | |
| 911 SkASSERT(initialOffset + getPaintOffset(DRAW_BITMAP_MATRIX, size, recordBoun ds()) \ | |
| 912 == fWriter.size()); | |
| 775 addPaintPtr(paint); | 913 addPaintPtr(paint); |
| 776 addBitmap(bitmap); | 914 addBitmap(bitmap); |
| 777 addMatrix(matrix); | 915 addMatrix(matrix); |
| 778 validate(initialOffset, size); | 916 validate(initialOffset, size); |
| 779 } | 917 } |
| 780 | 918 |
| 781 void SkPictureRecord::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& cent er, | 919 void SkPictureRecord::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& cent er, |
| 782 const SkRect& dst, const SkPaint* paint) { | 920 const SkRect& dst, const SkPaint* paint) { |
| 783 // op + paint index + bitmap id + center + dst rect | 921 // op + paint index + bitmap id + center + dst rect |
| 784 uint32_t size = 3 * kUInt32Size + sizeof(center) + sizeof(dst); | 922 uint32_t size = 3 * kUInt32Size + sizeof(center) + sizeof(dst); |
| 785 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_NINE, &size); | 923 uint32_t initialOffset; |
| 786 SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP_NINE, size) == fWriter.siz e()); | 924 if (recordBounds()) { |
| 925 initialOffset = this->addDrawWithBounds(DRAW_BITMAP_NINE, &size, paint, &dst); | |
| 926 if (fLastDrawRejected) { | |
| 927 return; | |
| 928 } | |
| 929 } else { | |
| 930 initialOffset = this->addDraw(DRAW_BITMAP_NINE, &size); | |
| 931 } | |
| 932 SkASSERT(initialOffset + getPaintOffset(DRAW_BITMAP_NINE, size, recordBounds ()) == \ | |
| 933 fWriter.size()); | |
| 787 addPaintPtr(paint); | 934 addPaintPtr(paint); |
| 788 addBitmap(bitmap); | 935 addBitmap(bitmap); |
| 789 addIRect(center); | 936 addIRect(center); |
| 790 addRect(dst); | 937 addRect(dst); |
| 791 validate(initialOffset, size); | 938 validate(initialOffset, size); |
| 792 } | 939 } |
| 793 | 940 |
| 794 void SkPictureRecord::drawSprite(const SkBitmap& bitmap, int left, int top, | 941 void SkPictureRecord::drawSprite(const SkBitmap& bitmap, int left, int top, |
| 795 const SkPaint* paint = NULL) { | 942 const SkPaint* paint) { |
| 796 // op + paint index + bitmap index + left + top | 943 // op + paint index + bitmap index + left + top |
| 797 uint32_t size = 5 * kUInt32Size; | 944 uint32_t size = 5 * kUInt32Size; |
| 798 uint32_t initialOffset = this->addDraw(DRAW_SPRITE, &size); | 945 uint32_t initialOffset; |
| 799 SkASSERT(initialOffset+getPaintOffset(DRAW_SPRITE, size) == fWriter.size()); | 946 // Note: Bounds encoding not supported. |
| 947 initialOffset = this->addDraw(DRAW_SPRITE, &size); | |
| 948 SkASSERT(initialOffset + getPaintOffset(DRAW_SPRITE, size, false) == fWriter .size()); | |
| 800 addPaintPtr(paint); | 949 addPaintPtr(paint); |
| 801 addBitmap(bitmap); | 950 addBitmap(bitmap); |
| 802 addInt(left); | 951 addInt(left); |
| 803 addInt(top); | 952 addInt(top); |
| 804 validate(initialOffset, size); | 953 validate(initialOffset, size); |
| 805 } | 954 } |
| 806 | 955 |
| 807 // Return fontmetrics.fTop,fBottom in topbot[0,1], after they have been | 956 // Return fontmetrics.fTop,fBottom in topbot[0,1], after they have been |
| 808 // tweaked by paint.computeFastBounds(). | 957 // tweaked by paint.computeFastBounds(). |
| 809 // | 958 // |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 823 SkScalar minY, SkScalar maxY) { | 972 SkScalar minY, SkScalar maxY) { |
| 824 if (!flat.isTopBotWritten()) { | 973 if (!flat.isTopBotWritten()) { |
| 825 computeFontMetricsTopBottom(paint, flat.writableTopBot()); | 974 computeFontMetricsTopBottom(paint, flat.writableTopBot()); |
| 826 SkASSERT(flat.isTopBotWritten()); | 975 SkASSERT(flat.isTopBotWritten()); |
| 827 } | 976 } |
| 828 addScalar(flat.topBot()[0] + minY); | 977 addScalar(flat.topBot()[0] + minY); |
| 829 addScalar(flat.topBot()[1] + maxY); | 978 addScalar(flat.topBot()[1] + maxY); |
| 830 } | 979 } |
| 831 | 980 |
| 832 void SkPictureRecord::drawText(const void* text, size_t byteLength, SkScalar x, | 981 void SkPictureRecord::drawText(const void* text, size_t byteLength, SkScalar x, |
| 833 SkScalar y, const SkPaint& paint) { | 982 SkScalar y, const SkPaint& paint) { |
|
robertphillips
2013/03/06 23:02:02
// We disallow DRAW_TEXT_TOP_BOTTOM when saving bo
| |
| 834 bool fast = !paint.isVerticalText() && paint.canComputeFastBounds(); | 983 bool fast = !paint.isVerticalText() && paint.canComputeFastBounds() && |
| 984 (fRecordFlags & SkPicture::kRecordBounds_RecordingFlag) == 0; | |
| 835 | 985 |
| 836 // op + paint index + length + 'length' worth of chars + x + y | 986 // op + paint index + length + 'length' worth of chars + x + y |
| 837 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * sizeof(SkScalar ); | 987 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * sizeof(SkScalar ); |
| 838 if (fast) { | 988 if (fast) { |
| 839 size += 2 * sizeof(SkScalar); // + top & bottom | 989 size += 2 * sizeof(SkScalar); // + top & bottom |
| 840 } | 990 } |
| 841 | 991 |
| 842 DrawType op = fast ? DRAW_TEXT_TOP_BOTTOM : DRAW_TEXT; | 992 DrawType op = fast ? DRAW_TEXT_TOP_BOTTOM : DRAW_TEXT; |
| 843 uint32_t initialOffset = this->addDraw(op, &size); | 993 uint32_t initialOffset; |
| 844 SkASSERT(initialOffset+getPaintOffset(op, size) == fWriter.size()); | 994 if (recordBounds()) { |
| 995 SkRect bbox; | |
| 996 paint.measureText(text, byteLength, &bbox); | |
| 997 SkPaint::FontMetrics metrics; | |
| 998 paint.getFontMetrics(&metrics); | |
| 999 | |
| 1000 // Vertical and aligned text need to be offset | |
| 1001 if (paint.isVerticalText()) { | |
| 1002 SkScalar h = bbox.fBottom - bbox.fTop; | |
| 1003 if (paint.getTextAlign() == SkPaint::kCenter_Align) { | |
| 1004 bbox.fTop -= h / 2; | |
| 1005 bbox.fBottom -= h / 2; | |
| 1006 } | |
| 1007 // Pad top and bottom with max extents from FontMetrics | |
| 1008 bbox.fBottom += metrics.fBottom; | |
| 1009 bbox.fTop += metrics.fTop; | |
| 1010 } else { | |
| 1011 SkScalar w = bbox.fRight - bbox.fLeft; | |
| 1012 if (paint.getTextAlign() == SkPaint::kCenter_Align) { | |
| 1013 bbox.fLeft -= w / 2; | |
| 1014 bbox.fRight -= w / 2; | |
| 1015 } else if (paint.getTextAlign() == SkPaint::kRight_Align) { | |
| 1016 bbox.fLeft -= w; | |
| 1017 bbox.fRight -= w; | |
| 1018 } | |
| 1019 // Set vertical bounds to max extents from font metrics | |
| 1020 bbox.fTop = metrics.fTop; | |
| 1021 bbox.fBottom = metrics.fBottom; | |
| 1022 } | |
| 1023 | |
| 1024 // Pad horizontal bounds on each side by half of max vertical extents (t his is sort of | |
| 1025 // arbitrary, but seems to produce reasonable results, if there were a w ay of getting max | |
| 1026 // glyph X-extents to pad by, that may be better here, but FontMetrics f XMin and fXMax seem | |
| 1027 // incorrect on most platforms (too small in Linux, never even set in Wi ndows). | |
| 1028 SkScalar pad = (metrics.fBottom - metrics.fTop) / 2; | |
| 1029 bbox.fLeft -= pad; | |
| 1030 bbox.fRight += pad; | |
| 1031 | |
| 1032 bbox.fLeft += x; | |
| 1033 bbox.fRight += x; | |
| 1034 bbox.fTop += y; | |
| 1035 bbox.fBottom += y; | |
| 1036 initialOffset = this->addDrawWithBounds(op, &size, &paint, &bbox); | |
| 1037 if (fLastDrawRejected) { | |
| 1038 return; | |
| 1039 } | |
| 1040 } else { | |
| 1041 initialOffset = this->addDraw(op, &size); | |
| 1042 } | |
| 1043 SkASSERT(initialOffset + getPaintOffset(op, size, recordBounds()) == fWriter .size()); | |
| 845 const SkFlatData* flatPaintData = addPaint(paint); | 1044 const SkFlatData* flatPaintData = addPaint(paint); |
| 846 SkASSERT(flatPaintData); | 1045 SkASSERT(flatPaintData); |
| 847 addText(text, byteLength); | 1046 addText(text, byteLength); |
| 848 addScalar(x); | 1047 addScalar(x); |
| 849 addScalar(y); | 1048 addScalar(y); |
| 850 if (fast) { | 1049 if (fast) { |
| 851 addFontMetricsTopBottom(paint, *flatPaintData, y, y); | 1050 addFontMetricsTopBottom(paint, *flatPaintData, y, y); |
| 852 } | 1051 } |
| 853 validate(initialOffset, size); | 1052 validate(initialOffset, size); |
| 854 } | 1053 } |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 870 canUseDrawH = false; | 1069 canUseDrawH = false; |
| 871 if (pos[index].fY < minY) { | 1070 if (pos[index].fY < minY) { |
| 872 minY = pos[index].fY; | 1071 minY = pos[index].fY; |
| 873 } else if (pos[index].fY > maxY) { | 1072 } else if (pos[index].fY > maxY) { |
| 874 maxY = pos[index].fY; | 1073 maxY = pos[index].fY; |
| 875 } | 1074 } |
| 876 } | 1075 } |
| 877 } | 1076 } |
| 878 } | 1077 } |
| 879 | 1078 |
| 880 bool fastBounds = !paint.isVerticalText() && paint.canComputeFastBounds(); | 1079 bool fastBounds = !paint.isVerticalText() && paint.canComputeFastBounds() && |
| 1080 (fRecordFlags & SkPicture::kRecordBounds_RecordingFlag) == 0; | |
| 881 bool fast = canUseDrawH && fastBounds; | 1081 bool fast = canUseDrawH && fastBounds; |
| 882 | 1082 |
| 883 // op + paint index + length + 'length' worth of data + num points | 1083 // op + paint index + length + 'length' worth of data + num points |
| 884 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size; | 1084 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size; |
| 885 if (canUseDrawH) { | 1085 if (canUseDrawH) { |
| 886 if (fast) { | 1086 if (fast) { |
| 887 size += 2 * sizeof(SkScalar); // + top & bottom | 1087 size += 2 * sizeof(SkScalar); // + top & bottom |
| 888 } | 1088 } |
| 889 // + y-pos + actual x-point data | 1089 // + y-pos + actual x-point data |
| 890 size += sizeof(SkScalar) + points * sizeof(SkScalar); | 1090 size += sizeof(SkScalar) + points * sizeof(SkScalar); |
| 891 } else { | 1091 } else { |
| 892 // + x&y point data | 1092 // + x&y point data |
| 893 size += points * sizeof(SkPoint); | 1093 size += points * sizeof(SkPoint); |
| 894 if (fastBounds) { | 1094 if (fastBounds) { |
| 895 size += 2 * sizeof(SkScalar); // + top & bottom | 1095 size += 2 * sizeof(SkScalar); // + top & bottom |
| 896 } | 1096 } |
| 897 } | 1097 } |
| 898 | 1098 |
| 899 DrawType op; | 1099 DrawType op; |
| 900 if (fast) { | 1100 if (fast) { |
| 901 op = DRAW_POS_TEXT_H_TOP_BOTTOM; | 1101 op = DRAW_POS_TEXT_H_TOP_BOTTOM; |
| 902 } else if (canUseDrawH) { | 1102 } else if (canUseDrawH) { |
| 903 op = DRAW_POS_TEXT_H; | 1103 op = DRAW_POS_TEXT_H; |
| 904 } else if (fastBounds) { | 1104 } else if (fastBounds) { |
| 905 op = DRAW_POS_TEXT_TOP_BOTTOM; | 1105 op = DRAW_POS_TEXT_TOP_BOTTOM; |
| 906 } else { | 1106 } else { |
| 907 op = DRAW_POS_TEXT; | 1107 op = DRAW_POS_TEXT; |
| 908 } | 1108 } |
| 909 uint32_t initialOffset = this->addDraw(op, &size); | 1109 uint32_t initialOffset; |
| 910 SkASSERT(initialOffset+getPaintOffset(op, size) == fWriter.size()); | 1110 if (recordBounds()) { |
| 1111 SkRect bbox; | |
| 1112 bbox.set(pos, paint.countText(text, byteLength)); | |
| 1113 SkPaint::FontMetrics metrics; | |
| 1114 paint.getFontMetrics(&metrics); | |
| 1115 bbox.fTop += metrics.fTop; | |
| 1116 bbox.fBottom += metrics.fBottom; | |
| 1117 | |
| 1118 // pad on left and right by half of max vertical glyph extents | |
| 1119 SkScalar pad = (metrics.fTop - metrics.fBottom) / 2; | |
| 1120 bbox.fLeft += pad; | |
| 1121 bbox.fRight -= pad; | |
| 1122 initialOffset = this->addDrawWithBounds(op, &size, &paint, &bbox); | |
| 1123 if (fLastDrawRejected) { | |
| 1124 return; | |
| 1125 } | |
| 1126 } else { | |
| 1127 initialOffset = this->addDraw(op, &size); | |
| 1128 } | |
| 1129 SkASSERT(initialOffset + getPaintOffset(op, size, recordBounds()) == fWriter .size()); | |
| 911 const SkFlatData* flatPaintData = addPaint(paint); | 1130 const SkFlatData* flatPaintData = addPaint(paint); |
| 912 SkASSERT(flatPaintData); | 1131 SkASSERT(flatPaintData); |
| 913 addText(text, byteLength); | 1132 addText(text, byteLength); |
| 914 addInt(points); | 1133 addInt(points); |
| 915 | 1134 |
| 916 #ifdef SK_DEBUG_SIZE | 1135 #ifdef SK_DEBUG_SIZE |
| 917 size_t start = fWriter.size(); | 1136 size_t start = fWriter.size(); |
| 918 #endif | 1137 #endif |
| 919 if (canUseDrawH) { | 1138 if (canUseDrawH) { |
| 920 if (fast) { | 1139 if (fast) { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 937 validate(initialOffset, size); | 1156 validate(initialOffset, size); |
| 938 } | 1157 } |
| 939 | 1158 |
| 940 void SkPictureRecord::drawPosTextH(const void* text, size_t byteLength, | 1159 void SkPictureRecord::drawPosTextH(const void* text, size_t byteLength, |
| 941 const SkScalar xpos[], SkScalar constY, | 1160 const SkScalar xpos[], SkScalar constY, |
| 942 const SkPaint& paint) { | 1161 const SkPaint& paint) { |
| 943 size_t points = paint.countText(text, byteLength); | 1162 size_t points = paint.countText(text, byteLength); |
| 944 if (0 == points) | 1163 if (0 == points) |
| 945 return; | 1164 return; |
| 946 | 1165 |
| 947 bool fast = !paint.isVerticalText() && paint.canComputeFastBounds(); | 1166 bool fast = !paint.isVerticalText() && paint.canComputeFastBounds() && |
| 1167 (fRecordFlags & SkPicture::kRecordBounds_RecordingFlag) == 0; | |
| 948 | 1168 |
| 949 // op + paint index + length + 'length' worth of data + num points | 1169 // op + paint index + length + 'length' worth of data + num points |
| 950 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size; | 1170 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size; |
| 951 if (fast) { | 1171 if (fast) { |
| 952 size += 2 * sizeof(SkScalar); // + top & bottom | 1172 size += 2 * sizeof(SkScalar); // + top & bottom |
| 953 } | 1173 } |
| 954 // + y + the actual points | 1174 // + y + the actual points |
| 955 size += 1 * kUInt32Size + points * sizeof(SkScalar); | 1175 size += 1 * kUInt32Size + points * sizeof(SkScalar); |
| 956 | 1176 |
| 957 uint32_t initialOffset = this->addDraw(fast ? DRAW_POS_TEXT_H_TOP_BOTTOM : D RAW_POS_TEXT_H, | 1177 uint32_t initialOffset; |
| 958 &size); | 1178 if (recordBounds()) { |
| 1179 size_t numChars = paint.countText(text, byteLength); | |
| 1180 SkRect bbox; | |
| 1181 bbox.fLeft = xpos[0]; | |
| 1182 bbox.fRight = xpos[numChars - 1]; | |
| 1183 // if we had a guarantee that these will be monotonically increasing, th is could be sped up | |
| 1184 for (size_t i = 1; i < numChars; ++i) { | |
| 1185 if (xpos[i] < bbox.fLeft) { | |
| 1186 bbox.fLeft = xpos[i]; | |
| 1187 } | |
| 1188 if (xpos[i] > bbox.fRight) { | |
| 1189 bbox.fRight = xpos[i]; | |
| 1190 } | |
| 1191 } | |
| 1192 SkPaint::FontMetrics metrics; | |
| 1193 paint.getFontMetrics(&metrics); | |
| 1194 | |
| 1195 // pad horizontally by max glyph height | |
| 1196 SkScalar pad = (metrics.fTop - metrics.fBottom); | |
| 1197 bbox.fLeft += pad; | |
| 1198 bbox.fRight -= pad; | |
| 1199 | |
| 1200 bbox.fTop = metrics.fTop + constY; | |
| 1201 bbox.fBottom = metrics.fBottom + constY; | |
| 1202 initialOffset = this->addDrawWithBounds(DRAW_POS_TEXT_H, &size, &paint, &bbox); | |
| 1203 if (fLastDrawRejected) { | |
| 1204 return; | |
| 1205 } | |
| 1206 } else { | |
| 1207 initialOffset = this->addDraw(fast ? DRAW_POS_TEXT_H_TOP_BOTTOM : DRAW_P OS_TEXT_H, | |
| 1208 &size); | |
| 1209 } | |
| 1210 SkASSERT(initialOffset + getPaintOffset(DRAW_TEXT_ON_PATH, size, recordBound s()) \ | |
| 1211 == fWriter.size()); | |
| 959 const SkFlatData* flatPaintData = addPaint(paint); | 1212 const SkFlatData* flatPaintData = addPaint(paint); |
| 960 SkASSERT(flatPaintData); | 1213 SkASSERT(flatPaintData); |
| 961 addText(text, byteLength); | 1214 addText(text, byteLength); |
| 962 addInt(points); | 1215 addInt(points); |
| 963 | 1216 |
| 964 #ifdef SK_DEBUG_SIZE | 1217 #ifdef SK_DEBUG_SIZE |
| 965 size_t start = fWriter.size(); | 1218 size_t start = fWriter.size(); |
| 966 #endif | 1219 #endif |
| 967 if (fast) { | 1220 if (fast) { |
| 968 addFontMetricsTopBottom(paint, *flatPaintData, constY, constY); | 1221 addFontMetricsTopBottom(paint, *flatPaintData, constY, constY); |
| 969 } | 1222 } |
| 970 addScalar(constY); | 1223 addScalar(constY); |
| 971 fWriter.writeMul4(xpos, points * sizeof(SkScalar)); | 1224 fWriter.writeMul4(xpos, points * sizeof(SkScalar)); |
| 972 #ifdef SK_DEBUG_SIZE | 1225 #ifdef SK_DEBUG_SIZE |
| 973 fPointBytes += fWriter.size() - start; | 1226 fPointBytes += fWriter.size() - start; |
| 974 fPointWrites += points; | 1227 fPointWrites += points; |
| 975 #endif | 1228 #endif |
| 976 validate(initialOffset, size); | 1229 validate(initialOffset, size); |
| 977 } | 1230 } |
| 978 | 1231 |
| 979 void SkPictureRecord::drawTextOnPath(const void* text, size_t byteLength, | 1232 void SkPictureRecord::drawTextOnPath(const void* text, size_t byteLength, |
| 980 const SkPath& path, const SkMatrix* matrix, | 1233 const SkPath& path, const SkMatrix* matrix, |
| 981 const SkPaint& paint) { | 1234 const SkPaint& paint) { |
| 982 // op + paint index + length + 'length' worth of data + path index + matrix index | 1235 // op + paint index + length + 'length' worth of data + path index + matrix index |
| 983 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * kUInt32Size; | 1236 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * kUInt32Size; |
| 984 uint32_t initialOffset = this->addDraw(DRAW_TEXT_ON_PATH, &size); | 1237 uint32_t initialOffset; |
| 985 SkASSERT(initialOffset+getPaintOffset(DRAW_TEXT_ON_PATH, size) == fWriter.si ze()); | 1238 if (recordBounds()) { |
| 1239 SkRect bbox = path.getBounds(); | |
| 1240 SkPaint::FontMetrics metrics; | |
| 1241 paint.getFontMetrics(&metrics); | |
| 1242 // pad out all sides by the max glyph height above baseline | |
| 1243 SkScalar pad = metrics.fTop; | |
| 1244 bbox.fLeft += pad; | |
| 1245 bbox.fRight -= pad; | |
| 1246 bbox.fTop += pad; | |
| 1247 bbox.fBottom -= pad; | |
| 1248 initialOffset = this->addDrawWithBounds(DRAW_TEXT_ON_PATH, &size, &paint , &bbox); | |
| 1249 if (fLastDrawRejected) { | |
| 1250 return; | |
| 1251 } | |
| 1252 } else { | |
| 1253 initialOffset = this->addDraw(DRAW_TEXT_ON_PATH, &size); | |
| 1254 } | |
| 1255 SkASSERT(initialOffset + getPaintOffset(DRAW_TEXT_ON_PATH, size, recordBound s()) \ | |
| 1256 == fWriter.size()); | |
| 986 addPaint(paint); | 1257 addPaint(paint); |
| 987 addText(text, byteLength); | 1258 addText(text, byteLength); |
| 988 addPath(path); | 1259 addPath(path); |
| 989 addMatrixPtr(matrix); | 1260 addMatrixPtr(matrix); |
| 990 validate(initialOffset, size); | 1261 validate(initialOffset, size); |
| 991 } | 1262 } |
| 992 | 1263 |
| 993 void SkPictureRecord::drawPicture(SkPicture& picture) { | 1264 void SkPictureRecord::drawPicture(SkPicture& picture) { |
| 994 // op + picture index | 1265 // op + picture index |
| 995 uint32_t size = 2 * kUInt32Size; | 1266 uint32_t size = 2 * kUInt32Size; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1020 size += vertexCount * sizeof(SkPoint); // + uvs | 1291 size += vertexCount * sizeof(SkPoint); // + uvs |
| 1021 } | 1292 } |
| 1022 if (flags & DRAW_VERTICES_HAS_COLORS) { | 1293 if (flags & DRAW_VERTICES_HAS_COLORS) { |
| 1023 size += vertexCount * sizeof(SkColor); // + vert colors | 1294 size += vertexCount * sizeof(SkColor); // + vert colors |
| 1024 } | 1295 } |
| 1025 if (flags & DRAW_VERTICES_HAS_INDICES) { | 1296 if (flags & DRAW_VERTICES_HAS_INDICES) { |
| 1026 // + num indices + indices | 1297 // + num indices + indices |
| 1027 size += 1 * kUInt32Size + SkAlign4(indexCount * sizeof(uint16_t)); | 1298 size += 1 * kUInt32Size + SkAlign4(indexCount * sizeof(uint16_t)); |
| 1028 } | 1299 } |
| 1029 | 1300 |
| 1030 uint32_t initialOffset = this->addDraw(DRAW_VERTICES, &size); | 1301 uint32_t initialOffset; |
| 1031 SkASSERT(initialOffset+getPaintOffset(DRAW_VERTICES, size) == fWriter.size() ); | 1302 if (recordBounds()) { |
| 1303 SkRect bbox; | |
| 1304 bbox.set(vertices, vertexCount); | |
| 1305 initialOffset = this->addDrawWithBounds(DRAW_VERTICES, &size, &paint, &b box); | |
| 1306 if (fLastDrawRejected) { | |
| 1307 return; | |
| 1308 } | |
| 1309 } else { | |
| 1310 initialOffset = this->addDraw(DRAW_VERTICES, &size); | |
| 1311 } | |
| 1312 SkASSERT(initialOffset + getPaintOffset(DRAW_VERTICES, size, recordBounds()) \ | |
| 1313 == fWriter.size()); | |
| 1032 addPaint(paint); | 1314 addPaint(paint); |
| 1033 addInt(flags); | 1315 addInt(flags); |
| 1034 addInt(vmode); | 1316 addInt(vmode); |
| 1035 addInt(vertexCount); | 1317 addInt(vertexCount); |
| 1036 addPoints(vertices, vertexCount); | 1318 addPoints(vertices, vertexCount); |
| 1037 if (flags & DRAW_VERTICES_HAS_TEXS) { | 1319 if (flags & DRAW_VERTICES_HAS_TEXS) { |
| 1038 addPoints(texs, vertexCount); | 1320 addPoints(texs, vertexCount); |
| 1039 } | 1321 } |
| 1040 if (flags & DRAW_VERTICES_HAS_COLORS) { | 1322 if (flags & DRAW_VERTICES_HAS_COLORS) { |
| 1041 fWriter.writeMul4(colors, vertexCount * sizeof(SkColor)); | 1323 fWriter.writeMul4(colors, vertexCount * sizeof(SkColor)); |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1292 void SkPictureRecord::validateRegions() const { | 1574 void SkPictureRecord::validateRegions() const { |
| 1293 int count = fRegions.count(); | 1575 int count = fRegions.count(); |
| 1294 SkASSERT((unsigned) count < 0x1000); | 1576 SkASSERT((unsigned) count < 0x1000); |
| 1295 for (int index = 0; index < count; index++) { | 1577 for (int index = 0; index < count; index++) { |
| 1296 const SkFlatData* region = fRegions[index]; | 1578 const SkFlatData* region = fRegions[index]; |
| 1297 SkASSERT(region); | 1579 SkASSERT(region); |
| 1298 // region->validate(); | 1580 // region->validate(); |
| 1299 } | 1581 } |
| 1300 } | 1582 } |
| 1301 #endif | 1583 #endif |
| OLD | NEW |