[PDF] Improve path effect and drawPath(prePathMatrix) support.
authorvandebo@chromium.org <vandebo@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 17 May 2011 18:58:44 +0000 (18:58 +0000)
committervandebo@chromium.org <vandebo@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 17 May 2011 18:58:44 +0000 (18:58 +0000)
Add path effect handling for drawPoints (via drawPath).
Move path effect handling from drawRect to drawPath.
Add prePathMatrix support to drawPath.

BUG=crbug.com/82849

Review URL: http://codereview.appspot.com/4531047

git-svn-id: http://skia.googlecode.com/svn/trunk@1354 2bbb7eff-a529-9590-31e7-b0007b416f81

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

index cdae413..94c30d8 100644 (file)
@@ -91,7 +91,7 @@ public:
                             size_t count, const SkPoint[],
                             const SkPaint& paint);
     virtual void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint);
-    virtual void drawPath(const SkDraw&, const SkPath& path,
+    virtual void drawPath(const SkDraw&, const SkPath& origpath,
                           const SkPaint& paint, const SkMatrix* prePathMatrix,
                           bool pathIsMutable);
     virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
index 6734c0e..d55deca 100644 (file)
@@ -590,6 +590,19 @@ void SkPDFDevice::drawPoints(const SkDraw& d, SkCanvas::PointMode mode,
         return;
     }
 
+    // SkDraw::drawPoints converts to multiple calls to fDevice->drawPath.
+    // We only use this when there's a path effect because of the overhead
+    // of multiple calls to setUpContentEntry it causes.
+    if (passedPaint.getPathEffect()) {
+        if (d.fClip->isEmpty()) {
+            return;
+        }
+        SkDraw pointDraw(d);
+        pointDraw.fDevice = this;
+        pointDraw.drawPoints(mode, count, points, passedPaint, true);
+        return;
+    }
+
     const SkPaint* paint = &passedPaint;
     SkPaint modifiedPaint;
 
@@ -660,14 +673,9 @@ void SkPDFDevice::drawRect(const SkDraw& d, const SkRect& r,
         if (d.fClip->isEmpty()) {
             return;
         }
-        // Create a path for the rectangle and apply the path effect to it.
         SkPath path;
         path.addRect(r);
-        paint.getFillPath(path, &path);
-
-        SkPaint noEffectPaint(paint);
-        SkSafeUnref(noEffectPaint.setPathEffect(NULL));
-        drawPath(d, path, noEffectPaint, NULL, true);
+        drawPath(d, path, paint, NULL, true);
         return;
     }
     if (!setUpContentEntry(d.fClipStack, *d.fClip, *d.fMatrix, paint)) {
@@ -680,30 +688,54 @@ void SkPDFDevice::drawRect(const SkDraw& d, const SkRect& r,
     finishContentEntry(paint);
 }
 
-void SkPDFDevice::drawPath(const SkDraw& d, const SkPath& path,
+void SkPDFDevice::drawPath(const SkDraw& d, const SkPath& origPath,
                            const SkPaint& paint, const SkMatrix* prePathMatrix,
                            bool pathIsMutable) {
-    NOT_IMPLEMENTED(prePathMatrix != NULL, true);
+    SkPath modifiedPath;
+    SkPath* pathPtr = const_cast<SkPath*>(&origPath);
+
+    SkMatrix matrix = *d.fMatrix;
+    if (prePathMatrix) {
+        if (paint.getPathEffect() || paint.getStyle() != SkPaint::kFill_Style) {
+            if (!pathIsMutable) {
+                pathPtr = &modifiedPath;
+                pathIsMutable = true;
+            }
+            origPath.transform(*prePathMatrix, pathPtr);
+        } else {
+            if (!matrix.preConcat(*prePathMatrix)) {
+                return;
+            }
+        }
+    }
 
     if (paint.getPathEffect()) {
         if (d.fClip->isEmpty()) {
             return;
         }
-        // Apply the path effect to path and draw it that way.
-        SkPath noEffectPath;
-        paint.getFillPath(path, &noEffectPath);
+        if (!pathIsMutable) {
+            pathPtr = &modifiedPath;
+            pathIsMutable = true;
+        }
+        bool fill = paint.getFillPath(origPath, pathPtr);
 
         SkPaint noEffectPaint(paint);
-        SkSafeUnref(noEffectPaint.setPathEffect(NULL));
-        drawPath(d, noEffectPath, noEffectPaint, NULL, true);
+        noEffectPaint.setPathEffect(NULL);
+        if (fill) {
+            noEffectPaint.setStyle(SkPaint::kFill_Style);
+        } else {
+            noEffectPaint.setStyle(SkPaint::kStroke_Style);
+            noEffectPaint.setStrokeWidth(0);
+        }
+        drawPath(d, *pathPtr, noEffectPaint, NULL, true);
         return;
     }
+
     if (!setUpContentEntry(d.fClipStack, *d.fClip, *d.fMatrix, paint)) {
         return;
     }
-
-    SkPDFUtils::EmitPath(path, &fCurrentContentEntry->fContent);
-    SkPDFUtils::PaintPath(paint.getStyle(), path.getFillType(),
+    SkPDFUtils::EmitPath(*pathPtr, &fCurrentContentEntry->fContent);
+    SkPDFUtils::PaintPath(paint.getStyle(), pathPtr->getFillType(),
                           &fCurrentContentEntry->fContent);
     finishContentEntry(paint);
 }