diff options
author | Hal Canary <halcanary@google.com> | 2017-07-12 13:13:51 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-07-12 21:02:22 +0000 |
commit | d425a1d013b669b6be375e99ad0c0703261e5bb6 (patch) | |
tree | 64dc8c6f3c7914b6fc68ba5c484ada027328572c /src/pdf | |
parent | 6b7e0e2c744f3c5aba3755e5c69c49669f791e9e (diff) |
SkPDF: start to support AlphaOnly Images as masks.
Does not work when img->isAlphaOnly() && pnt.getMaskFilter().
Change-Id: I60712d035e3a505799258e24660bba30f2c0ed53
Reviewed-on: https://skia-review.googlesource.com/22723
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Hal Canary <halcanary@google.com>
Diffstat (limited to 'src/pdf')
-rw-r--r-- | src/pdf/SkPDFDevice.cpp | 57 |
1 files changed, 55 insertions, 2 deletions
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp index 3125904797..bbc09f7ed6 100644 --- a/src/pdf/SkPDFDevice.cpp +++ b/src/pdf/SkPDFDevice.cpp @@ -87,6 +87,17 @@ sk_sp<SkImage> mask_to_greyscale_image(SkMask* mask) { return img; } +sk_sp<SkImage> alpha_image_to_greyscale_image(const SkImage* mask) { + int w = mask->width(), h = mask->height(); + SkBitmap greyBitmap; + greyBitmap.allocPixels(SkImageInfo::Make(w, h, kGray_8_SkColorType, kOpaque_SkAlphaType)); + if (!mask->readPixels(SkImageInfo::MakeA8(w, h), + greyBitmap.getPixels(), greyBitmap.rowBytes(), 0, 0)) { + return nullptr; + } + return SkImage::MakeFromBitmap(greyBitmap); +} + static void draw_points(SkCanvas::PointMode mode, size_t count, const SkPoint* points, @@ -613,8 +624,7 @@ void SkPDFDevice::internalDrawPaint(const SkPaint& paint, if (!contentEntry) { return; } - SkRect bbox = SkRect::MakeWH(SkIntToScalar(this->width()), - SkIntToScalar(this->height())); + SkRect bbox = SkRect::Make(fPageSize); SkMatrix inverse; if (!contentEntry->fState.fMatrix.invert(&inverse)) { return; @@ -2201,6 +2211,49 @@ void SkPDFDevice::internalDrawImageRect(SkKeyedImage imageSubset, } } + // TODO(halcanary) support isAlphaOnly & getMaskFilter. + bool imageAlphaOnly = imageSubset.image()->isAlphaOnly() && !paint.getMaskFilter(); + if (imageAlphaOnly) { + if (SkColorFilter* colorFilter = paint.getColorFilter()) { + sk_sp<SkImage> img = color_filter(imageSubset.image().get(), colorFilter); + paint.setColorFilter(nullptr); + imageSubset = SkKeyedImage(std::move(img)); + if (!imageSubset) { + return; + } + imageAlphaOnly = imageSubset.image()->isAlphaOnly(); + // The colorfilter can make a alphonly image no longer be alphaonly. + } + } + if (imageAlphaOnly) { + sk_sp<SkImage> mask = alpha_image_to_greyscale_image(imageSubset.image().get()); + if (!mask) { + return; + } + // PDF doesn't seem to allow masking vector graphics with an Image XObject. + // Must mask with a Form XObject. + sk_sp<SkPDFDevice> maskDevice = this->makeCongruentDevice(); + { + SkCanvas canvas(maskDevice.get()); + canvas.concat(transform); + canvas.concat(ctm); + // TODO(halcanary): investigate sub-pixel clipping. + canvas.drawImage(mask, 0, 0); + } + remove_color_filter(&paint); + if (!ctm.isIdentity() && paint.getShader()) { + transform_shader(&paint, ctm); // Since we are using identity matrix. + } + ScopedContentEntry content(this, this->cs(), SkMatrix::I(), paint); + if (!content.entry()) { + return; + } + this->addSMaskGraphicState(std::move(maskDevice), content.stream()); + SkPDFUtils::AppendRectangle(SkRect::Make(fPageSize), content.stream()); + SkPDFUtils::PaintPath(SkPaint::kFill_Style, SkPath::kWinding_FillType, content.stream()); + this->clearMaskOnGraphicState(content.stream()); + return; + } if (paint.getMaskFilter()) { paint.setShader(imageSubset.image()->makeShader(&transform)); SkPath path; |