SkPDF: stop using RasterClip for drawAnnotation()
authorHal Canary <halcanary@google.com>
Wed, 22 Feb 2017 20:55:06 +0000 (15:55 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Wed, 22 Feb 2017 23:23:09 +0000 (23:23 +0000)
Change-Id: Idc3a4151f1b6bd3cb11b59e39ddb1458af385035
Reviewed-on: https://skia-review.googlesource.com/8891
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Hal Canary <halcanary@google.com>

src/pdf/SkPDFDevice.cpp
src/pdf/SkPDFDevice.h

index 36c1418..dbe4c84 100644 (file)
@@ -511,12 +511,13 @@ void SkPDFDevice::cleanUp() {
 
 void SkPDFDevice::drawAnnotation(const SkDraw& d, const SkRect& rect, const char key[],
                                  SkData* value) {
-    if (0 == rect.width() && 0 == rect.height()) {
-        handlePointAnnotation({ rect.x(), rect.y() }, *d.fMatrix, key, value);
+    if (!value) {
+        return;
+    }
+    if (rect.isEmpty()) {
+        this->handlePointAnnotation({ rect.x(), rect.y() }, *d.fMatrix, key, value);
     } else {
-        SkPath path;
-        path.addRect(rect);
-        handlePathAnnotation(path, d, key, value);
+        this->handleRectAnnotation(rect, d, key, value);
     }
 }
 
@@ -1623,10 +1624,7 @@ bool SkPDFDevice::handleInversePath(const SkDraw& d, const SkPath& origPath,
 void SkPDFDevice::handlePointAnnotation(const SkPoint& point,
                                         const SkMatrix& matrix,
                                         const char key[], SkData* value) {
-    if (!value) {
-        return;
-    }
-
+    SkASSERT(value);
     if (!strcmp(SkAnnotationKeys::Define_Named_Dest_Key(), key)) {
         SkPoint transformedPoint;
         matrix.mapXY(point.x(), point.y(), &transformedPoint);
@@ -1634,25 +1632,28 @@ void SkPDFDevice::handlePointAnnotation(const SkPoint& point,
     }
 }
 
-void SkPDFDevice::handlePathAnnotation(const SkPath& path,
+void SkPDFDevice::handleRectAnnotation(const SkRect& rect,
                                        const SkDraw& d,
                                        const char key[], SkData* value) {
-    if (!value) {
-        return;
-    }
-
-    SkRasterClip clip = *d.fRC;
-    clip.op(path, *d.fMatrix, SkIRect::MakeWH(width(), height()),
-            SkRegion::kIntersect_Op,
-            false);
-    SkRect transformedRect = SkRect::Make(clip.getBounds());
-
-    if (!strcmp(SkAnnotationKeys::URL_Key(), key)) {
-        if (!transformedRect.isEmpty()) {
+    SkASSERT(value);
+    // Convert to path to handle non-90-degree rotations.
+    SkPath path;
+    path.addRect(rect);
+    path.transform(*d.fMatrix, &path);
+    SkPath clip;
+    (void)d.fClipStack->asPath(&clip);
+    SkIPoint deviceOrigin = this->getOrigin();
+    clip.offset(-deviceOrigin.x(), -deviceOrigin.y());
+    // Offset here to make clip and path share coordinates.
+    // We remove the offset in SkPDFDevice::drawDevice().
+    Op(clip, path, kIntersect_SkPathOp, &path);
+    // PDF wants a rectangle only.
+    SkRect transformedRect = path.getBounds();
+
+    if (!transformedRect.isEmpty()) {
+        if (!strcmp(SkAnnotationKeys::URL_Key(), key)) {
             fLinkToURLs.emplace_back(transformedRect, value);
-        }
-    } else if (!strcmp(SkAnnotationKeys::Link_Named_Dest_Key(), key)) {
-        if (!transformedRect.isEmpty()) {
+        } else if (!strcmp(SkAnnotationKeys::Link_Named_Dest_Key(), key)) {
             fLinkToDestinations.emplace_back(transformedRect, value);
         }
     }
index 14e4db6..1fa48da 100644 (file)
@@ -290,7 +290,7 @@ private:
                            const SkPaint& paint, bool pathIsMutable,
                            const SkMatrix* prePathMatrix = nullptr);
     void handlePointAnnotation(const SkPoint&, const SkMatrix&, const char key[], SkData* value);
-    void handlePathAnnotation(const SkPath&, const SkDraw& d, const char key[], SkData* value);
+    void handleRectAnnotation(const SkRect&, const SkDraw& d, const char key[], SkData* value);
 
     typedef SkClipStackDevice INHERITED;