Index: src/pdf/SkPDFDevice.cpp |
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp |
index b6a5b519e8d0f45493d2987f6ce073f442814f90..b2082019a49af74bbd986754d290ab3af4242348 100644 |
--- a/src/pdf/SkPDFDevice.cpp |
+++ b/src/pdf/SkPDFDevice.cpp |
@@ -1058,12 +1058,9 @@ void SkPDFDevice::drawBitmap(const SkDraw& d, |
SkMatrix transform = matrix; |
transform.postConcat(*d.fMatrix); |
- const SkImage* image = fDocument->canon()->bitmapToImage(bitmap); |
- if (!image) { |
- return; |
- } |
- this->internalDrawImage(transform, d.fClipStack, *d.fClip, image, nullptr, |
- paint); |
+ SkImageBitmap imageBitmap(bitmap); |
+ this->internalDrawImage( |
+ transform, d.fClipStack, *d.fClip, imageBitmap, paint); |
} |
void SkPDFDevice::drawSprite(const SkDraw& d, |
@@ -1082,12 +1079,9 @@ void SkPDFDevice::drawSprite(const SkDraw& d, |
SkMatrix matrix; |
matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y)); |
- const SkImage* image = fDocument->canon()->bitmapToImage(bitmap); |
- if (!image) { |
- return; |
- } |
- this->internalDrawImage(matrix, d.fClipStack, *d.fClip, image, nullptr, |
- paint); |
+ SkImageBitmap imageBitmap(bitmap); |
+ this->internalDrawImage( |
+ matrix, d.fClipStack, *d.fClip, imageBitmap, paint); |
} |
void SkPDFDevice::drawImage(const SkDraw& draw, |
@@ -1107,8 +1101,9 @@ void SkPDFDevice::drawImage(const SkDraw& draw, |
} |
SkMatrix transform = SkMatrix::MakeTrans(x, y); |
transform.postConcat(*draw.fMatrix); |
- this->internalDrawImage(transform, draw.fClipStack, *draw.fClip, image, |
- nullptr, paint); |
+ SkImageBitmap imageBitmap(const_cast<SkImage*>(image)); |
+ this->internalDrawImage( |
+ transform, draw.fClipStack, *draw.fClip, imageBitmap, paint); |
} |
void SkPDFDevice::drawImageRect(const SkDraw& draw, |
@@ -2112,43 +2107,37 @@ static SkSize rect_to_size(const SkRect& r) { |
return SkSize::Make(r.width(), r.height()); |
} |
-static const SkImage* color_filter(const SkImage* image, SkColorFilter* colorFilter) { |
- auto surface(SkSurface::MakeRaster(SkImageInfo::MakeN32Premul(image->dimensions()))); |
- if (!surface) { |
- return image; |
- } |
+static sk_sp<SkImage> color_filter(const SkImageBitmap& imageBitmap, |
+ SkColorFilter* colorFilter) { |
+ auto surface = |
+ SkSurface::MakeRaster(SkImageInfo::MakeN32Premul(imageBitmap.dimensions())); |
+ SkASSERT(surface); |
SkCanvas* canvas = surface->getCanvas(); |
canvas->clear(SK_ColorTRANSPARENT); |
SkPaint paint; |
paint.setColorFilter(sk_ref_sp(colorFilter)); |
- canvas->drawImage(image, 0, 0, &paint); |
+ imageBitmap.draw(canvas, &paint); |
canvas->flush(); |
- return surface->makeImageSnapshot().release(); |
+ return surface->makeImageSnapshot(); |
} |
//////////////////////////////////////////////////////////////////////////////// |
void SkPDFDevice::internalDrawImage(const SkMatrix& origMatrix, |
const SkClipStack* clipStack, |
const SkRegion& origClipRegion, |
- const SkImage* image, |
- const SkIRect* srcRect, |
+ SkImageBitmap imageBitmap, |
const SkPaint& paint) { |
- SkASSERT(image); |
+ if (imageBitmap.dimensions().isZero()) { |
+ return; |
+ } |
#ifdef SK_PDF_IMAGE_STATS |
gDrawImageCalls.fetch_add(1); |
#endif |
SkMatrix matrix = origMatrix; |
SkRegion perspectiveBounds; |
const SkRegion* clipRegion = &origClipRegion; |
- sk_sp<const SkImage> autoImageUnref; |
+ sk_sp<SkImage> autoImageUnref; |
- if (srcRect) { |
- autoImageUnref = image->makeSubset(*srcRect); |
- if (!autoImageUnref) { |
- return; |
- } |
- image = autoImageUnref.get(); |
- } |
// Rasterize the bitmap using perspective in a new bitmap. |
if (origMatrix.hasPerspective()) { |
if (fRasterDpi == 0) { |
@@ -2157,7 +2146,7 @@ void SkPDFDevice::internalDrawImage(const SkMatrix& origMatrix, |
// Transform the bitmap in the new space, without taking into |
// account the initial transform. |
SkPath perspectiveOutline; |
- SkRect imageBounds = SkRect::Make(image->bounds()); |
+ SkRect imageBounds = SkRect::Make(imageBitmap.bounds()); |
perspectiveOutline.addRect(imageBounds); |
perspectiveOutline.transform(origMatrix); |
@@ -2208,7 +2197,7 @@ void SkPDFDevice::internalDrawImage(const SkMatrix& origMatrix, |
// Translate the draw in the new canvas, so we perfectly fit the |
// shape in the bitmap. |
canvas->setMatrix(offsetMatrix); |
- canvas->drawImage(image, 0, 0, nullptr); |
+ imageBitmap.draw(canvas, nullptr); |
// Make sure the final bits are in the bitmap. |
canvas->flush(); |
@@ -2219,10 +2208,9 @@ void SkPDFDevice::internalDrawImage(const SkMatrix& origMatrix, |
perspectiveBounds.setRect(bounds.roundOut()); |
clipRegion = &perspectiveBounds; |
- srcRect = nullptr; |
- autoImageUnref.reset(surface->makeImageSnapshot().release()); |
- image = autoImageUnref.get(); |
+ autoImageUnref = surface->makeImageSnapshot(); |
+ imageBitmap = SkImageBitmap(autoImageUnref.get()); |
} |
SkMatrix scaled; |
@@ -2230,12 +2218,12 @@ void SkPDFDevice::internalDrawImage(const SkMatrix& origMatrix, |
scaled.setScale(SK_Scalar1, -SK_Scalar1); |
scaled.postTranslate(0, SK_Scalar1); |
// Scale the image up from 1x1 to WxH. |
- SkIRect subset = image->bounds(); |
- scaled.postScale(SkIntToScalar(image->width()), |
- SkIntToScalar(image->height())); |
+ SkIRect subset = imageBitmap.bounds(); |
+ scaled.postScale(SkIntToScalar(imageBitmap.dimensions().width()), |
+ SkIntToScalar(imageBitmap.dimensions().height())); |
scaled.postConcat(matrix); |
ScopedContentEntry content(this, clipStack, *clipRegion, scaled, paint); |
- if (!content.entry() || (srcRect && !subset.intersect(*srcRect))) { |
+ if (!content.entry()) { |
return; |
} |
if (content.needShape()) { |
@@ -2254,26 +2242,28 @@ void SkPDFDevice::internalDrawImage(const SkMatrix& origMatrix, |
// drawBitmap*()/drawImage*() calls amd ImageFilters (which |
// rasterize a layer on this backend). Fortuanely, this seems |
// to be how Chromium impements most color-filters. |
- autoImageUnref.reset(color_filter(image, colorFilter)); |
- image = autoImageUnref.get(); |
+ autoImageUnref = color_filter(imageBitmap, colorFilter); |
+ imageBitmap = SkImageBitmap(autoImageUnref.get()); |
// TODO(halcanary): de-dupe this by caching filtered images. |
// (maybe in the resource cache?) |
} |
- sk_sp<SkPDFObject> pdfimage(SkSafeRef(fDocument->canon()->findPDFBitmap(image))); |
+ |
+ SkBitmapKey key = imageBitmap.getKey(); |
+ sk_sp<SkPDFObject> pdfimage = fDocument->canon()->findPDFBitmap(key); |
if (!pdfimage) { |
- pdfimage.reset(SkPDFCreateBitmapObject( |
- image, fDocument->canon()->getPixelSerializer())); |
- if (!pdfimage) { |
+ auto img = imageBitmap.makeImage(); |
+ if (!img) { |
return; |
} |
- #if SK_PDF_SERIALIZE_IMAGES_EARLY // TODO(halcanary): enable. |
- sk_sp<SkData> encodedImage(image->refEncodedData()); |
- if (!encodedImage) { |
- fDocument->serialize(pdfimage); |
+ pdfimage = SkPDFCreateBitmapObject( |
+ std::move(img), fDocument->canon()->getPixelSerializer()); |
+ if (!pdfimage) { |
+ return; |
} |
- #endif |
- fDocument->canon()->addPDFBitmap(image->uniqueID(), pdfimage.get()); |
+ fDocument->serialize(pdfimage); // serialize images early. |
+ fDocument->canon()->addPDFBitmap(key, pdfimage); |
} |
+ // TODO(halcanary): addXObjectResource() should take a sk_sp<SkPDFObject> |
SkPDFUtils::DrawFormXObject(this->addXObjectResource(pdfimage.get()), |
&content.entry()->fContent); |
} |