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

Unified Diff: src/pdf/SkPDFDevice.cpp

Issue 19519017: Inverse fill support in PDF (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Fix indent 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
« no previous file with comments | « 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..eda3616a1f7681a1fcd7c2c9895a1c6a8ee74781 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,12 @@ void SkPDFDevice::drawPath(const SkDraw& d, const SkPath& origPath,
return;
}
+#ifdef SK_PDF_USE_PATHOPS
+ if (handleInversePath(d, origPath, paint, pathIsMutable)) {
+ return;
+ }
+#endif
+
if (handleRectAnnotation(pathPtr->getBounds(), *d.fMatrix, paint)) {
return;
}
@@ -1232,6 +1239,80 @@ SkData* SkPDFDevice::copyContentToData() const {
return data.copyToData();
}
+/* Calculate an inverted path's equivalent non-inverted path, given the
+ * canvas bounds.
+ */
+static bool calculate_inverse_path(const SkRect& bounds, const SkPath& invPath,
+ 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.
+ * Return true if this was an inverse path and was properly handled,
+ * otherwise returns false and the normal drawing routine should continue,
+ * either as a (incorrect) fallback or because the path was not inverse
+ * in the first place.
+ */
+bool SkPDFDevice::handleInversePath(const SkDraw& d, const SkPath& origPath,
+ const SkPaint& paint, bool pathIsMutable) {
+ if (!origPath.isInverseFillType()) {
+ return false;
+ }
+
+ if (d.fClip->isEmpty()) {
+ return false;
+ }
+
+ 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()) {
+ bool doFillPath = paint.getFillPath(origPath, &modifiedPath);
+ if (doFillPath) {
+ noInversePaint.setStyle(SkPaint::kFill_Style);
+ noInversePaint.setStrokeWidth(0);
+ pathPtr = &modifiedPath;
+ } else {
+ // To be consistent with the raster output, hairline strokes
+ // are rendered as non-inverted.
+ modifiedPath.toggleInverseFillType();
+ drawPath(d, modifiedPath, paint, NULL, true);
+ return true;
+ }
+ }
+
+ // 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 false;
+ }
+ 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)) {
+ return false;
+ }
+
+ drawPath(d, modifiedPath, noInversePaint, NULL, true);
+ return true;
+}
+
bool SkPDFDevice::handleRectAnnotation(const SkRect& r, const SkMatrix& matrix,
const SkPaint& p) {
SkAnnotation* annotationInfo = p.getAnnotation();
« no previous file with comments | « include/pdf/SkPDFDevice.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698