SkPDF: Add SkPDFCanvas to intercept some draw calls
authorhalcanary <halcanary@google.com>
Mon, 21 Mar 2016 20:01:34 +0000 (13:01 -0700)
committerCommit bot <commit-bot@chromium.org>
Mon, 21 Mar 2016 20:01:34 +0000 (13:01 -0700)
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

gyp/pdf.gypi
src/pdf/SkPDFCanvas.cpp [new file with mode: 0644]
src/pdf/SkPDFCanvas.h [new file with mode: 0644]
src/pdf/SkPDFDevice.cpp
src/pdf/SkPDFDocument.cpp

index af9a497..ce97e36 100644 (file)
@@ -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',
diff --git a/src/pdf/SkPDFCanvas.cpp b/src/pdf/SkPDFCanvas.cpp
new file mode 100644 (file)
index 0000000..de3dc93
--- /dev/null
@@ -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);
+}
diff --git a/src/pdf/SkPDFCanvas.h b/src/pdf/SkPDFCanvas.h
new file mode 100644 (file)
index 0000000..3a673e2
--- /dev/null
@@ -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
index f5e341b..9cc2563 100644 (file)
@@ -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.
index 670908e..2a01b80 100644 (file)
@@ -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());