Index: gm/aaclip.cpp |
diff --git a/gm/aaclip.cpp b/gm/aaclip.cpp |
index f59f6aa2b34d11cecb39a4b6e02f53b2309874fe..d6f922344542335f26e4b2213c1150d3e8bb2f75 100644 |
--- a/gm/aaclip.cpp |
+++ b/gm/aaclip.cpp |
@@ -9,6 +9,218 @@ |
#include "SkCanvas.h" |
#include "SkPath.h" |
+class SkWStream; |
+class SkDocument : public SkRefCnt { |
+public: |
+ static SkDocument* CreatePDF(SkWStream*); |
+ |
+ SkCanvas* beginPage(SkScalar width, SkScalar height, |
+ const SkRect* content = NULL); |
+ void endPage(); |
+ void close(); |
+ |
+protected: |
+ SkDocument(SkWStream*); |
+ virtual ~SkDocument(); |
+ |
+ virtual SkCanvas* onBeginPage(SkScalar width, SkScalar height, |
+ const SkRect& content) = 0; |
+ virtual void onEndPage() = 0; |
+ virtual void onClose(SkWStream*) = 0; |
+ |
+ enum State { |
+ kBeforePage_State, |
+ kInPage_State, |
+ kAfterPage_State, |
+ kClosed_State |
+ }; |
+ State getState() const { return fState; } |
+ |
+private: |
+ SkWStream* fStream; |
+ |
+ enum State { |
+ kBeforePage_State, |
+ kInPage_State, |
+ kAfterPage_State, |
+ kClosed_State |
+ }; |
+ State fState; |
+}; |
+ |
+#include "SkPDFDocument.h" |
+#include "SkPDFDevice.h" |
+ |
+class SkDocument_PDF : public SkDocument { |
+public: |
+ SkDocument_PDF(SkWStream* stream) : SkDocument(stream) { |
+ fDoc = new SkPDFDocument; |
+ fCanvas = NULL; |
+ fDevice = NULL; |
+ } |
+ |
+ virtual ~SkDocument_PDF() { |
+ this->close(); |
+ delete fDoc; |
+ } |
+ |
+protected: |
+ virtual SkCanvas* onBeginPage(SkScalar width, SkScalar height, |
+ const SkRect& content) SK_OVERRIDE { |
+ this->endPage(); |
+ |
+ SkISize pageS, contentS; |
+ SkMatrix matrix; |
+ |
+ pageS.set(SkScalarRoundToInt(width), SkScalarRoundToInt(height)); |
+ contentS.set(SkScalarRoundToInt(content.width()), |
+ SkScalarRoundToInt(content.height())); |
+ matrix.setTranslate(content.fLeft, content.fTop); |
+ |
+ fDevice = new SkPDFDevice(pageS, contentS, matrix); |
+ fCanvas = new SkCanvas(fDevice); |
+ return fCanvas; |
+ } |
+ |
+ virtual void onEndPage() SK_OVERRIDE { |
+ if (fCanvas) { |
+ fCanvas->flush(); |
+ fDoc->appendPage(fDevice); |
+ |
+ fCanvas->unref(); |
+ fDevice->unref(); |
+ |
+ fCanvas = NULL; |
+ fDevice = NULL; |
+ } |
+ } |
+ |
+ virtual void onClose(SkWStream* stream) SK_OVERRIDE { |
+ fDoc->emitPDF(stream); |
+ |
+ delete fDoc; |
+ SkSafeUnref(fCanvas); |
+ SkSafeUnref(fDevice); |
+ |
+ fDoc = NULL; |
+ fCanvas = NULL; |
+ fDevice = NULL; |
+ } |
+ |
+private: |
+ SkPDFDocument* fDoc; |
+ SkPDFDevice* fDevice; |
+ SkCanvas* fCanvas; |
+}; |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+ |
+SkDocument* SkDocument::CreatePDF(SkScalar width, SkScalar height, |
+ const SkRect* content) { |
+ if (width > 0 && height > 0) { |
+ SkRect outer = SkRect::MakeWH(width, height); |
+ SkRect inner; |
+ if (content) { |
+ inner = *content; |
+ if (!inner.intersect(outer)) { |
+ return NULL; |
+ } |
+ } else { |
+ inner = outer; |
+ } |
+ return new SkDocument_PDF(width, height, inner); |
+ } |
+ return NULL; |
+} |
+ |
+SkDocument::SkDocument() : fState(kBeforePage_State) { |
+} |
+ |
+SkDocument::~SkDocument() { |
+} |
+ |
+SkCanvas* SkDocument::beginPage(SkScalar width, SkScalar height, |
+ const SkRect* content) { |
+ if (width <= 0 || height <= 0) { |
+ return NULL; |
+ } |
+ |
+ SkRect outer = SkRect::MakeWH(width, height); |
+ SkRect inner; |
+ if (content) { |
+ inner = *content; |
+ if (!inner.intersect(outer)) { |
+ return NULL; |
+ } |
+ } else { |
+ inner = outer; |
+ } |
+ |
+ for (;;) { |
+ switch (fState) { |
+ case kBeforePage_State: |
+ case kAfterPage_State: |
+ fState = kInPage_State; |
+ return this->beginPage(width, height, inner); |
+ case kInPage_State: |
+ this->endPage(); |
+ break; |
+ case kClosed_State: |
+ return NULL; |
+ } |
+ } |
+ SkASSERT(!"never get here"); |
+ return NULL; |
+} |
+ |
+void SkDocument::endPage() { |
+ if (kInPage_State == fState) { |
+ this->onEndPage(); |
+ } |
+} |
+ |
+void SkDocument::close() { |
+ for (;;) { |
+ switch (fState) { |
+ case kBeforePage_State: |
+ case kAfterPage_State: |
+ fState = kClosed_State; |
+ this->onClose(fStream); |
+ return; |
+ case kInPage_State: |
+ this->endPage(); |
+ break; |
+ case kClosed_State: |
+ return; |
+ } |
+ } |
+} |
+ |
+static void draw(SkCanvas* canvas) { |
+ SkPaint paint; |
+ paint.setAntiAlias(true); |
+ paint.setTextSize(50); |
+ canvas->drawText("Hello PDF", 9, 100, 100, paint); |
+ |
+ paint.setStyle(SkPaint::kStroke_Style); |
+ paint.setStrokeWidth(2); |
+ SkRect r = { 0, 0, 8.5f * 72, 11.0f * 72 }; |
+ r.inset(72 * 3 / 4, 72 * 3 / 4); |
+ canvas->drawRect(r, paint); |
+} |
+ |
+static void test_pdf(SkCanvas* canvas) { |
+ SkDocument* doc = SkDocument::CreatePDF(72 * 8.5f, 72 * 11.0f); |
+ draw(doc->beginPage()); |
+ doc->endPage(); |
+ |
+ SkFILEWStream stream("/skia/trunk/test.pdf"); |
+ doc->close(&stream); |
+ doc->unref(); |
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+ |
#include "SkGradientShader.h" |
static void test_shallow_gradient(SkCanvas* canvas, SkScalar width, SkScalar height) { |
SkColor colors[] = { 0xFF7F7F7F, 0xFF7F7F7F, 0xFF000000 }; |
@@ -219,6 +431,9 @@ protected: |
} |
virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { |
+ if (true) { |
+ test_pdf(canvas); return; |
+ } |
if (false) { |
SkRect bounds; |
canvas->getClipBounds(&bounds); |