diff --git a/src/pdf/SkPDFCanvas.cpp b/src/pdf/SkPDFCanvas.cpp index c5cde3d113..a0ab8f16f7 100644 --- a/src/pdf/SkPDFCanvas.cpp +++ b/src/pdf/SkPDFCanvas.cpp @@ -54,13 +54,47 @@ void SkPDFCanvas::onDrawImageNine(const SkImage* image, } } +static bool is_integer(SkScalar x) { + return x == SkScalarTruncToScalar(x); +} + +static bool is_integral(const SkRect& r) { + return is_integer(r.left()) && + is_integer(r.top()) && + is_integer(r.right()) && + is_integer(r.bottom()); +} + void SkPDFCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, const SkPaint* paint, SkCanvas::SrcRectConstraint constraint) { - SkAutoCanvasRestore autoCanvasRestore(this, true); - this->clipRect(dst); + SkASSERT(src); + SkASSERT(image); + if (paint && paint->getMaskFilter()) { + SkPaint paintCopy(*paint); + paintCopy.setAntiAlias(true); + SkRect srcRect = src ? *src : SkRect::Make(image->bounds()); + SkMatrix m = SkMatrix::MakeRectToRect(srcRect, dst, SkMatrix::kFill_ScaleToFit); + if (!src || *src == SkRect::Make(image->bounds()) || + SkCanvas::kFast_SrcRectConstraint == constraint) { + paintCopy.setShader(image->makeShader(&m)); + } else { + SkIRect subset = src->roundOut(); + m.preTranslate(subset.x(), subset.y()); + auto si = image->makeSubset(subset); + if (!si) { return; } + paintCopy.setShader(si->makeShader(&m)); + } + this->drawRect(dst, paintCopy); + return; + } + SkAutoCanvasRestore autoCanvasRestore(this, false); + if (src && !is_integral(*src)) { + this->save(); + this->clipRect(dst); + } this->SkCanvas::onDrawImageRect(image, src, dst, paint, constraint); } @@ -69,8 +103,18 @@ void SkPDFCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint, SkCanvas::SrcRectConstraint constraint) { - SkAutoCanvasRestore autoCanvasRestore(this, true); - this->clipRect(dst); + SkASSERT(src); + if (paint && paint->getMaskFilter()) { + if (sk_sp img = SkImage::MakeFromBitmap(bitmap)) { + this->onDrawImageRect(img.get(), src, dst, paint, constraint); + } + return; + } + SkAutoCanvasRestore autoCanvasRestore(this, false); + if (src && !is_integral(*src)) { + this->save(); + this->clipRect(dst); + } this->SkCanvas::onDrawBitmapRect(bitmap, src, dst, paint, constraint); }