/* * 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& 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); } } 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 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); } }