Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(590)

Unified Diff: src/pdf/SkPDFDevice.cpp

Issue 1257533004: Merge sub-device annotations in SkPDFDevice::drawDevice() (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Rebase and address comment Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/pdf/SkPDFDevice.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/pdf/SkPDFDevice.cpp
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index a5c9557412032281fbbc341599baf5ff44dd451b..52c4c655cd9c38d6b1cd58c4cb0b217f54321c8a 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -25,6 +25,7 @@
#include "SkPDFStream.h"
#include "SkPDFTypes.h"
#include "SkPDFUtils.h"
+#include "SkRasterClip.h"
#include "SkRect.h"
#include "SkRRect.h"
#include "SkString.h"
@@ -702,7 +703,6 @@ SkPDFDevice::SkPDFDevice(SkISize pageSize, SkScalar rasterDpi, SkPDFCanon* canon
, fPageSize(pageSize)
, fContentSize(pageSize)
, fExistingClipRegion(SkIRect::MakeSize(pageSize))
- , fAnnotations(nullptr)
, fLastContentEntry(nullptr)
, fLastMarginContentEntry(nullptr)
, fDrawingArea(kContent_DrawingArea)
@@ -731,7 +731,6 @@ SkPDFDevice::~SkPDFDevice() {
}
void SkPDFDevice::init() {
- fAnnotations = nullptr;
fContentEntries.free();
fLastContentEntry = nullptr;
fMarginContentEntries.free();
@@ -747,7 +746,8 @@ void SkPDFDevice::cleanUp(bool clearFontUsage) {
fXObjectResources.unrefAll();
fFontResources.unrefAll();
fShaderResources.unrefAll();
- SkSafeUnref(fAnnotations);
+ fLinkToURLs.deleteAll();
+ fLinkToDestinations.deleteAll();
fNamedDestinations.deleteAll();
if (clearFontUsage) {
@@ -876,22 +876,6 @@ 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(new SkPDFDict("Annot"));
annotation->insertName("Subtype", "Link");
@@ -914,7 +898,7 @@ static SkPDFDict* create_link_annotation(const SkRect& translatedRect) {
return annotation.detach();
}
-static SkPDFDict* create_link_to_url(SkData* urlData, const SkRect& r) {
+static SkPDFDict* create_link_to_url(const SkData* urlData, const SkRect& r) {
SkAutoTUnref<SkPDFDict> annotation(create_link_annotation(r));
SkString url(static_cast<const char *>(urlData->data()),
@@ -926,7 +910,8 @@ static SkPDFDict* create_link_to_url(SkData* urlData, const SkRect& r) {
return annotation.detach();
}
-static SkPDFDict* create_link_named_dest(SkData* nameData, const SkRect& r) {
+static SkPDFDict* create_link_named_dest(const SkData* nameData,
+ const SkRect& r) {
SkAutoTUnref<SkPDFDict> annotation(create_link_annotation(r));
SkString name(static_cast<const char *>(nameData->data()),
nameData->size() - 1);
@@ -934,21 +919,6 @@ static SkPDFDict* create_link_named_dest(SkData* nameData, const SkRect& r) {
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 nullptr;
-}
-
void SkPDFDevice::drawRect(const SkDraw& d,
const SkRect& rect,
const SkPaint& srcPaint) {
@@ -970,12 +940,7 @@ void SkPDFDevice::drawRect(const SkDraw& d,
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());
+ if (handlePathAnnotation(path, d, annotation)) {
return;
}
}
@@ -1059,13 +1024,7 @@ void SkPDFDevice::drawPath(const SkDraw& d,
}
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());
+ if (handlePathAnnotation(*pathPtr, d, annotation)) {
return;
}
}
@@ -1327,10 +1286,42 @@ void SkPDFDevice::drawVertices(const SkDraw& d, SkCanvas::VertexMode,
// TODO: implement drawVertices
}
+struct RectWithData {
+ SkRect rect;
+ SkAutoTUnref<const SkData> data;
+
+ RectWithData(const SkRect& rect, const SkData* data)
+ : rect(rect), data(SkRef(data)) {}
+};
+
+struct NamedDestination {
+ SkAutoTUnref<const SkData> nameData;
+ SkPoint point;
+
+ NamedDestination(const SkData* nameData, const SkPoint& point)
+ : nameData(SkRef(nameData)), point(point) {}
+};
+
void SkPDFDevice::drawDevice(const SkDraw& d, SkBaseDevice* device,
int x, int y, const SkPaint& paint) {
// our onCreateCompatibleDevice() always creates SkPDFDevice subclasses.
SkPDFDevice* pdfDevice = static_cast<SkPDFDevice*>(device);
+
+ SkScalar scalarX = SkIntToScalar(x);
+ SkScalar scalarY = SkIntToScalar(y);
+ for (RectWithData* link : pdfDevice->fLinkToURLs) {
+ fLinkToURLs.push(new RectWithData(
+ link->rect.makeOffset(scalarX, scalarY), link->data));
+ }
+ for (RectWithData* link : pdfDevice->fLinkToDestinations) {
+ fLinkToDestinations.push(new RectWithData(
+ link->rect.makeOffset(scalarX, scalarY), link->data));
+ }
+ for (NamedDestination* d : pdfDevice->fNamedDestinations) {
+ fNamedDestinations.push(new NamedDestination(
+ d->nameData, d->point + SkPoint::Make(scalarX, scalarY)));
+ }
+
if (pdfDevice->isContentEmpty()) {
return;
}
@@ -1557,50 +1548,76 @@ bool SkPDFDevice::handleInversePath(const SkDraw& d, const SkPath& origPath,
return true;
}
-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,
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++) {
- SkPoint translatedPoint;
- transform.mapXY(points[i].x(), points[i].y(), &translatedPoint);
- fNamedDestinations.push(new NamedDestination(nameData, translatedPoint));
+ SkPoint transformedPoint;
+ matrix.mapXY(points[i].x(), points[i].y(), &transformedPoint);
+ fNamedDestinations.push(new NamedDestination(nameData, transformedPoint));
}
return true;
}
return false;
}
-void SkPDFDevice::addAnnotation(SkPDFDict* annotation) {
- if (nullptr == fAnnotations) {
- fAnnotations = new SkPDFArray;
+bool SkPDFDevice::handlePathAnnotation(const SkPath& path,
+ const SkDraw& d,
+ SkAnnotation* annotation) {
+ SkASSERT(annotation);
+
+ SkPath transformedPath = path;
+ transformedPath.transform(*d.fMatrix);
+ SkRasterClip clip = *d.fRC;
+ clip.op(transformedPath, SkISize::Make(width(), height()), SkRegion::kIntersect_Op, false);
+ SkRect transformedRect = SkRect::Make(clip.getBounds());
+
+ SkData* urlData = annotation->find(SkAnnotationKeys::URL_Key());
+ if (urlData) {
+ if (!transformedRect.isEmpty()) {
+ fLinkToURLs.push(new RectWithData(transformedRect, urlData));
+ }
+ return true;
}
- fAnnotations->appendObject(annotation);
+
+ SkData* linkToDestination =
+ annotation->find(SkAnnotationKeys::Link_Named_Dest_Key());
+ if (linkToDestination) {
+ if (!transformedRect.isEmpty()) {
+ fLinkToDestinations.push(new RectWithData(transformedRect, linkToDestination));
+ }
+ return true;
+ }
+
+ return false;
}
+void SkPDFDevice::appendAnnotations(SkPDFArray* array) const {
+ array->reserve(fLinkToURLs.count() + fLinkToDestinations.count());
+ for (RectWithData* rectWithURL : fLinkToURLs) {
+ SkRect r;
+ fInitialTransform.mapRect(&r, rectWithURL->rect);
+ array->appendObject(create_link_to_url(rectWithURL->data, r));
+ }
+ for (RectWithData* linkToDestination : fLinkToDestinations) {
+ SkRect r;
+ fInitialTransform.mapRect(&r, linkToDestination->rect);
+ array->appendObject(create_link_named_dest(linkToDestination->data, r));
+ }
+}
void SkPDFDevice::appendDestinations(SkPDFDict* dict, SkPDFObject* page) const {
- int nDest = fNamedDestinations.count();
- for (int i = 0; i < nDest; i++) {
- NamedDestination* dest = fNamedDestinations[i];
+ for (NamedDestination* dest : fNamedDestinations) {
SkAutoTUnref<SkPDFArray> pdfDest(new SkPDFArray);
pdfDest->reserve(5);
pdfDest->appendObjRef(SkRef(page));
pdfDest->appendName("XYZ");
- pdfDest->appendScalar(dest->point.x());
- pdfDest->appendScalar(dest->point.y());
+ SkPoint p = fInitialTransform.mapXY(dest->point.x(), dest->point.y());
+ pdfDest->appendScalar(p.x());
+ pdfDest->appendScalar(p.y());
pdfDest->appendInt(0); // Leave zoom unchanged
SkString name(static_cast<const char*>(dest->nameData->data()));
dict->insertObject(name, pdfDest.detach());
« no previous file with comments | « src/pdf/SkPDFDevice.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698