@@ -40,22 +40,41 @@ void SkDrawableList::append(SkDrawable* drawable) {
4040
4141// /////////////////////////////////////////////////////////////////////////////////////////////
4242
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+
4357SkRecorder::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+ }
4864
4965SkRecorder::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+ }
5472
5573void SkRecorder::reset (SkRecord* record, const SkRect& bounds, SkMiniRecorder* mr) {
5674 this ->forgetRecord ();
5775 fRecord = record;
58- this ->resetCanvas (bounds.roundOut ());
76+ this ->resetCanvas (safe_picture_bounds (bounds));
77+ SkASSERT (this ->imageInfo ().width () >= 0 && this ->imageInfo ().height () >= 0 );
5978 fMiniRecorder = mr;
6079}
6180
0 commit comments