aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar vandebo@chromium.org <vandebo@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-04-15 20:57:37 +0000
committerGravatar vandebo@chromium.org <vandebo@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-04-15 20:57:37 +0000
commit77bcaa324a574584331322d98768582d9232f7fc (patch)
tree7c66fac2c5030330815c05bb6ac0f6441dda73af
parentfb0b0edd86d71bb423fa921eaac1e2071602115c (diff)
[PDF] Implement clear() method and a couple fixes.
+ If the clip matches the initial clip, don't set the clip. + Don't change the transform for drawPaint. Review URL: http://codereview.appspot.com/4424041 git-svn-id: http://skia.googlecode.com/svn/trunk@1142 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--include/pdf/SkPDFDevice.h6
-rw-r--r--src/pdf/SkPDFDevice.cpp91
2 files changed, 72 insertions, 25 deletions
diff --git a/include/pdf/SkPDFDevice.h b/include/pdf/SkPDFDevice.h
index 2b9e5e6324..ac9ef20fc4 100644
--- a/include/pdf/SkPDFDevice.h
+++ b/include/pdf/SkPDFDevice.h
@@ -71,6 +71,8 @@ public:
virtual int height() const { return fHeight; };
+ virtual void clear(SkColor color);
+
/** Called with the correct matrix and clip before this device is drawn
to using those settings. If your subclass overrides this, be sure to
call through to the base class as well.
@@ -175,6 +177,8 @@ private:
SkDynamicMemoryWStream fContent;
+ void init();
+ void cleanUp();
void updateGSFromPaint(const SkPaint& newPaint, bool forText);
void updateFont(const SkPaint& paint, uint16_t glyphID);
int getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID);
@@ -182,6 +186,8 @@ private:
void pushGS();
void popGS();
void setTextTransform(SkScalar x, SkScalar y, SkScalar textSkewX);
+ void internalDrawPaint(const SkPaint& paint);
+ void internalDrawRect(const SkRect& r, const SkPaint& paint);
void internalDrawBitmap(const SkMatrix& matrix, const SkBitmap& bitmap,
const SkIRect* srcRect, const SkPaint& paint);
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index 675289489d..efe7257704 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -21,13 +21,13 @@
#include "SkGlyphCache.h"
#include "SkPaint.h"
#include "SkPath.h"
-#include "SkPDFImage.h"
-#include "SkPDFGraphicState.h"
#include "SkPDFFont.h"
#include "SkPDFFormXObject.h"
-#include "SkPDFTypes.h"
+#include "SkPDFGraphicState.h"
+#include "SkPDFImage.h"
#include "SkPDFShader.h"
#include "SkPDFStream.h"
+#include "SkPDFTypes.h"
#include "SkPDFUtils.h"
#include "SkRect.h"
#include "SkString.h"
@@ -135,6 +135,21 @@ SkPDFDevice::SkPDFDevice(int width, int height,
fWidth(width),
fHeight(height),
fGraphicStackIndex(0) {
+ // Skia generally uses the top left as the origin but PDF natively has the
+ // origin at the bottom left. This matrix corrects for that. When layering,
+ // we specify an inverse correction to cancel this out.
+ fInitialTransform.setTranslate(0, height);
+ fInitialTransform.preScale(1, -1);
+ fInitialTransform.preConcat(initialTransform);
+
+ this->init();
+}
+
+SkPDFDevice::~SkPDFDevice() {
+ this->cleanUp();
+}
+
+void SkPDFDevice::init() {
fGraphicStack[0].fColor = SK_ColorBLACK;
fGraphicStack[0].fTextSize = SK_ScalarNaN; // This has no default value.
fGraphicStack[0].fTextScaleX = SK_Scalar1;
@@ -142,27 +157,41 @@ SkPDFDevice::SkPDFDevice(int width, int height,
fGraphicStack[0].fFont = NULL;
fGraphicStack[0].fShader = NULL;
fGraphicStack[0].fGraphicState = NULL;
- fGraphicStack[0].fClip.setRect(0,0, width, height);
+ fGraphicStack[0].fClip.setRect(0,0, fWidth, fHeight);
fGraphicStack[0].fTransform.reset();
+ fGraphicStackIndex = 0;
+ fResourceDict = NULL;
+ fContent.reset();
- // Skia generally uses the top left as the origin but PDF natively has the
- // origin at the bottom left. This matrix corrects for that. When layering,
- // we specify an inverse correction to cancel this out.
- fInitialTransform.setTranslate(0, height);
- fInitialTransform.preScale(1, -1);
- fInitialTransform.preConcat(initialTransform);
if (fInitialTransform.getType() != SkMatrix::kIdentity_Mask) {
SkPDFUtils::AppendTransform(fInitialTransform, &fContent);
}
}
-SkPDFDevice::~SkPDFDevice() {
+void SkPDFDevice::cleanUp() {
fGraphicStateResources.unrefAll();
fXObjectResources.unrefAll();
fFontResources.unrefAll();
fShaderResources.unrefAll();
}
+void SkPDFDevice::clear(SkColor color) {
+ SkMatrix curTransform = fGraphicStack[fGraphicStackIndex].fTransform;
+ SkRegion curClip = fGraphicStack[fGraphicStackIndex].fClip;
+
+ this->cleanUp();
+ this->init();
+
+ SkPaint paint;
+ paint.setColor(color);
+ paint.setStyle(SkPaint::kFill_Style);
+ updateGSFromPaint(paint, false);
+ internalDrawPaint(paint);
+
+ SkClipStack clipStack;
+ setMatrixClip(curTransform, curClip, clipStack);
+}
+
void SkPDFDevice::setMatrixClip(const SkMatrix& matrix,
const SkRegion& region,
const SkClipStack&) {
@@ -180,12 +209,14 @@ void SkPDFDevice::setMatrixClip(const SkMatrix& matrix,
if (region != fGraphicStack[fGraphicStackIndex].fClip) {
while (fGraphicStackIndex > 0)
popGS();
- pushGS();
- SkPath clipPath;
- if (region.getBoundaryPath(&clipPath)) {
- SkPDFUtils::EmitPath(clipPath, &fContent);
+ if (region != fGraphicStack[fGraphicStackIndex].fClip) {
+ pushGS();
+ SkPath clipPath;
+ SkAssertResult(region.getBoundaryPath(&clipPath));
+
+ SkPDFUtils::EmitPath(clipPath, &fContent);
SkPath::FillType clipFill = clipPath.getFillType();
NOT_IMPLEMENTED(clipFill == SkPath::kInverseEvenOdd_FillType,
false);
@@ -195,9 +226,9 @@ void SkPDFDevice::setMatrixClip(const SkMatrix& matrix,
fContent.writeText("W* n ");
else
fContent.writeText("W n ");
- }
- fGraphicStack[fGraphicStackIndex].fClip = region;
+ fGraphicStack[fGraphicStackIndex].fClip = region;
+ }
}
setTransform(matrix);
}
@@ -207,18 +238,24 @@ void SkPDFDevice::drawPaint(const SkDraw& d, const SkPaint& paint) {
return;
}
- SkMatrix identityTransform;
- identityTransform.reset();
- SkMatrix curTransform = setTransform(identityTransform);
-
SkPaint newPaint = paint;
newPaint.setStyle(SkPaint::kFill_Style);
updateGSFromPaint(newPaint, false);
- SkRect all = SkRect::MakeWH(SkIntToScalar(this->width()),
- SkIntToScalar(this->height()));
- drawRect(d, all, newPaint);
- setTransform(curTransform);
+ internalDrawPaint(newPaint);
+}
+
+void SkPDFDevice::internalDrawPaint(const SkPaint& paint) {
+ SkRect bbox = SkRect::MakeWH(SkIntToScalar(this->width()),
+ SkIntToScalar(this->height()));
+ SkMatrix totalTransform = fInitialTransform;
+ totalTransform.preConcat(fGraphicStack[fGraphicStackIndex].fTransform);
+ SkMatrix inverse;
+ inverse.reset();
+ totalTransform.invert(&inverse);
+ inverse.mapRect(&bbox);
+
+ internalDrawRect(bbox, paint);
}
void SkPDFDevice::drawPoints(const SkDraw& d, SkCanvas::PointMode mode,
@@ -293,6 +330,10 @@ void SkPDFDevice::drawRect(const SkDraw& d, const SkRect& r,
}
updateGSFromPaint(paint, false);
+ internalDrawRect(r, paint);
+}
+
+void SkPDFDevice::internalDrawRect(const SkRect& r, const SkPaint& paint) {
// Skia has 0,0 at top left, pdf at bottom left. Do the right thing.
SkScalar bottom = r.fBottom < r.fTop ? r.fBottom : r.fTop;
SkPDFUtils::AppendRectangle(r.fLeft, bottom, r.width(), r.height(),