SkPDF: Add SkPDFCanvas to intercept some draw calls
Motivation: this simplifies implementation at the device level. GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1812063002 Review URL: https://codereview.chromium.org/1812063002
This commit is contained in:
parent
ddf9835e9c
commit
66be626f7f
@ -19,6 +19,8 @@
|
||||
'<(skia_src_path)/pdf/SkPDFBitmap.h',
|
||||
'<(skia_src_path)/pdf/SkPDFCanon.cpp',
|
||||
'<(skia_src_path)/pdf/SkPDFCanon.h',
|
||||
'<(skia_src_path)/pdf/SkPDFCanvas.cpp',
|
||||
'<(skia_src_path)/pdf/SkPDFCanvas.h',
|
||||
'<(skia_src_path)/pdf/SkPDFDevice.cpp',
|
||||
'<(skia_src_path)/pdf/SkPDFDevice.h',
|
||||
'<(skia_src_path)/pdf/SkPDFDocument.cpp',
|
||||
|
69
src/pdf/SkPDFCanvas.cpp
Normal file
69
src/pdf/SkPDFCanvas.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SkNinePatchIter.h"
|
||||
#include "SkPDFCanvas.h"
|
||||
#include "SkPDFDevice.h"
|
||||
|
||||
SkPDFCanvas::SkPDFCanvas(const sk_sp<SkPDFDevice>& dev)
|
||||
: SkCanvas(dev.get()) {}
|
||||
|
||||
SkPDFCanvas::~SkPDFCanvas() {}
|
||||
|
||||
void SkPDFCanvas::onDrawBitmapNine(const SkBitmap& bitmap,
|
||||
const SkIRect& center,
|
||||
const SkRect& dst,
|
||||
const SkPaint* paint) {
|
||||
SkNinePatchIter iter(bitmap.width(), bitmap.height(), center, dst);
|
||||
SkRect srcR, dstR;
|
||||
while (iter.next(&srcR, &dstR)) {
|
||||
this->drawBitmapRect(bitmap, srcR, dstR, paint);
|
||||
}
|
||||
}
|
||||
|
||||
void SkPDFCanvas::onDrawImageNine(const SkImage* image,
|
||||
const SkIRect& center,
|
||||
const SkRect& dst,
|
||||
const SkPaint* paint) {
|
||||
SkNinePatchIter iter(image->width(), image->height(), center, dst);
|
||||
SkRect srcR, dstR;
|
||||
while (iter.next(&srcR, &dstR)) {
|
||||
this->drawImageRect(image, srcR, dstR, paint);
|
||||
}
|
||||
}
|
||||
|
||||
void SkPDFCanvas::onDrawImageRect(const SkImage* image,
|
||||
const SkRect* srcPtr,
|
||||
const SkRect& dst,
|
||||
const SkPaint* paint,
|
||||
SkCanvas::SrcRectConstraint constraint) {
|
||||
SkRect bounds = SkRect::Make(image->bounds());
|
||||
SkRect src = srcPtr ? *srcPtr : bounds;
|
||||
SkAutoCanvasRestore autoCanvasRestore(this, true);
|
||||
if (src != bounds) {
|
||||
this->clipRect(dst);
|
||||
}
|
||||
this->concat(SkMatrix::MakeRectToRect(src, dst,
|
||||
SkMatrix::kFill_ScaleToFit));
|
||||
this->drawImage(image, 0, 0, paint);
|
||||
}
|
||||
|
||||
void SkPDFCanvas::onDrawBitmapRect(const SkBitmap& bitmap,
|
||||
const SkRect* srcPtr,
|
||||
const SkRect& dst,
|
||||
const SkPaint* paint,
|
||||
SkCanvas::SrcRectConstraint constraint) {
|
||||
SkRect bounds = SkRect::Make(bitmap.bounds());
|
||||
SkRect src = srcPtr ? *srcPtr : bounds;
|
||||
SkAutoCanvasRestore autoCanvasRestore(this, true);
|
||||
if (src != bounds) {
|
||||
this->clipRect(dst);
|
||||
}
|
||||
this->concat(SkMatrix::MakeRectToRect(src, dst,
|
||||
SkMatrix::kFill_ScaleToFit));
|
||||
this->drawBitmap(bitmap, 0, 0, paint);
|
||||
}
|
39
src/pdf/SkPDFCanvas.h
Normal file
39
src/pdf/SkPDFCanvas.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#ifndef SkPDFCanvas_DEFINED
|
||||
#define SkPDFCanvas_DEFINED
|
||||
|
||||
#include "SkCanvas.h"
|
||||
|
||||
class SkPDFDevice;
|
||||
|
||||
class SkPDFCanvas : public SkCanvas {
|
||||
public:
|
||||
SkPDFCanvas(const sk_sp<SkPDFDevice>&);
|
||||
~SkPDFCanvas();
|
||||
|
||||
protected:
|
||||
void onDrawBitmapNine(const SkBitmap&, const SkIRect&, const SkRect&,
|
||||
const SkPaint*) override;
|
||||
|
||||
void onDrawImageNine(const SkImage*, const SkIRect&, const SkRect&,
|
||||
const SkPaint*) override;
|
||||
|
||||
void onDrawImageRect(const SkImage*,
|
||||
const SkRect*,
|
||||
const SkRect&,
|
||||
const SkPaint*,
|
||||
SkCanvas::SrcRectConstraint) override;
|
||||
|
||||
void onDrawBitmapRect(const SkBitmap&,
|
||||
const SkRect*,
|
||||
const SkRect&,
|
||||
const SkPaint*,
|
||||
SkCanvas::SrcRectConstraint) override;
|
||||
};
|
||||
|
||||
#endif // SkPDFCanvas_DEFINED
|
@ -1039,12 +1039,7 @@ void SkPDFDevice::drawBitmapRect(const SkDraw& draw,
|
||||
const SkRect& dst,
|
||||
const SkPaint& srcPaint,
|
||||
SkCanvas::SrcRectConstraint constraint) {
|
||||
const SkImage* image = fCanon->bitmapToImage(bitmap);
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
// ownership of this image is retained by the canon.
|
||||
this->drawImageRect(draw, image, src, dst, srcPaint, constraint);
|
||||
SkASSERT(false);
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawBitmap(const SkDraw& d,
|
||||
@ -1121,66 +1116,7 @@ void SkPDFDevice::drawImageRect(const SkDraw& draw,
|
||||
const SkRect& dst,
|
||||
const SkPaint& srcPaint,
|
||||
SkCanvas::SrcRectConstraint constraint) {
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
if (draw.fClip->isEmpty()) {
|
||||
return;
|
||||
}
|
||||
SkPaint paint = srcPaint;
|
||||
if (image->isOpaque()) {
|
||||
replace_srcmode_on_opaque_paint(&paint);
|
||||
}
|
||||
// TODO: this code path must be updated to respect the flags parameter
|
||||
SkMatrix matrix;
|
||||
SkRect tmpSrc, tmpDst;
|
||||
SkRect imageBounds = SkRect::Make(image->bounds());
|
||||
|
||||
// Compute matrix from the two rectangles
|
||||
if (src) {
|
||||
tmpSrc = *src;
|
||||
} else {
|
||||
tmpSrc = imageBounds;
|
||||
}
|
||||
matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);
|
||||
|
||||
// clip the tmpSrc to the bounds of the bitmap, and recompute dstRect if
|
||||
// needed (if the src was clipped). No check needed if src==null.
|
||||
sk_sp<const SkImage> autoImageUnref;
|
||||
if (src) {
|
||||
if (!imageBounds.contains(*src)) {
|
||||
if (!tmpSrc.intersect(imageBounds)) {
|
||||
return; // nothing to draw
|
||||
}
|
||||
// recompute dst, based on the smaller tmpSrc
|
||||
matrix.mapRect(&tmpDst, tmpSrc);
|
||||
}
|
||||
|
||||
// since we may need to clamp to the borders of the src rect within
|
||||
// the bitmap, we extract a subset.
|
||||
SkIRect srcIR;
|
||||
tmpSrc.roundOut(&srcIR);
|
||||
|
||||
autoImageUnref = image->makeSubset(srcIR);
|
||||
if (!autoImageUnref) {
|
||||
return;
|
||||
}
|
||||
image = autoImageUnref.get();
|
||||
// Since we did an extract, we need to adjust the matrix accordingly
|
||||
SkScalar dx = 0, dy = 0;
|
||||
if (srcIR.fLeft > 0) {
|
||||
dx = SkIntToScalar(srcIR.fLeft);
|
||||
}
|
||||
if (srcIR.fTop > 0) {
|
||||
dy = SkIntToScalar(srcIR.fTop);
|
||||
}
|
||||
if (dx || dy) {
|
||||
matrix.preTranslate(dx, dy);
|
||||
}
|
||||
}
|
||||
matrix.postConcat(*draw.fMatrix);
|
||||
this->internalDrawImage(matrix, draw.fClipStack, *draw.fClip, image,
|
||||
nullptr, paint);
|
||||
SkASSERT(false);
|
||||
}
|
||||
|
||||
// Create a PDF string. Maximum length (in bytes) is 65,535.
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "SkPDFCanon.h"
|
||||
#include "SkPDFCanvas.h"
|
||||
#include "SkPDFDevice.h"
|
||||
#include "SkPDFDocument.h"
|
||||
#include "SkPDFFont.h"
|
||||
@ -333,7 +334,7 @@ protected:
|
||||
SkScalarRoundToInt(width), SkScalarRoundToInt(height));
|
||||
sk_sp<SkPDFDevice> device(
|
||||
SkPDFDevice::Create(pageSize, fRasterDpi, &fCanon));
|
||||
fCanvas.reset(new SkCanvas(device.get()));
|
||||
fCanvas = sk_make_sp<SkPDFCanvas>(device);
|
||||
fPageDevices.push_back(std::move(device));
|
||||
fCanvas->clipRect(trimBox);
|
||||
fCanvas->translate(trimBox.x(), trimBox.y());
|
||||
|
Loading…
Reference in New Issue
Block a user