diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp index 24fc9064a6..9a0509c488 100644 --- a/src/core/SkDraw.cpp +++ b/src/core/SkDraw.cpp @@ -1457,10 +1457,13 @@ public: void operator()(const SkGlyph& glyph, SkPoint position, SkPoint rounding) { position += rounding; // Prevent glyphs from being drawn outside of or straddling the edge of device space. - if (position.fX > INT_MAX - (INT16_MAX + UINT16_MAX) || - position.fX < INT_MIN - (INT16_MIN + 0 /*UINT16_MIN*/) || - position.fY > INT_MAX - (INT16_MAX + UINT16_MAX) || - position.fY < INT_MIN - (INT16_MIN + 0 /*UINT16_MIN*/)) { + // Comparisons written a little weirdly so that NaN coordinates are treated safely. + auto gt = [](float a, int b) { return !(a <= (float)b); }; + auto lt = [](float a, int b) { return !(a >= (float)b); }; + if (gt(position.fX, INT_MAX - (INT16_MAX + UINT16_MAX)) || + lt(position.fX, INT_MIN - (INT16_MIN + 0 /*UINT16_MIN*/)) || + gt(position.fY, INT_MAX - (INT16_MAX + UINT16_MAX)) || + lt(position.fY, INT_MIN - (INT16_MIN + 0 /*UINT16_MIN*/))) { return; } @@ -1476,6 +1479,7 @@ public: SkMask mask; mask.fBounds.set(left, top, right, bottom); + SkASSERT(!mask.fBounds.isEmpty()); if (fUseRegionToDraw) { SkRegion::Cliperator clipper(*fClip, mask.fBounds); diff --git a/tests/DrawTextTest.cpp b/tests/DrawTextTest.cpp index f2da450fe8..bf9bd39f8d 100644 --- a/tests/DrawTextTest.cpp +++ b/tests/DrawTextTest.cpp @@ -11,8 +11,10 @@ #include "SkPaint.h" #include "SkPoint.h" #include "SkRect.h" +#include "SkSurface.h" #include "SkTypes.h" #include "Test.h" +#include static const SkColor bgColor = SK_ColorWHITE; @@ -111,3 +113,21 @@ DEF_TEST(DrawText, reporter) { } } } + +// Test drawing text at some unusual coordinates. +// We measure success by not crashing or asserting. +DEF_TEST(DrawText_weirdCoordinates, r) { + auto surface = SkSurface::MakeRasterN32Premul(10,10); + auto canvas = surface->getCanvas(); + + SkScalar oddballs[] = { 0.0f, (float)INFINITY, (float)NAN, 34359738368.0f }; + + for (auto x : oddballs) { + canvas->drawText("a", 1, +x, 0.0f, SkPaint()); + canvas->drawText("a", 1, -x, 0.0f, SkPaint()); + } + for (auto y : oddballs) { + canvas->drawText("a", 1, 0.0f, +y, SkPaint()); + canvas->drawText("a", 1, 0.0f, -y, SkPaint()); + } +}