Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(308)

Side by Side Diff: src/core/SkPictureRecord.cpp

Issue 12545009: Adding option in SkPicture to record device-space bounds of draw commands. (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« src/core/SkPicture.cpp ('K') | « src/core/SkPictureRecord.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« src/core/SkPicture.cpp ('K') | « src/core/SkPictureRecord.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698