From: vandebo@chromium.org Date: Fri, 15 Apr 2011 20:57:37 +0000 (+0000) Subject: [PDF] Implement clear() method and a couple fixes. X-Git-Tag: accepted/tizen/5.0/unified/20181102.025319~18659 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=77bcaa324a574584331322d98768582d9232f7fc;p=platform%2Fupstream%2FlibSkiaSharp.git [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 --- diff --git a/include/pdf/SkPDFDevice.h b/include/pdf/SkPDFDevice.h index 2b9e5e6..ac9ef20 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 6752894..efe7257 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(),