blob: 720161ecf5333e23cd5efb921a74004dc636c66f [file] [log] [blame]
/*
* 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 "SkImage.h"
#include "SkLatticeIter.h"
#include "SkPDFCanvas.h"
#include "SkPDFDevice.h"
SkPDFCanvas::SkPDFCanvas(const sk_sp<SkPDFDevice>& dev)
: SkCanvas(dev.get()) {}
SkPDFCanvas::~SkPDFCanvas() {}
/*
* PDF's impl sometimes wants to access the raster clip as a SkRegion. To keep this valid,
* we intercept all clip calls to ensure that the clip stays BW (i.e. never antialiased), since
* an antialiased clip won't build a SkRegion (it builds SkAAClip).
*/
void SkPDFCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) {
this->INHERITED::onClipRect(rect, op, kHard_ClipEdgeStyle);
}
void SkPDFCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle) {
this->INHERITED::onClipRRect(rrect, op, kHard_ClipEdgeStyle);
}
void SkPDFCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle) {
this->INHERITED::onClipPath(path, op, kHard_ClipEdgeStyle);
}
void SkPDFCanvas::onDrawBitmapNine(const SkBitmap& bitmap,
const SkIRect& center,
const SkRect& dst,
const SkPaint* paint) {
SkLatticeIter 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) {
SkLatticeIter iter(image->width(), image->height(), center, dst);
SkRect srcR, dstR;
while (iter.next(&srcR, &dstR)) {
this->drawImageRect(image, srcR, dstR, paint);
}
}
void SkPDFCanvas::onDrawImage(const SkImage* image,
SkScalar x,
SkScalar y,
const SkPaint* paint) {
SkASSERT(image);
if (paint && paint->getMaskFilter()) {
SkPaint paintCopy(*paint);
SkMatrix m = SkMatrix::MakeTrans(x, y);
paintCopy.setShader(image->makeShader(&m));
this->drawRect(SkRect::MakeXYWH(x, y, image->width(), image->height()), paintCopy);
return;
}
this->SkCanvas::onDrawImage(image, x, y, paint);
}
void SkPDFCanvas::onDrawBitmap(const SkBitmap& bitmap,
SkScalar x,
SkScalar y,
const SkPaint* paint) {
if (paint && paint->getMaskFilter()) {
if (sk_sp<SkImage> img = SkImage::MakeFromBitmap(bitmap)) {
this->onDrawImage(img.get(), x, y, paint);
}
return;
}
this->SkCanvas::onDrawBitmap(bitmap, x, y, paint);
}
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) {
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);
}
void SkPDFCanvas::onDrawBitmapRect(const SkBitmap& bitmap,
const SkRect* src,
const SkRect& dst,
const SkPaint* paint,
SkCanvas::SrcRectConstraint constraint) {
SkASSERT(src);
if (paint && paint->getMaskFilter()) {
if (sk_sp<SkImage> 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);
}
void SkPDFCanvas::onDrawImageLattice(const SkImage* image,
const Lattice& lattice,
const SkRect& dst,
const SkPaint* paint) {
SkLatticeIter iter(lattice, dst);
SkRect srcR, dstR;
while (iter.next(&srcR, &dstR)) {
this->drawImageRect(image, srcR, dstR, paint);
}
}
void SkPDFCanvas::onDrawBitmapLattice(const SkBitmap& bitmap,
const Lattice& lattice,
const SkRect& dst,
const SkPaint* paint) {
SkLatticeIter iter(lattice, dst);
SkRect srcR, dstR;
while (iter.next(&srcR, &dstR)) {
this->drawBitmapRect(bitmap, srcR, dstR, paint);
}
}