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 |