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

Unified Diff: src/pdf/SkPDFDevice.cpp

Issue 19519017: Inverse fill support in PDF (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Add comprehensive inverse paths GM Created 7 years, 5 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
« gm/inversepaths.cpp ('K') | « include/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 387bfe836148b7715c3be37189e3d8e7e64dc670..c332468c05888b2ba378ad57275eb2a6ff729c02 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -16,6 +16,7 @@
#include "SkGlyphCache.h"
#include "SkPaint.h"
#include "SkPath.h"
+#include "SkPathOps.h"
#include "SkPDFFont.h"
#include "SkPDFFormXObject.h"
#include "SkPDFGraphicState.h"
@@ -842,6 +843,13 @@ void SkPDFDevice::drawPath(const SkDraw& d, const SkPath& origPath,
return;
}
+#ifdef SK_PDF_USE_PATHOPS
+ if (origPath.isInverseFillType()) {
vandebo (ex-Chrome) 2013/07/30 16:50:42 nit: Push this into the handle method... if (hand
ducky 2013/07/30 22:01:55 Done.
+ handleInversePath(d, origPath, paint, pathIsMutable);
+ return;
+ }
+#endif
+
if (handleRectAnnotation(pathPtr->getBounds(), *d.fMatrix, paint)) {
return;
}
@@ -1232,6 +1240,70 @@ SkData* SkPDFDevice::copyContentToData() const {
return data.copyToData();
}
+/* Calculate an inverted path's equivalent non-inverted path, given the
+ * canvas bounds.
+ */
+bool calculate_inverse_path(const SkRect& bounds, const SkPath& invPath,
vandebo (ex-Chrome) 2013/07/30 16:50:42 You can inline this function unless you intend to
ducky 2013/07/30 22:01:55 I probably should have noted that this was to get
+ SkPath* outPath) {
+ SkASSERT(invPath.isInverseFillType());
+
+ SkPath clipPath;
+ clipPath.addRect(bounds);
+
+ return Op(clipPath, invPath, kIntersect_PathOp, outPath);
+}
+
+/* Draws an inverse filled path by using Path Ops to compute the positive
+ * inverse using the current clip as the inverse bounds.
+ */
+void SkPDFDevice::handleInversePath(const SkDraw& d, const SkPath& origPath,
+ const SkPaint& paint, bool pathIsMutable) {
+ SkASSERT(origPath.isInverseFillType());
+
+ if (d.fClip->isEmpty()) {
+ return;
+ }
+
+ SkPath modifiedPath;
+ SkPath* pathPtr = const_cast<SkPath*>(&origPath);
+ SkPaint noInversePaint(paint);
+
+ // Merge stroking operations into final path.
+ if (SkPaint::kStroke_Style == paint.getStyle() ||
+ SkPaint::kStrokeAndFill_Style == paint.getStyle()) {
+ pathPtr = &modifiedPath;
+ if (paint.getFillPath(origPath, pathPtr)) {
+ noInversePaint.setStyle(SkPaint::kFill_Style);
+ noInversePaint.setStrokeWidth(0);
+ } else {
+ // To be consistent with the raster output, hairline strokes
vandebo (ex-Chrome) 2013/07/30 16:50:42 At this point pathPtr points to modifiedPath that
ducky 2013/07/30 22:01:55 I think paint.getFillPath still duplicates the pai
+ // are rendered as non-inverted.
+ pathPtr->toggleInverseFillType();
+ drawPath(d, *pathPtr, paint, NULL, true);
+ return;
vandebo (ex-Chrome) 2013/07/30 16:50:42 After you've changed this to return a bool though,
ducky 2013/07/30 22:01:55 I can see how that would be faster, but it seems l
+ }
+ }
+
+ // Get bounds of clip in current transform space
+ // (clip bounds are given in device space).
+ SkRect bounds;
+ SkMatrix transformInverse;
+ if (!d.fMatrix->invert(&transformInverse)) {
+ return;
+ }
+ bounds.set(d.fClip->getBounds());
+ transformInverse.mapRect(&bounds);
+
+ // Extend the bounds by the line width (plus some padding)
+ // so the edge doesn't cause a visible stroke.
+ bounds.outset(paint.getStrokeWidth() + SK_Scalar1,
+ paint.getStrokeWidth() + SK_Scalar1);
+
+ if (calculate_inverse_path(bounds, *pathPtr, &modifiedPath)) {
+ drawPath(d, modifiedPath, noInversePaint, NULL, true);
+ }
+}
+
bool SkPDFDevice::handleRectAnnotation(const SkRect& r, const SkMatrix& matrix,
const SkPaint& p) {
SkAnnotation* annotationInfo = p.getAnnotation();
« gm/inversepaths.cpp ('K') | « include/pdf/SkPDFDevice.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698