@@ -40,22 +40,41 @@ void SkDrawableList::append(SkDrawable* drawable) {
40
40
41
41
// /////////////////////////////////////////////////////////////////////////////////////////////
42
42
43
+ static SkIRect safe_picture_bounds (const SkRect& bounds) {
44
+ SkIRect picBounds = bounds.roundOut ();
45
+ // roundOut() saturates the float edges to +/-SK_MaxS32FitsInFloat (~2billion), but this is
46
+ // large enough that width/height calculations will overflow, leading to negative dimensions.
47
+ static constexpr int32_t kSafeEdge = SK_MaxS32FitsInFloat / 2 - 1 ;
48
+ static constexpr SkIRect kSafeBounds = {-kSafeEdge , -kSafeEdge , kSafeEdge , kSafeEdge };
49
+ static_assert ((kSafeBounds .fRight - kSafeBounds .fLeft ) >= 0 &&
50
+ (kSafeBounds .fBottom - kSafeBounds .fTop ) >= 0 );
51
+ if (!picBounds.intersect (kSafeBounds )) {
52
+ picBounds.setEmpty ();
53
+ }
54
+ return picBounds;
55
+ }
56
+
43
57
SkRecorder::SkRecorder (SkRecord* record, int width, int height, SkMiniRecorder* mr)
44
- : SkCanvasVirtualEnforcer<SkNoDrawCanvas>(width, height)
45
- , fApproxBytesUsedBySubPictures(0 )
46
- , fRecord(record)
47
- , fMiniRecorder(mr) {}
58
+ : SkCanvasVirtualEnforcer<SkNoDrawCanvas>(width, height)
59
+ , fApproxBytesUsedBySubPictures(0 )
60
+ , fRecord(record)
61
+ , fMiniRecorder(mr) {
62
+ SkASSERT (this ->imageInfo ().width () >= 0 && this ->imageInfo ().height () >= 0 );
63
+ }
48
64
49
65
SkRecorder::SkRecorder (SkRecord* record, const SkRect& bounds, SkMiniRecorder* mr)
50
- : SkCanvasVirtualEnforcer<SkNoDrawCanvas>(bounds.roundOut())
51
- , fApproxBytesUsedBySubPictures(0 )
52
- , fRecord(record)
53
- , fMiniRecorder(mr) {}
66
+ : SkCanvasVirtualEnforcer<SkNoDrawCanvas>(safe_picture_bounds(bounds))
67
+ , fApproxBytesUsedBySubPictures(0 )
68
+ , fRecord(record)
69
+ , fMiniRecorder(mr) {
70
+ SkASSERT (this ->imageInfo ().width () >= 0 && this ->imageInfo ().height () >= 0 );
71
+ }
54
72
55
73
void SkRecorder::reset (SkRecord* record, const SkRect& bounds, SkMiniRecorder* mr) {
56
74
this ->forgetRecord ();
57
75
fRecord = record;
58
- this ->resetCanvas (bounds.roundOut ());
76
+ this ->resetCanvas (safe_picture_bounds (bounds));
77
+ SkASSERT (this ->imageInfo ().width () >= 0 && this ->imageInfo ().height () >= 0 );
59
78
fMiniRecorder = mr;
60
79
}
61
80
0 commit comments