diff --git a/src/codec/SkWuffsCodec.cpp b/src/codec/SkWuffsCodec.cpp index f46552114c..1f0a3a1a80 100644 --- a/src/codec/SkWuffsCodec.cpp +++ b/src/codec/SkWuffsCodec.cpp @@ -700,7 +700,7 @@ SkCodec::Result SkWuffsCodec::onIncrementalDecodeTwoPass() { draw.fRC = &rc; SkMatrix translate = SkMatrix::Translate(dirty_rect.min_incl_x, dirty_rect.min_incl_y); - draw.drawBitmap(src, translate, nullptr, paint); + draw.drawBitmap(src, translate, nullptr, SkSamplingOptions(), paint); } if (result == SkCodec::kSuccess) { diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp index 8cebb1cfa5..434faa3619 100644 --- a/src/core/SkBitmapDevice.cpp +++ b/src/core/SkBitmapDevice.cpp @@ -409,7 +409,8 @@ void SkBitmapDevice::drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix, bounds = &storage; } } - LOOP_TILER(drawBitmap(bitmap, matrix, dstOrNull, paint), bounds) + SkSamplingOptions sampling(paint.getFilterQuality()); // TODO, pass this in directly + LOOP_TILER(drawBitmap(bitmap, matrix, dstOrNull, sampling, paint), bounds) } static inline bool CanApplyDstMatrixAsCTM(const SkMatrix& m, const SkPaint& paint) { @@ -529,7 +530,9 @@ void SkBitmapDevice::drawImageRect(const SkImage* image, // construct a shader, so we can call drawRect with the dst auto s = SkMakeBitmapShaderForPaint(paint, *bitmapPtr, SkTileMode::kClamp, - SkTileMode::kClamp, &matrix, kNever_SkCopyPixelsMode); + SkTileMode::kClamp, + SkSamplingOptions(paint.getFilterQuality()), &matrix, + kNever_SkCopyPixelsMode); if (!s) { return; } @@ -579,8 +582,9 @@ void SkBitmapDevice::drawDevice(SkBaseDevice* device, const SkPaint& paint) { draw.fRC = &fRCStack.rc(); SkPaint deviceAsShader = paint; - deviceAsShader.setShader(src->fBitmap.makeShader(SkSamplingOptions())); - draw.drawBitmap(*src->fCoverage, SkMatrix::I(), nullptr, deviceAsShader); + SkSamplingOptions sampling; // nearest-neighbor, since we in sprite mode + deviceAsShader.setShader(src->fBitmap.makeShader(sampling)); + draw.drawBitmap(*src->fCoverage, SkMatrix::I(), nullptr, sampling, deviceAsShader); } else { this->INHERITED::drawDevice(device, paint); } @@ -600,7 +604,8 @@ void SkBitmapDevice::drawSpecial(SkSpecialImage* src, draw.fDst = fBitmap.pixmap(); draw.fMatrixProvider = &matrixProvider; draw.fRC = &fRCStack.rc(); - draw.drawBitmap(resultBM, SkMatrix::I(), nullptr, paint); + draw.drawBitmap(resultBM, SkMatrix::I(), nullptr, + SkSamplingOptions(paint.getFilterQuality()), paint); } } sk_sp SkBitmapDevice::makeSpecial(const SkBitmap& bitmap) { diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp index 858995fe7e..8caff4f9d9 100644 --- a/src/core/SkDraw.cpp +++ b/src/core/SkDraw.cpp @@ -37,11 +37,19 @@ #include -static SkPaint make_paint_with_image( - const SkPaint& origPaint, const SkBitmap& bitmap, SkMatrix* matrix = nullptr) { +static bool allows_sprite(const SkSamplingOptions& sampling) { + // Legacy behavior is to ignore sampling if there is no matrix, but new behavior + // should respect cubic, and not draw as sprite. Need to rebaseline test images + // to respect this... + // return !sampling.useCubic + return true; +} +static SkPaint make_paint_with_image(const SkPaint& origPaint, const SkBitmap& bitmap, + const SkSamplingOptions& sampling, + SkMatrix* matrix = nullptr) { SkPaint paint(origPaint); paint.setShader(SkMakeBitmapShaderForPaint(origPaint, bitmap, SkTileMode::kClamp, - SkTileMode::kClamp, matrix, + SkTileMode::kClamp, sampling, matrix, kNever_SkCopyPixelsMode)); return paint; } @@ -965,7 +973,8 @@ void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint, this->drawDevPath(*devPathPtr, *paint, drawCoverage, customBlitter, doFill); } -void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap, const SkPaint& paint) const { +void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap, const SkSamplingOptions& sampling, + const SkPaint& paint) const { SkASSERT(bitmap.colorType() == kAlpha_8_SkColorType); // nothing to draw @@ -974,7 +983,7 @@ void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap, const SkPaint& paint) cons } SkMatrix ctm = fMatrixProvider->localToDevice(); - if (SkTreatAsSprite(ctm, bitmap.dimensions(), paint)) { + if (allows_sprite(sampling) && SkTreatAsSprite(ctm, bitmap.dimensions(), paint)) { int ix = SkScalarRoundToInt(ctm.getTranslateX()); int iy = SkScalarRoundToInt(ctm.getTranslateY()); @@ -1040,8 +1049,7 @@ void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap, const SkPaint& paint) cons SkPaint tmpPaint; tmpPaint.setAntiAlias(paint.isAntiAlias()); tmpPaint.setDither(paint.isDither()); - tmpPaint.setFilterQuality(paint.getFilterQuality()); - SkPaint paintWithShader = make_paint_with_image(tmpPaint, bitmap); + SkPaint paintWithShader = make_paint_with_image(tmpPaint, bitmap, sampling); SkRect rr; rr.setIWH(bitmap.width(), bitmap.height()); c.drawRect(rr, paintWithShader); @@ -1069,7 +1077,8 @@ static bool clipHandlesSprite(const SkRasterClip& clip, int x, int y, const SkPi } void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix, - const SkRect* dstBounds, const SkPaint& origPaint) const { + const SkRect* dstBounds, const SkSamplingOptions& sampling, + const SkPaint& origPaint) const { SkDEBUGCODE(this->validate();) // nothing to draw @@ -1092,6 +1101,7 @@ void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix, } if (bitmap.colorType() != kAlpha_8_SkColorType + && allows_sprite(sampling) && SkTreatAsSprite(matrix, bitmap.dimensions(), *paint)) { // // It is safe to call lock pixels now, since we know the matrix is @@ -1123,9 +1133,9 @@ void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix, draw.fMatrixProvider = &matrixProvider; if (bitmap.colorType() == kAlpha_8_SkColorType && !paint->getColorFilter()) { - draw.drawBitmapAsMask(bitmap, *paint); + draw.drawBitmapAsMask(bitmap, sampling, *paint); } else { - SkPaint paintWithShader = make_paint_with_image(*paint, bitmap); + SkPaint paintWithShader = make_paint_with_image(*paint, bitmap, sampling); const SkRect srcBounds = SkRect::MakeIWH(bitmap.width(), bitmap.height()); if (dstBounds) { this->drawRect(srcBounds, paintWithShader, &prematrix, dstBounds); @@ -1178,7 +1188,7 @@ void SkDraw::drawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint& ori // create shader with offset matrix.setTranslate(r.fLeft, r.fTop); - SkPaint paintWithShader = make_paint_with_image(paint, bitmap, &matrix); + SkPaint paintWithShader = make_paint_with_image(paint, bitmap, SkSamplingOptions(), &matrix); SkDraw draw(*this); SkOverrideDeviceMatrixProvider matrixProvider(*fMatrixProvider, SkMatrix::I()); draw.fMatrixProvider = &matrixProvider; diff --git a/src/core/SkDraw.h b/src/core/SkDraw.h index f7ed596dbc..df331afe8d 100644 --- a/src/core/SkDraw.h +++ b/src/core/SkDraw.h @@ -59,7 +59,7 @@ public: /* If dstOrNull is null, computes a dst by mapping the bitmap's bounds through the matrix. */ void drawBitmap(const SkBitmap&, const SkMatrix&, const SkRect* dstOrNull, - const SkPaint&) const; + const SkSamplingOptions&, const SkPaint&) const; void drawSprite(const SkBitmap&, int x, int y, const SkPaint&) const; void drawGlyphRunList(const SkGlyphRunList& glyphRunList, SkGlyphRunListPainter* glyphPainter) const; @@ -124,7 +124,7 @@ public: static SkScalar ComputeResScaleForStroking(const SkMatrix& ); private: - void drawBitmapAsMask(const SkBitmap&, const SkPaint&) const; + void drawBitmapAsMask(const SkBitmap&, const SkSamplingOptions&, const SkPaint&) const; void draw_fixed_vertices(const SkVertices*, SkBlendMode, const SkPaint&, const SkMatrix&, const SkPoint dev2[], const SkPoint3 dev3[], SkArenaAlloc*) const; void draw_vdata_vertices(const SkVertices*, const SkPaint&, const SkMatrix&, diff --git a/src/core/SkImagePriv.h b/src/core/SkImagePriv.h index 810fe9b815..380b8ae3aa 100644 --- a/src/core/SkImagePriv.h +++ b/src/core/SkImagePriv.h @@ -24,14 +24,15 @@ enum {kSkBlitterContextSize = 3332}; // If alloc is non-nullptr, it will be used to allocate the returned SkShader, and MUST outlive // the SkShader. sk_sp SkMakeBitmapShader(const SkBitmap& src, SkTileMode, SkTileMode, - const SkMatrix* localMatrix, SkCopyPixelsMode); + const SkSamplingOptions&, const SkMatrix* localMatrix, + SkCopyPixelsMode); // Convenience function to return a shader that implements the shader+image behavior defined for // drawImage/Bitmap where the paint's shader is ignored when the bitmap is a color image, but // properly compose them together when it is an alpha image. This allows the returned paint to // be assigned to a paint clone without discarding the original behavior. sk_sp SkMakeBitmapShaderForPaint(const SkPaint& paint, const SkBitmap& src, - SkTileMode, SkTileMode, + SkTileMode, SkTileMode, const SkSamplingOptions&, const SkMatrix* localMatrix, SkCopyPixelsMode); /** diff --git a/src/shaders/SkImageShader.cpp b/src/shaders/SkImageShader.cpp index 1ba1888bf8..b5d4fbe5d5 100755 --- a/src/shaders/SkImageShader.cpp +++ b/src/shaders/SkImageShader.cpp @@ -500,17 +500,12 @@ std::unique_ptr SkImageShader::asFragmentProcessor( /////////////////////////////////////////////////////////////////////////////////////////////////// #include "src/core/SkImagePriv.h" -sk_sp SkMakeBitmapShader(const SkBitmap& src, SkTileMode tmx, SkTileMode tmy, - const SkMatrix* localMatrix, SkCopyPixelsMode cpm) { - const SkSamplingOptions* inherit_from_paint = nullptr; - return SkImageShader::Make(SkMakeImageFromRasterBitmap(src, cpm), - tmx, tmy, inherit_from_paint, localMatrix); -} - sk_sp SkMakeBitmapShaderForPaint(const SkPaint& paint, const SkBitmap& src, SkTileMode tmx, SkTileMode tmy, + const SkSamplingOptions& sampling, const SkMatrix* localMatrix, SkCopyPixelsMode mode) { - auto s = SkMakeBitmapShader(src, tmx, tmy, localMatrix, mode); + auto s = SkImageShader::Make(SkMakeImageFromRasterBitmap(src, mode), + tmx, tmy, &sampling, localMatrix); if (!s) { return nullptr; } diff --git a/src/xps/SkXPSDevice.cpp b/src/xps/SkXPSDevice.cpp index b723804b31..6cbc1cabd8 100644 --- a/src/xps/SkXPSDevice.cpp +++ b/src/xps/SkXPSDevice.cpp @@ -2024,9 +2024,10 @@ void SkXPSDevice::drawImageRect(const SkImage* image, matrix.mapRect(&actualDst, srcBounds); } - auto bitmapShader = SkMakeBitmapShaderForPaint(paint, bitmap, SkTileMode::kClamp, - SkTileMode::kClamp, &matrix, - kNever_SkCopyPixelsMode); + auto bitmapShader = SkMakeBitmapShaderForPaint(paint, bitmap, + SkTileMode::kClamp, SkTileMode::kClamp, + SkSamplingOptions(paint.getFilterQuality()), + &matrix, kNever_SkCopyPixelsMode); SkASSERT(bitmapShader); if (!bitmapShader) { return; } SkPaint paintWithShader(paint);