aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar wangxianzhu <wangxianzhu@chromium.org>2015-07-17 17:23:15 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-07-17 17:23:15 -0700
commitd76665da1c93372720506ce7763cc810223ee9ee (patch)
tree4bc7faa02e7a47c18893e844f3ba9dd5f0b6d3fa
parent97a26d04e2a9324e7fc84c8a78d399e3484c9f50 (diff)
Reland "SkPDF: Annotations are clipped by canvas clip stack."
Original patch was created by halcanary@google.com, and was reverted because it triggered crbug.com/503541. This patch fixes a bug in the original patch about clip path transformation. > Also, remove some SkPDFDevice functions. > Will fix this GM: http://crrev.com/1159273003 > BUG=skia:3872 > Review URL: https://codereview.chromium.org/1148263005 BUG=skia:3872 BUG=503514 Review URL: https://codereview.chromium.org/1238503007
-rw-r--r--gm/annotated_text.cpp2
-rw-r--r--src/pdf/SkPDFDevice.cpp220
-rw-r--r--src/pdf/SkPDFDevice.h10
3 files changed, 116 insertions, 116 deletions
diff --git a/gm/annotated_text.cpp b/gm/annotated_text.cpp
index ab7e816126..7126206eeb 100644
--- a/gm/annotated_text.cpp
+++ b/gm/annotated_text.cpp
@@ -27,7 +27,7 @@ static void draw_url_annotated_text_with_box(
DEF_SIMPLE_GM(annotated_text, canvas, 512, 512) {
SkAutoCanvasRestore autoCanvasRestore(canvas, true);
canvas->clear(SK_ColorWHITE);
- canvas->clipRect(SkRect::MakeXYWH(64, 64, 384, 384));
+ canvas->clipRect(SkRect::MakeXYWH(64, 64, 256, 256));
canvas->clear(0xFFEEEEEE);
SkPaint p;
p.setTextSize(40);
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index 7ca6c2200e..957480d5df 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -804,8 +804,10 @@ void SkPDFDevice::drawPoints(const SkDraw& d,
return;
}
- if (handlePointAnnotation(points, count, *d.fMatrix, passedPaint)) {
- return;
+ if (SkAnnotation* annotation = passedPaint.getAnnotation()) {
+ if (handlePointAnnotation(points, count, *d.fMatrix, annotation)) {
+ return;
+ }
}
// SkDraw::drawPoints converts to multiple calls to fDevice->drawPath.
@@ -884,6 +886,79 @@ void SkPDFDevice::drawPoints(const SkDraw& d,
}
}
+static SkPath transform_and_clip_path(const SkDraw& d,
+ const SkPath& region,
+ const SkMatrix& initialTransform) {
+ SkPath path = region;
+ SkMatrix transform = *d.fMatrix;
+ transform.postConcat(initialTransform);
+ path.transform(transform);
+ if (const SkClipStack* clipStack = d.fClipStack) {
+ SkPath clip;
+ (void)clipStack->asPath(&clip);
+ clip.transform(initialTransform);
+ Op(clip, path, SkPathOp::kIntersect_SkPathOp, &path);
+ }
+ return path;
+}
+
+static SkPDFDict* create_link_annotation(const SkRect& translatedRect) {
+ SkAutoTUnref<SkPDFDict> annotation(SkNEW_ARGS(SkPDFDict, ("Annot")));
+ annotation->insertName("Subtype", "Link");
+
+ SkAutoTUnref<SkPDFArray> border(SkNEW(SkPDFArray));
+ border->reserve(3);
+ border->appendInt(0); // Horizontal corner radius.
+ border->appendInt(0); // Vertical corner radius.
+ border->appendInt(0); // Width, 0 = no border.
+ annotation->insertObject("Border", border.detach());
+
+ SkAutoTUnref<SkPDFArray> rect(SkNEW(SkPDFArray));
+ rect->reserve(4);
+ rect->appendScalar(translatedRect.fLeft);
+ rect->appendScalar(translatedRect.fTop);
+ rect->appendScalar(translatedRect.fRight);
+ rect->appendScalar(translatedRect.fBottom);
+ annotation->insertObject("Rect", rect.detach());
+
+ return annotation.detach();
+}
+
+static SkPDFDict* create_link_to_url(SkData* urlData, const SkRect& r) {
+ SkAutoTUnref<SkPDFDict> annotation(create_link_annotation(r));
+
+ SkString url(static_cast<const char *>(urlData->data()),
+ urlData->size() - 1);
+ SkAutoTUnref<SkPDFDict> action(SkNEW_ARGS(SkPDFDict, ("Action")));
+ action->insertName("S", "URI");
+ action->insertString("URI", url);
+ annotation->insertObject("A", action.detach());
+ return annotation.detach();
+}
+
+static SkPDFDict* create_link_named_dest(SkData* nameData, const SkRect& r) {
+ SkAutoTUnref<SkPDFDict> annotation(create_link_annotation(r));
+ SkString name(static_cast<const char *>(nameData->data()),
+ nameData->size() - 1);
+ annotation->insertName("Dest", name);
+ return annotation.detach();
+}
+
+static SkPDFDict* create_rect_annotation(const SkRect& r,
+ SkAnnotation* annotation) {
+ SkASSERT(annotation);
+ SkData* urlData = annotation->find(SkAnnotationKeys::URL_Key());
+ if (urlData) {
+ return create_link_to_url(urlData, r);
+ }
+ SkData* linkToName =
+ annotation->find(SkAnnotationKeys::Link_Named_Dest_Key());
+ if (linkToName) {
+ return create_link_named_dest(linkToName, r);
+ }
+ return NULL;
+}
+
void SkPDFDevice::drawRect(const SkDraw& d,
const SkRect& rect,
const SkPaint& srcPaint) {
@@ -902,8 +977,17 @@ void SkPDFDevice::drawRect(const SkDraw& d,
return;
}
- if (handleRectAnnotation(r, *d.fMatrix, paint)) {
- return;
+ if (SkAnnotation* annotation = paint.getAnnotation()) {
+ SkPath path;
+ path.addRect(rect);
+ SkRect transformedRect =
+ transform_and_clip_path(d, path, fInitialTransform).getBounds();
+ SkAutoTUnref<SkPDFDict> annot(
+ create_rect_annotation(transformedRect, annotation));
+ if (annot) {
+ this->addAnnotation(annot.detach());
+ return;
+ }
}
ScopedContentEntry content(this, d, paint);
@@ -984,8 +1068,16 @@ void SkPDFDevice::drawPath(const SkDraw& d,
return;
}
- if (handleRectAnnotation(pathPtr->getBounds(), matrix, paint)) {
- return;
+ if (SkAnnotation* annotation = paint.getAnnotation()) {
+ SkRect transformedRect =
+ transform_and_clip_path(d, *pathPtr, fInitialTransform)
+ .getBounds();
+ SkAutoTUnref<SkPDFDict> annot(
+ create_rect_annotation(transformedRect, annotation));
+ if (annot) {
+ this->addAnnotation(annot.detach());
+ return;
+ }
}
ScopedContentEntry content(this, d.fClipStack, *d.fClip, matrix, paint);
@@ -1476,40 +1568,30 @@ bool SkPDFDevice::handleInversePath(const SkDraw& d, const SkPath& origPath,
return true;
}
-bool SkPDFDevice::handleRectAnnotation(const SkRect& r, const SkMatrix& matrix,
- const SkPaint& p) {
- SkAnnotation* annotationInfo = p.getAnnotation();
- if (!annotationInfo) {
- return false;
- }
- SkData* urlData = annotationInfo->find(SkAnnotationKeys::URL_Key());
- if (urlData) {
- handleLinkToURL(urlData, r, matrix);
- return p.getAnnotation() != NULL;
- }
- SkData* linkToName = annotationInfo->find(
- SkAnnotationKeys::Link_Named_Dest_Key());
- if (linkToName) {
- handleLinkToNamedDest(linkToName, r, matrix);
- return p.getAnnotation() != NULL;
- }
- return false;
-}
+struct NamedDestination {
+ SkAutoTUnref<const SkData> nameData;
+ SkPoint point;
+
+ NamedDestination(const SkData* nameData, const SkPoint& point)
+ : nameData(SkRef(nameData)), point(point) {}
+};
bool SkPDFDevice::handlePointAnnotation(const SkPoint* points, size_t count,
const SkMatrix& matrix,
- const SkPaint& paint) {
- SkAnnotation* annotationInfo = paint.getAnnotation();
- if (!annotationInfo) {
- return false;
- }
+ SkAnnotation* annotationInfo) {
SkData* nameData = annotationInfo->find(
SkAnnotationKeys::Define_Named_Dest_Key());
if (nameData) {
+ SkMatrix transform = matrix;
+ transform.postConcat(fInitialTransform);
for (size_t i = 0; i < count; i++) {
- defineNamedDestination(nameData, points[i], matrix);
+ SkPoint translatedPoint;
+ transform.mapXY(points[i].x(), points[i].y(), &translatedPoint);
+ fNamedDestinations.push(
+ SkNEW_ARGS(NamedDestination, (nameData, translatedPoint)));
+
}
- return paint.getAnnotation() != NULL;
+ return true;
}
return false;
}
@@ -1521,80 +1603,6 @@ void SkPDFDevice::addAnnotation(SkPDFDict* annotation) {
fAnnotations->appendObject(annotation);
}
-static SkPDFDict* create_link_annotation(const SkRect& r,
- const SkMatrix& initialTransform,
- const SkMatrix& matrix) {
- SkMatrix transform = matrix;
- transform.postConcat(initialTransform);
- SkRect translatedRect;
- transform.mapRect(&translatedRect, r);
-
- SkAutoTUnref<SkPDFDict> annotation(SkNEW_ARGS(SkPDFDict, ("Annot")));
- annotation->insertName("Subtype", "Link");
-
- SkAutoTUnref<SkPDFArray> border(SkNEW(SkPDFArray));
- border->reserve(3);
- border->appendInt(0); // Horizontal corner radius.
- border->appendInt(0); // Vertical corner radius.
- border->appendInt(0); // Width, 0 = no border.
- annotation->insertObject("Border", border.detach());
-
- SkAutoTUnref<SkPDFArray> rect(SkNEW(SkPDFArray));
- rect->reserve(4);
- rect->appendScalar(translatedRect.fLeft);
- rect->appendScalar(translatedRect.fTop);
- rect->appendScalar(translatedRect.fRight);
- rect->appendScalar(translatedRect.fBottom);
- annotation->insertObject("Rect", rect.detach());
-
- return annotation.detach();
-}
-
-void SkPDFDevice::handleLinkToURL(SkData* urlData, const SkRect& r,
- const SkMatrix& matrix) {
- SkAutoTUnref<SkPDFDict> annotation(
- create_link_annotation(r, fInitialTransform, matrix));
-
- SkString url(static_cast<const char *>(urlData->data()),
- urlData->size() - 1);
- SkAutoTUnref<SkPDFDict> action(SkNEW_ARGS(SkPDFDict, ("Action")));
- action->insertName("S", "URI");
- action->insertString("URI", url);
- annotation->insertObject("A", action.detach());
- this->addAnnotation(annotation.detach());
-}
-
-void SkPDFDevice::handleLinkToNamedDest(SkData* nameData, const SkRect& r,
- const SkMatrix& matrix) {
- SkAutoTUnref<SkPDFDict> annotation(
- create_link_annotation(r, fInitialTransform, matrix));
- SkString name(static_cast<const char *>(nameData->data()),
- nameData->size() - 1);
- annotation->insertName("Dest", name);
- this->addAnnotation(annotation.detach());
-}
-
-struct NamedDestination {
- const SkData* nameData;
- SkPoint point;
-
- NamedDestination(const SkData* nameData, const SkPoint& point)
- : nameData(SkRef(nameData)), point(point) {}
-
- ~NamedDestination() {
- nameData->unref();
- }
-};
-
-void SkPDFDevice::defineNamedDestination(SkData* nameData, const SkPoint& point,
- const SkMatrix& matrix) {
- SkMatrix transform = matrix;
- transform.postConcat(fInitialTransform);
- SkPoint translatedPoint;
- transform.mapXY(point.x(), point.y(), &translatedPoint);
- fNamedDestinations.push(
- SkNEW_ARGS(NamedDestination, (nameData, translatedPoint)));
-}
void SkPDFDevice::appendDestinations(SkPDFDict* dict, SkPDFObject* page) const {
int nDest = fNamedDestinations.count();
diff --git a/src/pdf/SkPDFDevice.h b/src/pdf/SkPDFDevice.h
index bb12a3f6dc..5c391c3ccd 100644
--- a/src/pdf/SkPDFDevice.h
+++ b/src/pdf/SkPDFDevice.h
@@ -292,17 +292,9 @@ private:
bool handleInversePath(const SkDraw& d, const SkPath& origPath,
const SkPaint& paint, bool pathIsMutable,
const SkMatrix* prePathMatrix = NULL);
- bool handleRectAnnotation(const SkRect& r, const SkMatrix& matrix,
- const SkPaint& paint);
bool handlePointAnnotation(const SkPoint* points, size_t count,
- const SkMatrix& matrix, const SkPaint& paint);
+ const SkMatrix& matrix, SkAnnotation* annot);
void addAnnotation(SkPDFDict*);
- void handleLinkToURL(SkData* urlData, const SkRect& r,
- const SkMatrix& matrix);
- void handleLinkToNamedDest(SkData* nameData, const SkRect& r,
- const SkMatrix& matrix);
- void defineNamedDestination(SkData* nameData, const SkPoint& point,
- const SkMatrix& matrix);
typedef SkBaseDevice INHERITED;