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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
55 SkSafeUnref(fBitmapHeap); | 55 SkSafeUnref(fBitmapHeap); |
56 SkSafeUnref(fPathHeap); | 56 SkSafeUnref(fPathHeap); |
57 SkSafeUnref(fBoundingHierarchy); | 57 SkSafeUnref(fBoundingHierarchy); |
58 SkSafeUnref(fStateTree); | 58 SkSafeUnref(fStateTree); |
59 fFlattenableHeap.setBitmapStorage(NULL); | 59 fFlattenableHeap.setBitmapStorage(NULL); |
60 fPictureRefs.unrefAll(); | 60 fPictureRefs.unrefAll(); |
61 } | 61 } |
62 | 62 |
63 /////////////////////////////////////////////////////////////////////////////// | 63 /////////////////////////////////////////////////////////////////////////////// |
64 | 64 |
65 enum DrawTypeFlags { | |
66 kHasPaint_DrawTypeFlag = 1 << 0, | |
67 kModifiesState_DrawTypeFlag = 1 << 1, // modifes clip or matrix state | |
68 kCanRecordBounds_DrawTypeFlag = 1 << 2, | |
69 }; | |
70 | |
71 static const uint8_t gDrawTypeFlags[LAST_DRAWTYPE_ENUM + 1] = { | |
72 0, // UNUSED | |
73 kModifiesState_DrawTypeFlag, // CLIP_PATH | |
74 kModifiesState_DrawTypeFlag, // CLIP_REGION | |
75 kModifiesState_DrawTypeFlag, // CLIP_RECT | |
76 kModifiesState_DrawTypeFlag, // CLIP_RRECT | |
77 kModifiesState_DrawTypeFlag, // CONCAT | |
78 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_BITMAP | |
79 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_BITMAP_MATR IX | |
80 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_BITMAP_NINE | |
81 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_BITMAP_RECT _TO_RECT | |
82 0, // DRAW_CLEAR | |
83 0, // DRAW_DATA | |
84 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_OVAL | |
85 kHasPaint_DrawTypeFlag, // DRAW_PAINT | |
86 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_PATH | |
87 kModifiesState_DrawTypeFlag, // DRAW_PICTURE | |
88 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_POINTS | |
89 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_POS_TEXT | |
90 kHasPaint_DrawTypeFlag, // DRAW_POS_TEXT_TO P_BOTTOM | |
91 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_POS_TEXT_H | |
92 kHasPaint_DrawTypeFlag, // DRAW_POS_TEXT_H_ TOP_BOTTOM | |
93 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_RECT | |
94 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_RRECT | |
95 kHasPaint_DrawTypeFlag, // DRAW_SPRITE | |
96 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_TEXT | |
97 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_TEXT_ON_PAT H | |
98 kHasPaint_DrawTypeFlag, // DRAW_TEXT_TOP_BO TTOM | |
99 kHasPaint_DrawTypeFlag | kCanRecordBounds_DrawTypeFlag, // DRAW_VERTICES | |
100 kModifiesState_DrawTypeFlag, // RESTORE | |
101 kModifiesState_DrawTypeFlag, // ROTATE | |
102 kModifiesState_DrawTypeFlag, // SAVE | |
103 kHasPaint_DrawTypeFlag | kModifiesState_DrawTypeFlag, // SAVE_LAYER | |
104 kModifiesState_DrawTypeFlag, // SCALE | |
105 kModifiesState_DrawTypeFlag, // SET_MATRIX | |
106 kModifiesState_DrawTypeFlag, // SKEW | |
107 kModifiesState_DrawTypeFlag, // TRANSLATE | |
108 0, // NOOP | |
109 }; | |
110 | |
111 bool SkPictureRecord::canRecordBounds(DrawType op) { | |
112 #if SK_RECORD_BOUNDS_IN_PICTURE | |
113 SkASSERT((unsigned)op <= (unsigned)LAST_DRAWTYPE_ENUM); | |
114 return SkToBool(gDrawTypeFlags[op] & kCanRecordBounds_DrawTypeFlag); | |
115 #else | |
116 return false; | |
117 #endif | |
118 } | |
119 | |
120 static inline bool modifies_state(DrawType op) { | |
121 SkASSERT((unsigned)op <= (unsigned)LAST_DRAWTYPE_ENUM); | |
122 return SkToBool(gDrawTypeFlags[op] & kModifiesState_DrawTypeFlag); | |
123 } | |
124 | |
65 // Return the offset of the paint inside a given op's byte stream. A zero | 125 // 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 | 126 // return value means there is no paint (and you really shouldn't be calling |
67 // this method) | 127 // this method) |
68 static inline uint32_t getPaintOffset(DrawType op, uint32_t opSize) { | 128 static inline uint32_t getPaintOffset(DrawType op, uint32_t opSize) { |
69 // These offsets are where the paint would be if the op size doesn't overflo w | 129 // 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] = { | |
71 0, // UNUSED - no paint | |
72 0, // CLIP_PATH - no paint | |
73 0, // CLIP_REGION - no paint | |
74 0, // CLIP_RECT - no paint | |
75 0, // CLIP_RRECT - no paint | |
76 0, // CONCAT - no paint | |
77 1, // DRAW_BITMAP - right after op code | |
78 1, // DRAW_BITMAP_MATRIX - right after op code | |
79 1, // DRAW_BITMAP_NINE - right after op code | |
80 1, // DRAW_BITMAP_RECT_TO_RECT - right after op code | |
81 0, // DRAW_CLEAR - no paint | |
82 0, // DRAW_DATA - no paint | |
83 1, // DRAW_OVAL - right after op code | |
84 1, // DRAW_PAINT - right after op code | |
85 1, // DRAW_PATH - right after op code | |
86 0, // DRAW_PICTURE - no paint | |
87 1, // DRAW_POINTS - right after op code | |
88 1, // DRAW_POS_TEXT - right after op code | |
89 1, // DRAW_POS_TEXT_TOP_BOTTOM - right after op code | |
90 1, // DRAW_POS_TEXT_H - right after op code | |
91 1, // DRAW_POS_TEXT_H_TOP_BOTTOM - right after op code | |
92 1, // DRAW_RECT - right after op code | |
93 1, // DRAW_RRECT - right after op code | |
94 1, // DRAW_SPRITE - right after op code | |
95 1, // DRAW_TEXT - right after op code | |
96 1, // DRAW_TEXT_ON_PATH - right after op code | |
97 1, // DRAW_TEXT_TOP_BOTTOM - right after op code | |
98 1, // DRAW_VERTICES - right after op code | |
99 0, // RESTORE - no paint | |
100 0, // ROTATE - no paint | |
101 0, // SAVE - no paint | |
102 0, // SAVE_LAYER - see below - this paint's location varies | |
103 0, // SCALE - no paint | |
104 0, // SET_MATRIX - no paint | |
105 0, // SKEW - no paint | |
106 0, // TRANSLATE - no paint | |
107 0, // NOOP - no paint | |
108 }; | |
109 | |
110 SkASSERT(sizeof(gPaintOffsets) == LAST_DRAWTYPE_ENUM + 1); | |
111 SkASSERT((unsigned)op <= (unsigned)LAST_DRAWTYPE_ENUM); | 130 SkASSERT((unsigned)op <= (unsigned)LAST_DRAWTYPE_ENUM); |
112 | 131 |
113 int overflow = 0; | 132 int offset = sizeof(uint32_t); // storage for op and 24-bit size |
114 if (0 != (opSize & ~MASK_24) || opSize == MASK_24) { | 133 if (0 != (opSize & ~MASK_24) || opSize == MASK_24) { |
115 // This op's size overflows so an extra uint32_t will be written | 134 // This op's size overflows so an extra uint32_t will be written |
116 // after the op code | 135 // after the op code |
117 overflow = sizeof(uint32_t); | 136 offset += sizeof(uint32_t); |
137 } | |
138 if (SkPictureRecord::canRecordBounds(op)) { | |
139 offset += sizeof(SkIRect); | |
118 } | 140 } |
119 | 141 |
120 if (SAVE_LAYER == op) { | 142 if (SAVE_LAYER == op) { |
121 static const uint32_t kSaveLayerNoBoundsPaintOffset = 2 * kUInt32Size; | 143 static const uint32_t kSaveLayerNoBoundsPaintOffset = kUInt32Size; |
122 static const uint32_t kSaveLayerWithBoundsPaintOffset = 2 * kUInt32Size + sizeof(SkRect); | 144 static const uint32_t kSaveLayerWithBoundsPaintOffset = kUInt32Size + si zeof(SkRect); |
123 | 145 |
124 if (kSaveLayerNoBoundsSize == opSize) { | 146 if (kSaveLayerNoBoundsSize == opSize) { |
125 return kSaveLayerNoBoundsPaintOffset + overflow; | 147 offset += kSaveLayerNoBoundsPaintOffset; |
126 } else { | 148 } else { |
127 SkASSERT(kSaveLayerWithBoundsSize == opSize); | 149 SkASSERT(kSaveLayerWithBoundsSize == opSize); |
128 return kSaveLayerWithBoundsPaintOffset + overflow; | 150 offset += kSaveLayerWithBoundsPaintOffset; |
129 } | 151 } |
130 } | 152 } |
131 | 153 |
132 SkASSERT(0 != gPaintOffsets[op]); // really shouldn't be calling this meth od | 154 SkASSERT(kHasPaint_DrawTypeFlag & gDrawTypeFlags[op]); // Shouldn't be call ing this method |
133 return gPaintOffsets[op] * sizeof(uint32_t) + overflow; | 155 return offset; |
134 } | 156 } |
135 | 157 |
136 SkDevice* SkPictureRecord::setDevice(SkDevice* device) { | 158 SkDevice* SkPictureRecord::setDevice(SkDevice* device) { |
137 SkASSERT(!"eeek, don't try to change the device on a recording canvas"); | 159 SkASSERT(!"eeek, don't try to change the device on a recording canvas"); |
138 return this->INHERITED::setDevice(device); | 160 return this->INHERITED::setDevice(device); |
139 } | 161 } |
140 | 162 |
141 int SkPictureRecord::save(SaveFlags flags) { | 163 int SkPictureRecord::save(SaveFlags flags) { |
142 // record the offset to us, making it non-positive to distinguish a save | 164 // record the offset to us, making it non-positive to distinguish a save |
143 // from a clip entry. | 165 // from a clip entry. |
144 fRestoreOffsetStack.push(-(int32_t)fWriter.size()); | 166 fRestoreOffsetStack.push(-(int32_t)fWriter.size()); |
145 | 167 |
146 // op + flags | 168 // op + flags |
147 uint32_t size = 2 * kUInt32Size; | 169 uint32_t size = 2 * kUInt32Size; |
148 uint32_t initialOffset = this->addDraw(SAVE, &size); | 170 uint32_t initialOffset = this->addDraw(SAVE, &size); |
171 SkASSERT(kInvalidOffset != initialOffset); | |
149 addInt(flags); | 172 addInt(flags); |
150 | 173 |
151 validate(initialOffset, size); | 174 validate(initialOffset, size); |
152 return this->INHERITED::save(flags); | 175 return this->INHERITED::save(flags); |
153 } | 176 } |
154 | 177 |
155 int SkPictureRecord::saveLayer(const SkRect* bounds, const SkPaint* paint, | 178 int SkPictureRecord::saveLayer(const SkRect* bounds, const SkPaint* paint, |
156 SaveFlags flags) { | 179 SaveFlags flags) { |
157 // record the offset to us, making it non-positive to distinguish a save | 180 // record the offset to us, making it non-positive to distinguish a save |
158 // from a clip entry. | 181 // from a clip entry. |
159 fRestoreOffsetStack.push(-(int32_t)fWriter.size()); | 182 fRestoreOffsetStack.push(-(int32_t)fWriter.size()); |
160 | 183 |
161 // op + bool for 'bounds' | 184 // op + bool for 'bounds' |
162 uint32_t size = 2 * kUInt32Size; | 185 uint32_t size = 2 * kUInt32Size; |
163 if (NULL != bounds) { | 186 if (NULL != bounds) { |
164 size += sizeof(*bounds); // + rect | 187 size += sizeof(*bounds); // + rect |
165 } | 188 } |
166 // + paint index + flags | 189 // + paint index + flags |
167 size += 2 * kUInt32Size; | 190 size += 2 * kUInt32Size; |
168 | 191 |
169 SkASSERT(kSaveLayerNoBoundsSize == size || kSaveLayerWithBoundsSize == size) ; | 192 SkASSERT(kSaveLayerNoBoundsSize == size || kSaveLayerWithBoundsSize == size) ; |
170 | 193 |
171 uint32_t initialOffset = this->addDraw(SAVE_LAYER, &size); | 194 uint32_t initialOffset = this->addDraw(SAVE_LAYER, &size); |
195 SkASSERT(kInvalidOffset != initialOffset); | |
172 addRectPtr(bounds); | 196 addRectPtr(bounds); |
173 SkASSERT(initialOffset+getPaintOffset(SAVE_LAYER, size) == fWriter.size()); | 197 SkASSERT(initialOffset + getPaintOffset(SAVE_LAYER, size) == fWriter.size()) ; |
174 addPaintPtr(paint); | 198 addPaintPtr(paint); |
175 addInt(flags); | 199 addInt(flags); |
176 | 200 |
177 if (kNoSavedLayerIndex == fFirstSavedLayerIndex) { | 201 if (kNoSavedLayerIndex == fFirstSavedLayerIndex) { |
178 fFirstSavedLayerIndex = fRestoreOffsetStack.count(); | 202 fFirstSavedLayerIndex = fRestoreOffsetStack.count(); |
179 } | 203 } |
180 | 204 |
181 validate(initialOffset, size); | 205 validate(initialOffset, size); |
182 /* Don't actually call saveLayer, because that will try to allocate an | 206 /* Don't actually call saveLayer, because that will try to allocate an |
183 offscreen device (potentially very big) which we don't actually need | 207 offscreen device (potentially very big) which we don't actually need |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
420 if (!collapseSaveClipRestore(&fWriter, fRestoreOffsetStack.top()) && | 444 if (!collapseSaveClipRestore(&fWriter, fRestoreOffsetStack.top()) && |
421 !remove_save_layer1(&fWriter, fRestoreOffsetStack.top(), &fPaints)) { | 445 !remove_save_layer1(&fWriter, fRestoreOffsetStack.top(), &fPaints)) { |
422 fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.size ()); | 446 fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.size ()); |
423 // op | 447 // op |
424 size = 1 * kUInt32Size; | 448 size = 1 * kUInt32Size; |
425 initialOffset = this->addDraw(RESTORE, &size); | 449 initialOffset = this->addDraw(RESTORE, &size); |
426 } else { | 450 } else { |
427 size = 0; | 451 size = 0; |
428 initialOffset = fWriter.size(); | 452 initialOffset = fWriter.size(); |
429 } | 453 } |
454 SkASSERT(kInvalidOffset != initialOffset); | |
430 | 455 |
431 fRestoreOffsetStack.pop(); | 456 fRestoreOffsetStack.pop(); |
432 | 457 |
433 validate(initialOffset, size); | 458 validate(initialOffset, size); |
434 return this->INHERITED::restore(); | 459 return this->INHERITED::restore(); |
435 } | 460 } |
436 | 461 |
462 uint32_t SkPictureRecord::addDraw(DrawType drawType, uint32_t* size, | |
463 const SkPaint* paint, const SkRect* localBound s) { | |
464 SkIRect devClipBounds; // Bounds of the current clip in device space | |
465 if (!modifies_state(drawType) && !this->getClipDeviceBounds(&devClipBounds)) { | |
466 // Optimize-out calls that are clipped-out. State modifying commands | |
467 // can not be optimized-out because they may have an impact on future ca lls | |
468 // if the clip is ever expanded. For example, with a union clip op. | |
469 return kInvalidOffset; | |
470 } | |
471 #if SK_RECORD_BOUNDS_IN_PICTURE | |
472 bool writeBounds = canRecordBounds(drawType); | |
473 SkIRect clippedDevBounds; // Bounds of the clipped draw in device space | |
474 if (writeBounds) { | |
475 SkASSERT(!modifies_state(drawType)); // Ensure devClipBounds is initial ized | |
476 if (NULL == localBounds || (NULL != paint && !paint->canComputeFastBound s())) { | |
477 clippedDevBounds = devClipBounds; | |
478 } else { | |
479 SkRect paintBounds; | |
480 SkRect rectifiedBounds = *localBounds; | |
481 rectifiedBounds.sort(); | |
482 if (NULL != paint) { | |
483 if (drawType == DRAW_POINTS) { | |
484 paintBounds = paint->computeFastStrokeBounds(rectifiedBounds , &paintBounds); | |
485 } else { | |
486 paintBounds = paint->computeFastBounds(rectifiedBounds, &pai ntBounds); | |
487 } | |
488 } else { | |
489 paintBounds = *localBounds; | |
490 } | |
491 if (paintBounds.isEmpty()) { | |
492 // Area affected by draw op is empty even after accounting | |
493 // for stroke width. | |
494 return kInvalidOffset; | |
495 } | |
496 SkRect devBounds; | |
497 this->getTotalMatrix().mapRect(&devBounds, paintBounds); | |
498 devBounds.roundOut(&clippedDevBounds); | |
499 if (!clippedDevBounds.intersect(devClipBounds)) { | |
500 // Draw lies outside of clip. The clip can only get further | |
501 // restricted at playback time, so it is safe to reject during | |
502 // record stage. | |
503 return kInvalidOffset; | |
504 } | |
505 } | |
506 *size += sizeof(SkIRect); | |
507 } | |
508 #else | |
509 sk_ignore_unused_variable(paint); | |
510 sk_ignore_unused_variable(localBounds); | |
511 #endif | |
512 | |
513 uint32_t offset = fWriter.size(); | |
514 | |
515 this->predrawNotify(); | |
516 | |
robertphillips
2013/03/11 17:31:39
left justify the # commands?
Justin Novosad
2013/03/11 17:52:10
Done.
| |
517 #ifdef SK_DEBUG_TRACE | |
518 SkDebugf("add %s\n", DrawTypeToString(drawType)); | |
519 #endif | |
520 SkASSERT(0 != *size); | |
521 SkASSERT(((uint8_t) drawType) == drawType); | |
522 if (0 != (*size & ~MASK_24) || *size == MASK_24) { | |
523 fWriter.writeInt(PACK_8_24(drawType, MASK_24)); | |
524 *size += 1; | |
525 fWriter.writeInt(*size); | |
526 } else { | |
527 fWriter.writeInt(PACK_8_24(drawType, *size)); | |
528 } | |
529 | |
530 #if SK_RECORD_BOUNDS_IN_PICTURE | |
531 if (writeBounds) { | |
532 fWriter.write(&clippedDevBounds, sizeof(clippedDevBounds)); | |
533 } | |
534 #endif | |
535 | |
536 return offset; | |
537 } | |
538 | |
437 bool SkPictureRecord::translate(SkScalar dx, SkScalar dy) { | 539 bool SkPictureRecord::translate(SkScalar dx, SkScalar dy) { |
438 // op + dx + dy | 540 // op + dx + dy |
439 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); | 541 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); |
440 uint32_t initialOffset = this->addDraw(TRANSLATE, &size); | 542 uint32_t initialOffset = this->addDraw(TRANSLATE, &size); |
543 SkASSERT(kInvalidOffset != initialOffset); | |
441 addScalar(dx); | 544 addScalar(dx); |
442 addScalar(dy); | 545 addScalar(dy); |
443 validate(initialOffset, size); | 546 validate(initialOffset, size); |
444 return this->INHERITED::translate(dx, dy); | 547 return this->INHERITED::translate(dx, dy); |
445 } | 548 } |
446 | 549 |
447 bool SkPictureRecord::scale(SkScalar sx, SkScalar sy) { | 550 bool SkPictureRecord::scale(SkScalar sx, SkScalar sy) { |
448 // op + sx + sy | 551 // op + sx + sy |
449 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); | 552 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); |
450 uint32_t initialOffset = this->addDraw(SCALE, &size); | 553 uint32_t initialOffset = this->addDraw(SCALE, &size); |
554 SkASSERT(kInvalidOffset != initialOffset); | |
451 addScalar(sx); | 555 addScalar(sx); |
452 addScalar(sy); | 556 addScalar(sy); |
453 validate(initialOffset, size); | 557 validate(initialOffset, size); |
454 return this->INHERITED::scale(sx, sy); | 558 return this->INHERITED::scale(sx, sy); |
455 } | 559 } |
456 | 560 |
457 bool SkPictureRecord::rotate(SkScalar degrees) { | 561 bool SkPictureRecord::rotate(SkScalar degrees) { |
458 // op + degrees | 562 // op + degrees |
459 uint32_t size = 1 * kUInt32Size + sizeof(SkScalar); | 563 uint32_t size = 1 * kUInt32Size + sizeof(SkScalar); |
460 uint32_t initialOffset = this->addDraw(ROTATE, &size); | 564 uint32_t initialOffset = this->addDraw(ROTATE, &size); |
565 SkASSERT(kInvalidOffset != initialOffset); | |
461 addScalar(degrees); | 566 addScalar(degrees); |
462 validate(initialOffset, size); | 567 validate(initialOffset, size); |
463 return this->INHERITED::rotate(degrees); | 568 return this->INHERITED::rotate(degrees); |
464 } | 569 } |
465 | 570 |
466 bool SkPictureRecord::skew(SkScalar sx, SkScalar sy) { | 571 bool SkPictureRecord::skew(SkScalar sx, SkScalar sy) { |
467 // op + sx + sy | 572 // op + sx + sy |
468 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); | 573 uint32_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); |
469 uint32_t initialOffset = this->addDraw(SKEW, &size); | 574 uint32_t initialOffset = this->addDraw(SKEW, &size); |
575 SkASSERT(kInvalidOffset != initialOffset); | |
470 addScalar(sx); | 576 addScalar(sx); |
471 addScalar(sy); | 577 addScalar(sy); |
472 validate(initialOffset, size); | 578 validate(initialOffset, size); |
473 return this->INHERITED::skew(sx, sy); | 579 return this->INHERITED::skew(sx, sy); |
474 } | 580 } |
475 | 581 |
476 bool SkPictureRecord::concat(const SkMatrix& matrix) { | 582 bool SkPictureRecord::concat(const SkMatrix& matrix) { |
477 validate(fWriter.size(), 0); | 583 validate(fWriter.size(), 0); |
478 // op + matrix index | 584 // op + matrix index |
479 uint32_t size = 2 * kUInt32Size; | 585 uint32_t size = 2 * kUInt32Size; |
480 uint32_t initialOffset = this->addDraw(CONCAT, &size); | 586 uint32_t initialOffset = this->addDraw(CONCAT, &size); |
587 SkASSERT(kInvalidOffset != initialOffset); | |
481 addMatrix(matrix); | 588 addMatrix(matrix); |
482 validate(initialOffset, size); | 589 validate(initialOffset, size); |
483 return this->INHERITED::concat(matrix); | 590 return this->INHERITED::concat(matrix); |
484 } | 591 } |
485 | 592 |
486 void SkPictureRecord::setMatrix(const SkMatrix& matrix) { | 593 void SkPictureRecord::setMatrix(const SkMatrix& matrix) { |
487 validate(fWriter.size(), 0); | 594 validate(fWriter.size(), 0); |
488 // op + matrix index | 595 // op + matrix index |
489 uint32_t size = 2 * kUInt32Size; | 596 uint32_t size = 2 * kUInt32Size; |
490 uint32_t initialOffset = this->addDraw(SET_MATRIX, &size); | 597 uint32_t initialOffset = this->addDraw(SET_MATRIX, &size); |
598 SkASSERT(kInvalidOffset != initialOffset); | |
491 addMatrix(matrix); | 599 addMatrix(matrix); |
492 validate(initialOffset, size); | 600 validate(initialOffset, size); |
493 this->INHERITED::setMatrix(matrix); | 601 this->INHERITED::setMatrix(matrix); |
494 } | 602 } |
495 | 603 |
496 static bool regionOpExpands(SkRegion::Op op) { | 604 static bool regionOpExpands(SkRegion::Op op) { |
497 switch (op) { | 605 switch (op) { |
498 case SkRegion::kUnion_Op: | 606 case SkRegion::kUnion_Op: |
499 case SkRegion::kXOR_Op: | 607 case SkRegion::kXOR_Op: |
500 case SkRegion::kReverseDifference_Op: | 608 case SkRegion::kReverseDifference_Op: |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
562 | 670 |
563 bool SkPictureRecord::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { | 671 bool SkPictureRecord::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { |
564 // id + rect + clip params | 672 // id + rect + clip params |
565 uint32_t size = 1 * kUInt32Size + sizeof(rect) + 1 * kUInt32Size; | 673 uint32_t size = 1 * kUInt32Size + sizeof(rect) + 1 * kUInt32Size; |
566 // recordRestoreOffsetPlaceholder doesn't always write an offset | 674 // recordRestoreOffsetPlaceholder doesn't always write an offset |
567 if (!fRestoreOffsetStack.isEmpty()) { | 675 if (!fRestoreOffsetStack.isEmpty()) { |
568 // + restore offset | 676 // + restore offset |
569 size += kUInt32Size; | 677 size += kUInt32Size; |
570 } | 678 } |
571 uint32_t initialOffset = this->addDraw(CLIP_RECT, &size); | 679 uint32_t initialOffset = this->addDraw(CLIP_RECT, &size); |
680 SkASSERT(kInvalidOffset != initialOffset); | |
572 addRect(rect); | 681 addRect(rect); |
573 addInt(ClipParams_pack(op, doAA)); | 682 addInt(ClipParams_pack(op, doAA)); |
574 recordRestoreOffsetPlaceholder(op); | 683 recordRestoreOffsetPlaceholder(op); |
575 | 684 |
576 validate(initialOffset, size); | 685 validate(initialOffset, size); |
577 return this->INHERITED::clipRect(rect, op, doAA); | 686 return this->INHERITED::clipRect(rect, op, doAA); |
578 } | 687 } |
579 | 688 |
580 bool SkPictureRecord::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA ) { | 689 bool SkPictureRecord::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA ) { |
581 if (rrect.isRect()) { | 690 if (rrect.isRect()) { |
582 return this->SkPictureRecord::clipRect(rrect.getBounds(), op, doAA); | 691 return this->SkPictureRecord::clipRect(rrect.getBounds(), op, doAA); |
583 } | 692 } |
584 | 693 |
585 // op + rrect + clip params | 694 // op + rrect + clip params |
586 uint32_t size = 1 * kUInt32Size + SkRRect::kSizeInMemory + 1 * kUInt32Size; | 695 uint32_t size = 1 * kUInt32Size + SkRRect::kSizeInMemory + 1 * kUInt32Size; |
587 // recordRestoreOffsetPlaceholder doesn't always write an offset | 696 // recordRestoreOffsetPlaceholder doesn't always write an offset |
588 if (!fRestoreOffsetStack.isEmpty()) { | 697 if (!fRestoreOffsetStack.isEmpty()) { |
589 // + restore offset | 698 // + restore offset |
590 size += kUInt32Size; | 699 size += kUInt32Size; |
591 } | 700 } |
592 uint32_t initialOffset = this->addDraw(CLIP_RRECT, &size); | 701 uint32_t initialOffset = this->addDraw(CLIP_RRECT, &size); |
702 SkASSERT(kInvalidOffset != initialOffset); | |
593 addRRect(rrect); | 703 addRRect(rrect); |
594 addInt(ClipParams_pack(op, doAA)); | 704 addInt(ClipParams_pack(op, doAA)); |
595 recordRestoreOffsetPlaceholder(op); | 705 recordRestoreOffsetPlaceholder(op); |
596 | 706 |
597 validate(initialOffset, size); | 707 validate(initialOffset, size); |
598 | 708 |
599 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { | 709 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { |
600 return this->INHERITED::clipRect(rrect.getBounds(), op, doAA); | 710 return this->INHERITED::clipRect(rrect.getBounds(), op, doAA); |
601 } else { | 711 } else { |
602 return this->INHERITED::clipRRect(rrect, op, doAA); | 712 return this->INHERITED::clipRRect(rrect, op, doAA); |
603 } | 713 } |
604 } | 714 } |
605 | 715 |
606 bool SkPictureRecord::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { | 716 bool SkPictureRecord::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { |
607 | 717 |
608 SkRect r; | 718 SkRect r; |
609 if (!path.isInverseFillType() && path.isRect(&r)) { | 719 if (!path.isInverseFillType() && path.isRect(&r)) { |
610 return this->clipRect(r, op, doAA); | 720 return this->clipRect(r, op, doAA); |
611 } | 721 } |
612 | 722 |
613 // op + path index + clip params | 723 // op + path index + clip params |
614 uint32_t size = 3 * kUInt32Size; | 724 uint32_t size = 3 * kUInt32Size; |
615 // recordRestoreOffsetPlaceholder doesn't always write an offset | 725 // recordRestoreOffsetPlaceholder doesn't always write an offset |
616 if (!fRestoreOffsetStack.isEmpty()) { | 726 if (!fRestoreOffsetStack.isEmpty()) { |
617 // + restore offset | 727 // + restore offset |
618 size += kUInt32Size; | 728 size += kUInt32Size; |
619 } | 729 } |
620 uint32_t initialOffset = this->addDraw(CLIP_PATH, &size); | 730 uint32_t initialOffset = this->addDraw(CLIP_PATH, &size); |
731 SkASSERT(kInvalidOffset != initialOffset); | |
621 addPath(path); | 732 addPath(path); |
622 addInt(ClipParams_pack(op, doAA)); | 733 addInt(ClipParams_pack(op, doAA)); |
623 recordRestoreOffsetPlaceholder(op); | 734 recordRestoreOffsetPlaceholder(op); |
624 | 735 |
625 validate(initialOffset, size); | 736 validate(initialOffset, size); |
626 | 737 |
627 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { | 738 if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { |
628 return this->INHERITED::clipRect(path.getBounds(), op, doAA); | 739 return this->INHERITED::clipRect(path.getBounds(), op, doAA); |
629 } else { | 740 } else { |
630 return this->INHERITED::clipPath(path, op, doAA); | 741 return this->INHERITED::clipPath(path, op, doAA); |
631 } | 742 } |
632 } | 743 } |
633 | 744 |
634 bool SkPictureRecord::clipRegion(const SkRegion& region, SkRegion::Op op) { | 745 bool SkPictureRecord::clipRegion(const SkRegion& region, SkRegion::Op op) { |
635 // op + region index + clip params | 746 // op + region index + clip params |
636 uint32_t size = 3 * kUInt32Size; | 747 uint32_t size = 3 * kUInt32Size; |
637 // recordRestoreOffsetPlaceholder doesn't always write an offset | 748 // recordRestoreOffsetPlaceholder doesn't always write an offset |
638 if (!fRestoreOffsetStack.isEmpty()) { | 749 if (!fRestoreOffsetStack.isEmpty()) { |
639 // + restore offset | 750 // + restore offset |
640 size += kUInt32Size; | 751 size += kUInt32Size; |
641 } | 752 } |
642 uint32_t initialOffset = this->addDraw(CLIP_REGION, &size); | 753 uint32_t initialOffset = this->addDraw(CLIP_REGION, &size); |
754 SkASSERT(kInvalidOffset != initialOffset); | |
643 addRegion(region); | 755 addRegion(region); |
644 addInt(ClipParams_pack(op, false)); | 756 addInt(ClipParams_pack(op, false)); |
645 recordRestoreOffsetPlaceholder(op); | 757 recordRestoreOffsetPlaceholder(op); |
646 | 758 |
647 validate(initialOffset, size); | 759 validate(initialOffset, size); |
648 return this->INHERITED::clipRegion(region, op); | 760 return this->INHERITED::clipRegion(region, op); |
649 } | 761 } |
650 | 762 |
651 void SkPictureRecord::clear(SkColor color) { | 763 void SkPictureRecord::clear(SkColor color) { |
652 // op + color | 764 // op + color |
653 uint32_t size = 2 * kUInt32Size; | 765 uint32_t size = 2 * kUInt32Size; |
654 uint32_t initialOffset = this->addDraw(DRAW_CLEAR, &size); | 766 uint32_t initialOffset = this->addDraw(DRAW_CLEAR, &size); |
767 if (kInvalidOffset == initialOffset) { | |
768 return; | |
769 } | |
655 addInt(color); | 770 addInt(color); |
656 validate(initialOffset, size); | 771 validate(initialOffset, size); |
657 } | 772 } |
658 | 773 |
659 void SkPictureRecord::drawPaint(const SkPaint& paint) { | 774 void SkPictureRecord::drawPaint(const SkPaint& paint) { |
660 // op + paint index | 775 // op + paint index |
661 uint32_t size = 2 * kUInt32Size; | 776 uint32_t size = 2 * kUInt32Size; |
662 uint32_t initialOffset = this->addDraw(DRAW_PAINT, &size); | 777 uint32_t initialOffset = this->addDraw(DRAW_PAINT, &size); |
663 SkASSERT(initialOffset+getPaintOffset(DRAW_PAINT, size) == fWriter.size()); | 778 if (kInvalidOffset == initialOffset) { |
779 return; | |
780 } | |
781 SkASSERT(initialOffset + getPaintOffset(DRAW_PAINT, size) == fWriter.size()) ; | |
664 addPaint(paint); | 782 addPaint(paint); |
665 validate(initialOffset, size); | 783 validate(initialOffset, size); |
666 } | 784 } |
667 | 785 |
668 void SkPictureRecord::drawPoints(PointMode mode, size_t count, const SkPoint pts [], | 786 void SkPictureRecord::drawPoints(PointMode mode, size_t count, const SkPoint pts [], |
669 const SkPaint& paint) { | 787 const SkPaint& paint) { |
670 // op + paint index + mode + count + point data | 788 // op + paint index + mode + count + point data |
671 uint32_t size = 4 * kUInt32Size + count * sizeof(SkPoint); | 789 uint32_t size = 4 * kUInt32Size + count * sizeof(SkPoint); |
790 #if SK_RECORD_BOUNDS_IN_PICTURE | |
791 SkRect bbox; | |
792 bbox.set(pts, count); | |
793 uint32_t initialOffset = this->addDraw(DRAW_POINTS, &size, &paint, &bbox); | |
794 #else | |
672 uint32_t initialOffset = this->addDraw(DRAW_POINTS, &size); | 795 uint32_t initialOffset = this->addDraw(DRAW_POINTS, &size); |
673 SkASSERT(initialOffset+getPaintOffset(DRAW_POINTS, size) == fWriter.size()); | 796 #endif |
797 if (kInvalidOffset == initialOffset) { | |
798 return; | |
799 } | |
800 SkASSERT(initialOffset + getPaintOffset(DRAW_POINTS, size) == fWriter.size() ); | |
674 addPaint(paint); | 801 addPaint(paint); |
675 addInt(mode); | 802 addInt(mode); |
676 addInt(count); | 803 addInt(count); |
677 fWriter.writeMul4(pts, count * sizeof(SkPoint)); | 804 fWriter.writeMul4(pts, count * sizeof(SkPoint)); |
678 validate(initialOffset, size); | 805 validate(initialOffset, size); |
679 } | 806 } |
680 | 807 |
681 void SkPictureRecord::drawOval(const SkRect& oval, const SkPaint& paint) { | 808 void SkPictureRecord::drawOval(const SkRect& oval, const SkPaint& paint) { |
682 // op + paint index + rect | 809 // op + paint index + rect |
683 uint32_t size = 2 * kUInt32Size + sizeof(oval); | 810 uint32_t size = 2 * kUInt32Size + sizeof(oval); |
811 #if SK_RECORD_BOUNDS_IN_PICTURE | |
812 uint32_t initialOffset = this->addDraw(DRAW_OVAL, &size, &paint, &oval); | |
813 #else | |
684 uint32_t initialOffset = this->addDraw(DRAW_OVAL, &size); | 814 uint32_t initialOffset = this->addDraw(DRAW_OVAL, &size); |
685 SkASSERT(initialOffset+getPaintOffset(DRAW_OVAL, size) == fWriter.size()); | 815 #endif |
816 if (kInvalidOffset == initialOffset) { | |
817 return; | |
818 } | |
819 SkASSERT(initialOffset + getPaintOffset(DRAW_OVAL, size) == fWriter.size()); | |
686 addPaint(paint); | 820 addPaint(paint); |
687 addRect(oval); | 821 addRect(oval); |
688 validate(initialOffset, size); | 822 validate(initialOffset, size); |
689 } | 823 } |
690 | 824 |
691 void SkPictureRecord::drawRect(const SkRect& rect, const SkPaint& paint) { | 825 void SkPictureRecord::drawRect(const SkRect& rect, const SkPaint& paint) { |
692 // op + paint index + rect | 826 // op + paint index + rect |
693 uint32_t size = 2 * kUInt32Size + sizeof(rect); | 827 uint32_t size = 2 * kUInt32Size + sizeof(rect); |
828 #if SK_RECORD_BOUNDS_IN_PICTURE | |
829 uint32_t initialOffset = this->addDraw(DRAW_RECT, &size, &paint, &rect); | |
830 #else | |
694 uint32_t initialOffset = this->addDraw(DRAW_RECT, &size); | 831 uint32_t initialOffset = this->addDraw(DRAW_RECT, &size); |
695 SkASSERT(initialOffset+getPaintOffset(DRAW_RECT, size) == fWriter.size()); | 832 #endif |
833 if (kInvalidOffset == initialOffset) { | |
834 return; | |
835 } | |
836 SkASSERT(initialOffset + getPaintOffset(DRAW_RECT, size) == fWriter.size()); | |
696 addPaint(paint); | 837 addPaint(paint); |
697 addRect(rect); | 838 addRect(rect); |
698 validate(initialOffset, size); | 839 validate(initialOffset, size); |
699 } | 840 } |
700 | 841 |
701 void SkPictureRecord::drawRRect(const SkRRect& rrect, const SkPaint& paint) { | 842 void SkPictureRecord::drawRRect(const SkRRect& rrect, const SkPaint& paint) { |
702 uint32_t initialOffset, size; | |
703 if (rrect.isRect()) { | 843 if (rrect.isRect()) { |
704 // op + paint index + rect | 844 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()) { | 845 } else if (rrect.isOval()) { |
711 // op + paint index + rect | 846 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 { | 847 } else { |
718 // op + paint index + rrect | 848 // op + paint index + rrect |
719 size = 2 * kUInt32Size + SkRRect::kSizeInMemory; | 849 uint32_t size = 2 * kUInt32Size + SkRRect::kSizeInMemory; |
720 initialOffset = this->addDraw(DRAW_RRECT, &size); | 850 #if SK_RECORD_BOUNDS_IN_PICTURE |
721 SkASSERT(initialOffset+getPaintOffset(DRAW_RRECT, size) == fWriter.size( )); | 851 uint32_t initialOffset = this->addDraw(DRAW_RRECT, &size, &paint, &rrect .getBounds()); |
852 #else | |
853 uint32_t initialOffset = this->addDraw(DRAW_RRECT, &size); | |
854 #endif | |
855 if (kInvalidOffset == initialOffset) { | |
856 return; | |
857 } | |
858 SkASSERT(initialOffset + getPaintOffset(DRAW_RRECT, size) == fWriter.siz e()); | |
722 addPaint(paint); | 859 addPaint(paint); |
723 addRRect(rrect); | 860 addRRect(rrect); |
861 validate(initialOffset, size); | |
724 } | 862 } |
725 validate(initialOffset, size); | |
726 } | 863 } |
727 | 864 |
728 void SkPictureRecord::drawPath(const SkPath& path, const SkPaint& paint) { | 865 void SkPictureRecord::drawPath(const SkPath& path, const SkPaint& paint) { |
729 // op + paint index + path index | 866 // op + paint index + path index |
730 uint32_t size = 3 * kUInt32Size; | 867 uint32_t size = 3 * kUInt32Size; |
868 const SkRect* bounds = path.isInverseFillType() ? NULL : &path.getBounds(); | |
869 #if SK_RECORD_BOUNDS_IN_PICTURE | |
870 uint32_t initialOffset = this->addDraw(DRAW_PATH, &size, &paint, bounds); | |
871 #else | |
731 uint32_t initialOffset = this->addDraw(DRAW_PATH, &size); | 872 uint32_t initialOffset = this->addDraw(DRAW_PATH, &size); |
732 SkASSERT(initialOffset+getPaintOffset(DRAW_PATH, size) == fWriter.size()); | 873 #endif |
874 if (kInvalidOffset == initialOffset) { | |
875 return; | |
876 } | |
877 SkASSERT(initialOffset + getPaintOffset(DRAW_PATH, size) == fWriter.size()); | |
733 addPaint(paint); | 878 addPaint(paint); |
734 addPath(path); | 879 addPath(path); |
735 validate(initialOffset, size); | 880 validate(initialOffset, size); |
736 } | 881 } |
737 | 882 |
738 void SkPictureRecord::drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, | 883 void SkPictureRecord::drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, |
739 const SkPaint* paint = NULL) { | 884 const SkPaint* paint = NULL) { |
740 // op + paint index + bitmap index + left + top | 885 // op + paint index + bitmap index + left + top |
741 uint32_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar); | 886 uint32_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar); |
887 SkRect bounds = SkRect::MakeXYWH(left, top, bitmap.width(), bitmap.height()) ; | |
888 #if SK_RECORD_BOUNDS_IN_PICTURE | |
889 uint32_t initialOffset = this->addDraw(DRAW_BITMAP, &size, paint, &bounds); | |
890 #else | |
742 uint32_t initialOffset = this->addDraw(DRAW_BITMAP, &size); | 891 uint32_t initialOffset = this->addDraw(DRAW_BITMAP, &size); |
743 SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP, size) == fWriter.size()); | 892 #endif |
893 if (kInvalidOffset == initialOffset) { | |
894 return; | |
895 } | |
896 SkASSERT(initialOffset + getPaintOffset(DRAW_BITMAP, size) == fWriter.size() ); | |
744 addPaintPtr(paint); | 897 addPaintPtr(paint); |
745 addBitmap(bitmap); | 898 addBitmap(bitmap); |
746 addScalar(left); | 899 addScalar(left); |
747 addScalar(top); | 900 addScalar(top); |
748 validate(initialOffset, size); | 901 validate(initialOffset, size); |
749 } | 902 } |
750 | 903 |
751 void SkPictureRecord::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, | 904 void SkPictureRecord::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, |
752 const SkRect& dst, const SkPaint* paint) { | 905 const SkRect& dst, const SkPaint* paint) { |
753 // id + paint index + bitmap index + bool for 'src' | 906 // id + paint index + bitmap index + bool for 'src' |
754 uint32_t size = 4 * kUInt32Size; | 907 uint32_t size = 4 * kUInt32Size; |
755 if (NULL != src) { | 908 if (NULL != src) { |
756 size += sizeof(*src); // + rect | 909 size += sizeof(*src); // + rect |
757 } | 910 } |
758 size += sizeof(dst); // + rect | 911 size += sizeof(dst); // + rect |
759 | 912 |
913 #if SK_RECORD_BOUNDS_IN_PICTURE | |
914 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_RECT_TO_RECT, &size, pain t, &dst); | |
915 #else | |
760 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_RECT_TO_RECT, &size); | 916 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_RECT_TO_RECT, &size); |
761 SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP_RECT_TO_RECT, size) == fWr iter.size()); | 917 #endif |
918 if (kInvalidOffset == initialOffset) { | |
919 return; | |
920 } | |
921 SkASSERT(initialOffset + getPaintOffset(DRAW_BITMAP_RECT_TO_RECT, size) == f Writer.size()); | |
762 addPaintPtr(paint); | 922 addPaintPtr(paint); |
763 addBitmap(bitmap); | 923 addBitmap(bitmap); |
764 addRectPtr(src); // may be null | 924 addRectPtr(src); // may be null |
765 addRect(dst); | 925 addRect(dst); |
766 validate(initialOffset, size); | 926 validate(initialOffset, size); |
767 } | 927 } |
768 | 928 |
769 void SkPictureRecord::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m atrix, | 929 void SkPictureRecord::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m atrix, |
770 const SkPaint* paint) { | 930 const SkPaint* paint) { |
771 // id + paint index + bitmap index + matrix index | 931 // id + paint index + bitmap index + matrix index |
772 uint32_t size = 4 * kUInt32Size; | 932 uint32_t size = 4 * kUInt32Size; |
933 #if SK_RECORD_BOUNDS_IN_PICTURE | |
934 SkRect bounds = SkRect::MakeWH(bitmap.width(), bitmap.height()); | |
935 matrix.mapRect(&bounds); | |
936 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_MATRIX, &size, paint, &bo unds); | |
937 #else | |
773 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_MATRIX, &size); | 938 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_MATRIX, &size); |
774 SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP_MATRIX, size) == fWriter.s ize()); | 939 #endif |
940 if (kInvalidOffset == initialOffset) { | |
941 return; | |
942 } | |
943 SkASSERT(initialOffset + getPaintOffset(DRAW_BITMAP_MATRIX, size) == fWriter .size()); | |
775 addPaintPtr(paint); | 944 addPaintPtr(paint); |
776 addBitmap(bitmap); | 945 addBitmap(bitmap); |
777 addMatrix(matrix); | 946 addMatrix(matrix); |
778 validate(initialOffset, size); | 947 validate(initialOffset, size); |
779 } | 948 } |
780 | 949 |
781 void SkPictureRecord::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& cent er, | 950 void SkPictureRecord::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& cent er, |
782 const SkRect& dst, const SkPaint* paint) { | 951 const SkRect& dst, const SkPaint* paint) { |
783 // op + paint index + bitmap id + center + dst rect | 952 // op + paint index + bitmap id + center + dst rect |
784 uint32_t size = 3 * kUInt32Size + sizeof(center) + sizeof(dst); | 953 uint32_t size = 3 * kUInt32Size + sizeof(center) + sizeof(dst); |
954 #if SK_RECORD_BOUNDS_IN_PICTURE | |
955 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_NINE, &size, paint, &dst) ; | |
956 #else | |
785 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_NINE, &size); | 957 uint32_t initialOffset = this->addDraw(DRAW_BITMAP_NINE, &size); |
786 SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP_NINE, size) == fWriter.siz e()); | 958 #endif |
959 if (kInvalidOffset == initialOffset) { | |
960 return; | |
961 } | |
962 SkASSERT(initialOffset + getPaintOffset(DRAW_BITMAP_NINE, size) == fWriter.s ize()); | |
787 addPaintPtr(paint); | 963 addPaintPtr(paint); |
788 addBitmap(bitmap); | 964 addBitmap(bitmap); |
789 addIRect(center); | 965 addIRect(center); |
790 addRect(dst); | 966 addRect(dst); |
791 validate(initialOffset, size); | 967 validate(initialOffset, size); |
792 } | 968 } |
793 | 969 |
794 void SkPictureRecord::drawSprite(const SkBitmap& bitmap, int left, int top, | 970 void SkPictureRecord::drawSprite(const SkBitmap& bitmap, int left, int top, |
795 const SkPaint* paint = NULL) { | 971 const SkPaint* paint) { |
796 // op + paint index + bitmap index + left + top | 972 // op + paint index + bitmap index + left + top |
797 uint32_t size = 5 * kUInt32Size; | 973 uint32_t size = 5 * kUInt32Size; |
974 // Note: Bounds encoding not supported on drawSprite. Because drawSprite | |
975 // ignores the current transform matrix, the bounds will not follow the | |
976 // playback canvas's initial tranform matrix at playback time, and | |
977 // recorded bounds are assumed to be in the playback canvas' initial | |
978 // local frame of reference. | |
798 uint32_t initialOffset = this->addDraw(DRAW_SPRITE, &size); | 979 uint32_t initialOffset = this->addDraw(DRAW_SPRITE, &size); |
799 SkASSERT(initialOffset+getPaintOffset(DRAW_SPRITE, size) == fWriter.size()); | 980 if (kInvalidOffset == initialOffset) { |
981 return; | |
982 } | |
983 SkASSERT(initialOffset + getPaintOffset(DRAW_SPRITE, size) == fWriter.size() ); | |
800 addPaintPtr(paint); | 984 addPaintPtr(paint); |
801 addBitmap(bitmap); | 985 addBitmap(bitmap); |
802 addInt(left); | 986 addInt(left); |
803 addInt(top); | 987 addInt(top); |
804 validate(initialOffset, size); | 988 validate(initialOffset, size); |
805 } | 989 } |
806 | 990 |
807 // Return fontmetrics.fTop,fBottom in topbot[0,1], after they have been | 991 // Return fontmetrics.fTop,fBottom in topbot[0,1], after they have been |
808 // tweaked by paint.computeFastBounds(). | 992 // tweaked by paint.computeFastBounds(). |
809 // | 993 // |
810 static void computeFontMetricsTopBottom(const SkPaint& paint, SkScalar topbot[2] ) { | 994 static void computeFontMetricsTopBottom(const SkPaint& paint, SkScalar topbot[2] ) { |
811 SkPaint::FontMetrics metrics; | 995 SkPaint::FontMetrics metrics; |
812 paint.getFontMetrics(&metrics); | 996 paint.getFontMetrics(&metrics); |
813 SkRect bounds; | 997 SkRect bounds; |
814 // construct a rect so we can see any adjustments from the paint. | 998 // construct a rect so we can see any adjustments from the paint. |
815 // we use 0,1 for left,right, just so the rect isn't empty | 999 // we use 0,1 for left,right, just so the rect isn't empty |
816 bounds.set(0, metrics.fTop, SK_Scalar1, metrics.fBottom); | 1000 bounds.set(0, metrics.fTop, SK_Scalar1, metrics.fBottom); |
817 (void)paint.computeFastBounds(bounds, &bounds); | 1001 (void)paint.computeFastBounds(bounds, &bounds); |
818 topbot[0] = bounds.fTop; | 1002 topbot[0] = bounds.fTop; |
819 topbot[1] = bounds.fBottom; | 1003 topbot[1] = bounds.fBottom; |
820 } | 1004 } |
821 | 1005 |
1006 #if !(SK_RECORD_BOUNDS_IN_PICTURE) | |
822 void SkPictureRecord::addFontMetricsTopBottom(const SkPaint& paint, const SkFlat Data& flat, | 1007 void SkPictureRecord::addFontMetricsTopBottom(const SkPaint& paint, const SkFlat Data& flat, |
823 SkScalar minY, SkScalar maxY) { | 1008 SkScalar minY, SkScalar maxY) { |
824 if (!flat.isTopBotWritten()) { | 1009 if (!flat.isTopBotWritten()) { |
825 computeFontMetricsTopBottom(paint, flat.writableTopBot()); | 1010 computeFontMetricsTopBottom(paint, flat.writableTopBot()); |
826 SkASSERT(flat.isTopBotWritten()); | 1011 SkASSERT(flat.isTopBotWritten()); |
827 } | 1012 } |
828 addScalar(flat.topBot()[0] + minY); | 1013 addScalar(flat.topBot()[0] + minY); |
829 addScalar(flat.topBot()[1] + maxY); | 1014 addScalar(flat.topBot()[1] + maxY); |
830 } | 1015 } |
1016 #endif | |
1017 | |
1018 static void pad_text_bbox_horizontally(const SkPaint::FontMetrics& metrics, SkRe ct* bbox) { | |
1019 // Pad horizontal bounds on each side by max vertical extents. | |
1020 // This is sort of arbitrary, but seems to produce reasonable results. | |
1021 // If there were a way of getting max glyph X-extents to pad by, that | |
1022 // may be better here, but FontMetrics fXMin and fXMax seem incorrect | |
1023 // on most platforms (too small in Linux, never even set in Windows). | |
1024 SkScalar pad = (metrics.fBottom - metrics.fTop); | |
1025 SkASSERT(pad > 0); | |
1026 bbox->fLeft -= pad; | |
1027 bbox->fRight += pad; | |
1028 } | |
831 | 1029 |
832 void SkPictureRecord::drawText(const void* text, size_t byteLength, SkScalar x, | 1030 void SkPictureRecord::drawText(const void* text, size_t byteLength, SkScalar x, |
833 SkScalar y, const SkPaint& paint) { | 1031 SkScalar y, const SkPaint& paint) { |
834 bool fast = !paint.isVerticalText() && paint.canComputeFastBounds(); | 1032 // Note: The DRAW_TEXT_TOP_BOTTOM optimization is redundant if we are |
1033 // already recording full bounds. | |
835 | 1034 |
836 // op + paint index + length + 'length' worth of chars + x + y | 1035 // op + paint index + length + 'length' worth of chars + x + y |
837 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * sizeof(SkScalar ); | 1036 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * sizeof(SkScalar ); |
1037 | |
1038 #if SK_RECORD_BOUNDS_IN_PICTURE | |
1039 SkRect bbox; | |
1040 paint.measureText(text, byteLength, &bbox); | |
1041 SkPaint::FontMetrics metrics; | |
1042 paint.getFontMetrics(&metrics); | |
1043 | |
1044 // Vertical and aligned text need to be offset | |
1045 if (paint.isVerticalText()) { | |
1046 SkScalar h = bbox.fBottom - bbox.fTop; | |
1047 if (paint.getTextAlign() == SkPaint::kCenter_Align) { | |
1048 bbox.fTop -= h / 2; | |
1049 bbox.fBottom -= h / 2; | |
1050 } | |
1051 // Pad top and bottom with max extents from FontMetrics | |
1052 bbox.fBottom += metrics.fBottom; | |
1053 bbox.fTop += metrics.fTop; | |
1054 } else { | |
1055 SkScalar w = bbox.fRight - bbox.fLeft; | |
1056 if (paint.getTextAlign() == SkPaint::kCenter_Align) { | |
1057 bbox.fLeft -= w / 2; | |
1058 bbox.fRight -= w / 2; | |
1059 } else if (paint.getTextAlign() == SkPaint::kRight_Align) { | |
1060 bbox.fLeft -= w; | |
1061 bbox.fRight -= w; | |
1062 } | |
1063 // Set vertical bounds to max extents from font metrics | |
1064 bbox.fTop = metrics.fTop; | |
1065 bbox.fBottom = metrics.fBottom; | |
1066 } | |
1067 pad_text_bbox_horizontally(metrics, &bbox); | |
1068 bbox.fLeft += x; | |
1069 bbox.fRight += x; | |
1070 bbox.fTop += y; | |
1071 bbox.fBottom += y; | |
1072 uint32_t initialOffset = this->addDraw(DRAW_TEXT, &size, &paint, &bbox); | |
1073 #else | |
1074 bool fast = !paint.isVerticalText() && paint.canComputeFastBounds(); | |
1075 | |
838 if (fast) { | 1076 if (fast) { |
839 size += 2 * sizeof(SkScalar); // + top & bottom | 1077 size += 2 * sizeof(SkScalar); // + top & bottom |
840 } | 1078 } |
841 | |
842 DrawType op = fast ? DRAW_TEXT_TOP_BOTTOM : DRAW_TEXT; | 1079 DrawType op = fast ? DRAW_TEXT_TOP_BOTTOM : DRAW_TEXT; |
843 uint32_t initialOffset = this->addDraw(op, &size); | 1080 uint32_t initialOffset = this->addDraw(op, &size); |
844 SkASSERT(initialOffset+getPaintOffset(op, size) == fWriter.size()); | 1081 #endif |
1082 if (kInvalidOffset == initialOffset) { | |
1083 return; | |
1084 } | |
1085 #if SK_RECORD_BOUNDS_IN_PICTURE | |
1086 SkASSERT(initialOffset + getPaintOffset(DRAW_TEXT, size) == fWriter.size()); | |
1087 #else | |
1088 SkASSERT(initialOffset + getPaintOffset(op, size) == fWriter.size()); | |
1089 #endif | |
845 const SkFlatData* flatPaintData = addPaint(paint); | 1090 const SkFlatData* flatPaintData = addPaint(paint); |
846 SkASSERT(flatPaintData); | 1091 SkASSERT(flatPaintData); |
847 addText(text, byteLength); | 1092 addText(text, byteLength); |
848 addScalar(x); | 1093 addScalar(x); |
849 addScalar(y); | 1094 addScalar(y); |
1095 #if !(SK_RECORD_BOUNDS_IN_PICTURE) | |
850 if (fast) { | 1096 if (fast) { |
851 addFontMetricsTopBottom(paint, *flatPaintData, y, y); | 1097 addFontMetricsTopBottom(paint, *flatPaintData, y, y); |
852 } | 1098 } |
1099 #endif | |
853 validate(initialOffset, size); | 1100 validate(initialOffset, size); |
854 } | 1101 } |
855 | 1102 |
856 void SkPictureRecord::drawPosText(const void* text, size_t byteLength, | 1103 void SkPictureRecord::drawPosText(const void* text, size_t byteLength, |
857 const SkPoint pos[], const SkPaint& paint) { | 1104 const SkPoint pos[], const SkPaint& paint) { |
858 size_t points = paint.countText(text, byteLength); | 1105 size_t points = paint.countText(text, byteLength); |
859 if (0 == points) | 1106 if (0 == points) |
860 return; | 1107 return; |
861 | 1108 |
862 bool canUseDrawH = true; | 1109 bool canUseDrawH = true; |
863 SkScalar minY = pos[0].fY; | 1110 SkScalar minY = pos[0].fY; |
864 SkScalar maxY = pos[0].fY; | 1111 SkScalar maxY = pos[0].fY; |
865 // check if the caller really should have used drawPosTextH() | 1112 // check if the caller really should have used drawPosTextH() |
866 { | 1113 { |
867 const SkScalar firstY = pos[0].fY; | 1114 const SkScalar firstY = pos[0].fY; |
868 for (size_t index = 1; index < points; index++) { | 1115 for (size_t index = 1; index < points; index++) { |
869 if (pos[index].fY != firstY) { | 1116 if (pos[index].fY != firstY) { |
870 canUseDrawH = false; | 1117 canUseDrawH = false; |
871 if (pos[index].fY < minY) { | 1118 if (pos[index].fY < minY) { |
872 minY = pos[index].fY; | 1119 minY = pos[index].fY; |
873 } else if (pos[index].fY > maxY) { | 1120 } else if (pos[index].fY > maxY) { |
874 maxY = pos[index].fY; | 1121 maxY = pos[index].fY; |
875 } | 1122 } |
876 } | 1123 } |
877 } | 1124 } |
878 } | 1125 } |
879 | 1126 |
1127 // Note: The DRAW_TEXT_[H_]TOP_BOTTOM optimization is redundant if we are | |
1128 // already recording full bounds. | |
1129 #if !(SK_RECORD_BOUNDS_IN_PICTURE) | |
880 bool fastBounds = !paint.isVerticalText() && paint.canComputeFastBounds(); | 1130 bool fastBounds = !paint.isVerticalText() && paint.canComputeFastBounds(); |
881 bool fast = canUseDrawH && fastBounds; | 1131 bool fast = canUseDrawH && fastBounds; |
1132 #endif | |
882 | 1133 |
883 // op + paint index + length + 'length' worth of data + num points | 1134 // op + paint index + length + 'length' worth of data + num points |
884 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size; | 1135 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size; |
885 if (canUseDrawH) { | 1136 if (canUseDrawH) { |
1137 #if !(SK_RECORD_BOUNDS_IN_PICTURE) | |
886 if (fast) { | 1138 if (fast) { |
887 size += 2 * sizeof(SkScalar); // + top & bottom | 1139 size += 2 * sizeof(SkScalar); // + top & bottom |
888 } | 1140 } |
1141 #endif | |
889 // + y-pos + actual x-point data | 1142 // + y-pos + actual x-point data |
890 size += sizeof(SkScalar) + points * sizeof(SkScalar); | 1143 size += sizeof(SkScalar) + points * sizeof(SkScalar); |
891 } else { | 1144 } else { |
892 // + x&y point data | 1145 // + x&y point data |
893 size += points * sizeof(SkPoint); | 1146 size += points * sizeof(SkPoint); |
1147 #if !(SK_RECORD_BOUNDS_IN_PICTURE) | |
894 if (fastBounds) { | 1148 if (fastBounds) { |
895 size += 2 * sizeof(SkScalar); // + top & bottom | 1149 size += 2 * sizeof(SkScalar); // + top & bottom |
896 } | 1150 } |
1151 #endif | |
897 } | 1152 } |
898 | 1153 |
899 DrawType op; | 1154 DrawType op; |
1155 #if !(SK_RECORD_BOUNDS_IN_PICTURE) | |
900 if (fast) { | 1156 if (fast) { |
901 op = DRAW_POS_TEXT_H_TOP_BOTTOM; | 1157 op = DRAW_POS_TEXT_H_TOP_BOTTOM; |
902 } else if (canUseDrawH) { | 1158 } else |
1159 #endif | |
1160 if (canUseDrawH) { | |
903 op = DRAW_POS_TEXT_H; | 1161 op = DRAW_POS_TEXT_H; |
1162 #if !(SK_RECORD_BOUNDS_IN_PICTURE) | |
904 } else if (fastBounds) { | 1163 } else if (fastBounds) { |
905 op = DRAW_POS_TEXT_TOP_BOTTOM; | 1164 op = DRAW_POS_TEXT_TOP_BOTTOM; |
1165 #endif | |
906 } else { | 1166 } else { |
907 op = DRAW_POS_TEXT; | 1167 op = DRAW_POS_TEXT; |
908 } | 1168 } |
1169 #if SK_RECORD_BOUNDS_IN_PICTURE | |
1170 SkRect bbox; | |
1171 bbox.set(pos, paint.countText(text, byteLength)); | |
1172 SkPaint::FontMetrics metrics; | |
1173 paint.getFontMetrics(&metrics); | |
1174 bbox.fTop += metrics.fTop; | |
1175 bbox.fBottom += metrics.fBottom; | |
1176 | |
1177 // pad on left and right by half of max vertical glyph extents | |
1178 pad_text_bbox_horizontally(metrics, &bbox); | |
1179 uint32_t initialOffset = this->addDraw(op, &size, &paint, &bbox); | |
1180 #else | |
909 uint32_t initialOffset = this->addDraw(op, &size); | 1181 uint32_t initialOffset = this->addDraw(op, &size); |
910 SkASSERT(initialOffset+getPaintOffset(op, size) == fWriter.size()); | 1182 #endif |
1183 if (kInvalidOffset == initialOffset) { | |
1184 return; | |
1185 } | |
1186 SkASSERT(initialOffset + getPaintOffset(op, size) == fWriter.size()); | |
911 const SkFlatData* flatPaintData = addPaint(paint); | 1187 const SkFlatData* flatPaintData = addPaint(paint); |
912 SkASSERT(flatPaintData); | 1188 SkASSERT(flatPaintData); |
913 addText(text, byteLength); | 1189 addText(text, byteLength); |
914 addInt(points); | 1190 addInt(points); |
915 | 1191 |
916 #ifdef SK_DEBUG_SIZE | 1192 #ifdef SK_DEBUG_SIZE |
917 size_t start = fWriter.size(); | 1193 size_t start = fWriter.size(); |
918 #endif | 1194 #endif |
919 if (canUseDrawH) { | 1195 if (canUseDrawH) { |
1196 #if !(SK_RECORD_BOUNDS_IN_PICTURE) | |
920 if (fast) { | 1197 if (fast) { |
921 addFontMetricsTopBottom(paint, *flatPaintData, pos[0].fY, pos[0].fY) ; | 1198 addFontMetricsTopBottom(paint, *flatPaintData, pos[0].fY, pos[0].fY) ; |
922 } | 1199 } |
1200 #endif | |
923 addScalar(pos[0].fY); | 1201 addScalar(pos[0].fY); |
924 SkScalar* xptr = (SkScalar*)fWriter.reserve(points * sizeof(SkScalar)); | 1202 SkScalar* xptr = (SkScalar*)fWriter.reserve(points * sizeof(SkScalar)); |
925 for (size_t index = 0; index < points; index++) | 1203 for (size_t index = 0; index < points; index++) |
926 *xptr++ = pos[index].fX; | 1204 *xptr++ = pos[index].fX; |
927 } else { | 1205 } else { |
928 fWriter.writeMul4(pos, points * sizeof(SkPoint)); | 1206 fWriter.writeMul4(pos, points * sizeof(SkPoint)); |
1207 #if !(SK_RECORD_BOUNDS_IN_PICTURE) | |
929 if (fastBounds) { | 1208 if (fastBounds) { |
930 addFontMetricsTopBottom(paint, *flatPaintData, minY, maxY); | 1209 addFontMetricsTopBottom(paint, *flatPaintData, minY, maxY); |
931 } | 1210 } |
1211 #endif | |
932 } | 1212 } |
933 #ifdef SK_DEBUG_SIZE | 1213 #ifdef SK_DEBUG_SIZE |
934 fPointBytes += fWriter.size() - start; | 1214 fPointBytes += fWriter.size() - start; |
935 fPointWrites += points; | 1215 fPointWrites += points; |
936 #endif | 1216 #endif |
937 validate(initialOffset, size); | 1217 validate(initialOffset, size); |
938 } | 1218 } |
939 | 1219 |
940 void SkPictureRecord::drawPosTextH(const void* text, size_t byteLength, | 1220 void SkPictureRecord::drawPosTextH(const void* text, size_t byteLength, |
941 const SkScalar xpos[], SkScalar constY, | 1221 const SkScalar xpos[], SkScalar constY, |
942 const SkPaint& paint) { | 1222 const SkPaint& paint) { |
943 size_t points = paint.countText(text, byteLength); | 1223 size_t numChars = paint.countText(text, byteLength); |
944 if (0 == points) | 1224 if (0 == numChars) |
945 return; | 1225 return; |
946 | 1226 |
947 bool fast = !paint.isVerticalText() && paint.canComputeFastBounds(); | |
948 | |
949 // op + paint index + length + 'length' worth of data + num points | 1227 // op + paint index + length + 'length' worth of data + num points |
950 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size; | 1228 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size; |
1229 | |
1230 // Note: The DRAW_POS_TEXT_H_TOP_BOTTOM optimization is redundant if we are | |
1231 // already recording full bounds. | |
1232 #if !(SK_RECORD_BOUNDS_IN_PICTURE) | |
1233 bool fast = !paint.isVerticalText() && paint.canComputeFastBounds(); | |
951 if (fast) { | 1234 if (fast) { |
952 size += 2 * sizeof(SkScalar); // + top & bottom | 1235 size += 2 * sizeof(SkScalar); // + top & bottom |
953 } | 1236 } |
1237 #endif | |
1238 | |
954 // + y + the actual points | 1239 // + y + the actual points |
955 size += 1 * kUInt32Size + points * sizeof(SkScalar); | 1240 size += 1 * kUInt32Size + numChars * sizeof(SkScalar); |
956 | 1241 |
1242 #if SK_RECORD_BOUNDS_IN_PICTURE | |
1243 SkRect bbox; | |
1244 bbox.fLeft = xpos[0]; | |
1245 bbox.fRight = xpos[numChars - 1]; | |
1246 // if we had a guarantee that these will be monotonically increasing, this c ould be sped up | |
1247 for (size_t i = 0; i < numChars; ++i) { | |
1248 if (xpos[i] < bbox.fLeft) { | |
1249 bbox.fLeft = xpos[i]; | |
1250 } | |
1251 if (xpos[i] > bbox.fRight) { | |
1252 bbox.fRight = xpos[i]; | |
1253 } | |
1254 } | |
1255 SkPaint::FontMetrics metrics; | |
1256 paint.getFontMetrics(&metrics); | |
1257 pad_text_bbox_horizontally(metrics, &bbox); | |
1258 bbox.fTop = metrics.fTop + constY; | |
1259 bbox.fBottom = metrics.fBottom + constY; | |
1260 uint32_t initialOffset = this->addDraw(DRAW_POS_TEXT_H, &size, &paint, &bbox ); | |
1261 #else | |
957 uint32_t initialOffset = this->addDraw(fast ? DRAW_POS_TEXT_H_TOP_BOTTOM : D RAW_POS_TEXT_H, | 1262 uint32_t initialOffset = this->addDraw(fast ? DRAW_POS_TEXT_H_TOP_BOTTOM : D RAW_POS_TEXT_H, |
958 &size); | 1263 &size); |
1264 #endif | |
1265 if (kInvalidOffset == initialOffset) { | |
1266 return; | |
1267 } | |
1268 SkASSERT(initialOffset + getPaintOffset(DRAW_TEXT_ON_PATH, size) == fWriter. size()); | |
959 const SkFlatData* flatPaintData = addPaint(paint); | 1269 const SkFlatData* flatPaintData = addPaint(paint); |
960 SkASSERT(flatPaintData); | 1270 SkASSERT(flatPaintData); |
961 addText(text, byteLength); | 1271 addText(text, byteLength); |
962 addInt(points); | 1272 addInt(numChars); |
963 | 1273 |
964 #ifdef SK_DEBUG_SIZE | 1274 #ifdef SK_DEBUG_SIZE |
965 size_t start = fWriter.size(); | 1275 size_t start = fWriter.size(); |
966 #endif | 1276 #endif |
1277 #if !(SK_RECORD_BOUNDS_IN_PICTURE) | |
967 if (fast) { | 1278 if (fast) { |
968 addFontMetricsTopBottom(paint, *flatPaintData, constY, constY); | 1279 addFontMetricsTopBottom(paint, *flatPaintData, constY, constY); |
969 } | 1280 } |
1281 #endif | |
970 addScalar(constY); | 1282 addScalar(constY); |
971 fWriter.writeMul4(xpos, points * sizeof(SkScalar)); | 1283 fWriter.writeMul4(xpos, numChars * sizeof(SkScalar)); |
972 #ifdef SK_DEBUG_SIZE | 1284 #ifdef SK_DEBUG_SIZE |
973 fPointBytes += fWriter.size() - start; | 1285 fPointBytes += fWriter.size() - start; |
974 fPointWrites += points; | 1286 fPointWrites += points; |
975 #endif | 1287 #endif |
976 validate(initialOffset, size); | 1288 validate(initialOffset, size); |
977 } | 1289 } |
978 | 1290 |
979 void SkPictureRecord::drawTextOnPath(const void* text, size_t byteLength, | 1291 void SkPictureRecord::drawTextOnPath(const void* text, size_t byteLength, |
980 const SkPath& path, const SkMatrix* matrix, | 1292 const SkPath& path, const SkMatrix* matrix, |
981 const SkPaint& paint) { | 1293 const SkPaint& paint) { |
982 // op + paint index + length + 'length' worth of data + path index + matrix index | 1294 // op + paint index + length + 'length' worth of data + path index + matrix index |
983 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * kUInt32Size; | 1295 uint32_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * kUInt32Size; |
1296 #if SK_RECORD_BOUNDS_IN_PICTURE | |
1297 SkRect bbox = path.getBounds(); | |
1298 SkPaint::FontMetrics metrics; | |
1299 paint.getFontMetrics(&metrics); | |
1300 // pad out all sides by the max glyph height above baseline | |
1301 SkScalar pad = metrics.fTop; | |
1302 bbox.fLeft += pad; | |
1303 bbox.fRight -= pad; | |
1304 bbox.fTop += pad; | |
1305 bbox.fBottom -= pad; | |
1306 uint32_t initialOffset = this->addDraw(DRAW_TEXT_ON_PATH, &size, &paint, &bb ox); | |
1307 #else | |
984 uint32_t initialOffset = this->addDraw(DRAW_TEXT_ON_PATH, &size); | 1308 uint32_t initialOffset = this->addDraw(DRAW_TEXT_ON_PATH, &size); |
985 SkASSERT(initialOffset+getPaintOffset(DRAW_TEXT_ON_PATH, size) == fWriter.si ze()); | 1309 #endif |
1310 if (kInvalidOffset == initialOffset) { | |
1311 return; | |
1312 } | |
1313 SkASSERT(initialOffset + getPaintOffset(DRAW_TEXT_ON_PATH, size) == fWriter. size()); | |
986 addPaint(paint); | 1314 addPaint(paint); |
987 addText(text, byteLength); | 1315 addText(text, byteLength); |
988 addPath(path); | 1316 addPath(path); |
989 addMatrixPtr(matrix); | 1317 addMatrixPtr(matrix); |
990 validate(initialOffset, size); | 1318 validate(initialOffset, size); |
991 } | 1319 } |
992 | 1320 |
993 void SkPictureRecord::drawPicture(SkPicture& picture) { | 1321 void SkPictureRecord::drawPicture(SkPicture& picture) { |
994 // op + picture index | 1322 // op + picture index |
995 uint32_t size = 2 * kUInt32Size; | 1323 uint32_t size = 2 * kUInt32Size; |
996 uint32_t initialOffset = this->addDraw(DRAW_PICTURE, &size); | 1324 uint32_t initialOffset = this->addDraw(DRAW_PICTURE, &size); |
1325 SkASSERT(kInvalidOffset != initialOffset); | |
997 addPicture(picture); | 1326 addPicture(picture); |
998 validate(initialOffset, size); | 1327 validate(initialOffset, size); |
999 } | 1328 } |
1000 | 1329 |
1001 void SkPictureRecord::drawVertices(VertexMode vmode, int vertexCount, | 1330 void SkPictureRecord::drawVertices(VertexMode vmode, int vertexCount, |
1002 const SkPoint vertices[], const SkPoint texs[], | 1331 const SkPoint vertices[], const SkPoint texs[], |
1003 const SkColor colors[], SkXfermode*, | 1332 const SkColor colors[], SkXfermode*, |
1004 const uint16_t indices[], int indexCount, | 1333 const uint16_t indices[], int indexCount, |
1005 const SkPaint& paint) { | 1334 const SkPaint& paint) { |
1006 uint32_t flags = 0; | 1335 uint32_t flags = 0; |
(...skipping 12 matching lines...) Expand all Loading... | |
1019 if (flags & DRAW_VERTICES_HAS_TEXS) { | 1348 if (flags & DRAW_VERTICES_HAS_TEXS) { |
1020 size += vertexCount * sizeof(SkPoint); // + uvs | 1349 size += vertexCount * sizeof(SkPoint); // + uvs |
1021 } | 1350 } |
1022 if (flags & DRAW_VERTICES_HAS_COLORS) { | 1351 if (flags & DRAW_VERTICES_HAS_COLORS) { |
1023 size += vertexCount * sizeof(SkColor); // + vert colors | 1352 size += vertexCount * sizeof(SkColor); // + vert colors |
1024 } | 1353 } |
1025 if (flags & DRAW_VERTICES_HAS_INDICES) { | 1354 if (flags & DRAW_VERTICES_HAS_INDICES) { |
1026 // + num indices + indices | 1355 // + num indices + indices |
1027 size += 1 * kUInt32Size + SkAlign4(indexCount * sizeof(uint16_t)); | 1356 size += 1 * kUInt32Size + SkAlign4(indexCount * sizeof(uint16_t)); |
1028 } | 1357 } |
1029 | 1358 #if SK_RECORD_BOUNDS_IN_PICTURE |
1359 SkRect bbox; | |
1360 bbox.set(vertices, vertexCount); | |
1361 uint32_t initialOffset = this->addDraw(DRAW_VERTICES, &size, &paint, &bbox); | |
1362 #else | |
1030 uint32_t initialOffset = this->addDraw(DRAW_VERTICES, &size); | 1363 uint32_t initialOffset = this->addDraw(DRAW_VERTICES, &size); |
1031 SkASSERT(initialOffset+getPaintOffset(DRAW_VERTICES, size) == fWriter.size() ); | 1364 #endif |
1365 if (kInvalidOffset == initialOffset) { | |
1366 return; | |
1367 } | |
1368 SkASSERT(initialOffset + getPaintOffset(DRAW_VERTICES, size) == fWriter.size ()); | |
1032 addPaint(paint); | 1369 addPaint(paint); |
1033 addInt(flags); | 1370 addInt(flags); |
1034 addInt(vmode); | 1371 addInt(vmode); |
1035 addInt(vertexCount); | 1372 addInt(vertexCount); |
1036 addPoints(vertices, vertexCount); | 1373 addPoints(vertices, vertexCount); |
1037 if (flags & DRAW_VERTICES_HAS_TEXS) { | 1374 if (flags & DRAW_VERTICES_HAS_TEXS) { |
1038 addPoints(texs, vertexCount); | 1375 addPoints(texs, vertexCount); |
1039 } | 1376 } |
1040 if (flags & DRAW_VERTICES_HAS_COLORS) { | 1377 if (flags & DRAW_VERTICES_HAS_COLORS) { |
1041 fWriter.writeMul4(colors, vertexCount * sizeof(SkColor)); | 1378 fWriter.writeMul4(colors, vertexCount * sizeof(SkColor)); |
1042 } | 1379 } |
1043 if (flags & DRAW_VERTICES_HAS_INDICES) { | 1380 if (flags & DRAW_VERTICES_HAS_INDICES) { |
1044 addInt(indexCount); | 1381 addInt(indexCount); |
1045 fWriter.writePad(indices, indexCount * sizeof(uint16_t)); | 1382 fWriter.writePad(indices, indexCount * sizeof(uint16_t)); |
1046 } | 1383 } |
1047 validate(initialOffset, size); | 1384 validate(initialOffset, size); |
1048 } | 1385 } |
1049 | 1386 |
1050 void SkPictureRecord::drawData(const void* data, size_t length) { | 1387 void SkPictureRecord::drawData(const void* data, size_t length) { |
1051 // op + length + 'length' worth of data | 1388 // op + length + 'length' worth of data |
1052 uint32_t size = 2 * kUInt32Size + SkAlign4(length); | 1389 uint32_t size = 2 * kUInt32Size + SkAlign4(length); |
1053 uint32_t initialOffset = this->addDraw(DRAW_DATA, &size); | 1390 uint32_t initialOffset = this->addDraw(DRAW_DATA, &size); |
1391 SkASSERT(kInvalidOffset != initialOffset); | |
1054 addInt(length); | 1392 addInt(length); |
1055 fWriter.writePad(data, length); | 1393 fWriter.writePad(data, length); |
1056 validate(initialOffset, size); | 1394 validate(initialOffset, size); |
1057 } | 1395 } |
1058 | 1396 |
1059 /////////////////////////////////////////////////////////////////////////////// | 1397 /////////////////////////////////////////////////////////////////////////////// |
1060 | 1398 |
1061 void SkPictureRecord::addBitmap(const SkBitmap& bitmap) { | 1399 void SkPictureRecord::addBitmap(const SkBitmap& bitmap) { |
1062 const int index = fBitmapHeap->insert(bitmap); | 1400 const int index = fBitmapHeap->insert(bitmap); |
1063 // In debug builds, a bad return value from insert() will crash, allowing fo r debugging. In | 1401 // In debug builds, a bad return value from insert() will crash, allowing fo r debugging. In |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1292 void SkPictureRecord::validateRegions() const { | 1630 void SkPictureRecord::validateRegions() const { |
1293 int count = fRegions.count(); | 1631 int count = fRegions.count(); |
1294 SkASSERT((unsigned) count < 0x1000); | 1632 SkASSERT((unsigned) count < 0x1000); |
1295 for (int index = 0; index < count; index++) { | 1633 for (int index = 0; index < count; index++) { |
1296 const SkFlatData* region = fRegions[index]; | 1634 const SkFlatData* region = fRegions[index]; |
1297 SkASSERT(region); | 1635 SkASSERT(region); |
1298 // region->validate(); | 1636 // region->validate(); |
1299 } | 1637 } |
1300 } | 1638 } |
1301 #endif | 1639 #endif |
OLD | NEW |