Add SkPDFDeviceFlatenner which extends SkPDFDevice to add support to flatten the path and the text when we have perspective.
prepare to deprecate SkPDFDevice constructor, and route gm and render_pdfs to use SkDocument::Create pdf interface instead. - controlled by a flag
add comments where we are supposed to flatten other features (paint, shaders, ... )
R=reed@google.com, bungeman@google.com, scroggo@google.com, vandebo@chromium.org, bsalomon@google.com
Author: edisonn@google.com
Review URL: https://codereview.chromium.org/24811002
git-svn-id: http://skia.googlecode.com/svn/trunk@11751 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/tools/PdfRenderer.cpp b/tools/PdfRenderer.cpp
index 704cbea..890abde 100644
--- a/tools/PdfRenderer.cpp
+++ b/tools/PdfRenderer.cpp
@@ -13,7 +13,7 @@
namespace sk_tools {
-void PdfRenderer::init(SkPicture* pict) {
+void PdfRenderer::init(SkPicture* pict, SkWStream* stream) {
SkASSERT(NULL == fPicture);
SkASSERT(NULL == fCanvas.get());
if (fPicture != NULL || NULL != fCanvas.get()) {
@@ -26,44 +26,35 @@
}
fPicture = pict;
- fCanvas.reset(this->setupCanvas());
+ fCanvas.reset(this->setupCanvas(stream, pict->width(), pict->height()));
}
-SkCanvas* PdfRenderer::setupCanvas() {
- return this->setupCanvas(fPicture->width(), fPicture->height());
-}
+SkCanvas* PdfRenderer::setupCanvas(SkWStream* stream, int width, int height) {
+ fPdfDoc.reset(SkDocument::CreatePDF(stream, NULL, fEncoder));
-SkCanvas* PdfRenderer::setupCanvas(int width, int height) {
- SkISize pageSize = SkISize::Make(width, height);
- fPDFDevice = SkNEW_ARGS(SkPDFDevice, (pageSize, pageSize, SkMatrix::I()));
- fPDFDevice->setDCTEncoder(fEncoder);
- return SkNEW_ARGS(SkCanvas, (fPDFDevice));
+ SkCanvas* canvas = fPdfDoc->beginPage(SkIntToScalar(width), SkIntToScalar(height));
+ canvas->ref();
+
+ return canvas;
}
void PdfRenderer::end() {
fPicture = NULL;
fCanvas.reset(NULL);
- if (fPDFDevice) {
- SkDELETE(fPDFDevice);
- fPDFDevice = NULL;
- }
+ fPdfDoc.reset(NULL);
}
-void PdfRenderer::write(SkWStream* stream) const {
- SkPDFDocument doc;
- doc.appendPage(fPDFDevice);
- doc.emitPDF(stream);
-}
-
-void SimplePdfRenderer::render() {
+bool SimplePdfRenderer::render() {
SkASSERT(fCanvas.get() != NULL);
SkASSERT(fPicture != NULL);
if (NULL == fCanvas.get() || NULL == fPicture) {
- return;
+ return false;
}
fCanvas->drawPicture(*fPicture);
fCanvas->flush();
+
+ return fPdfDoc->close();
}
}
diff --git a/tools/PdfRenderer.h b/tools/PdfRenderer.h
index be338e9..d70c458 100644
--- a/tools/PdfRenderer.h
+++ b/tools/PdfRenderer.h
@@ -13,8 +13,8 @@
// An SkPicture can be built manually, or read from an SKP file.
//
+#include "SkDocument.h"
#include "SkMath.h"
-#include "SkPDFDevice.h"
#include "SkPicture.h"
#include "SkTypes.h"
#include "SkTDArray.h"
@@ -23,32 +23,30 @@
class SkBitmap;
class SkCanvas;
+class SkWStream;
namespace sk_tools {
class PdfRenderer : public SkRefCnt {
public:
- virtual void init(SkPicture* pict);
+ virtual void init(SkPicture* pict, SkWStream* stream);
virtual void setup() {}
- virtual void render() = 0;
+ virtual bool render() = 0;
virtual void end();
PdfRenderer(SkPicture::EncodeBitmap encoder)
: fPicture(NULL)
- , fPDFDevice(NULL)
, fEncoder(encoder)
+ , fPdfDoc(NULL)
{}
- void write(SkWStream* stream) const;
-
protected:
- SkCanvas* setupCanvas();
- SkCanvas* setupCanvas(int width, int height);
+ SkCanvas* setupCanvas(SkWStream* stream, int width, int height);
SkAutoTUnref<SkCanvas> fCanvas;
SkPicture* fPicture;
- SkPDFDevice* fPDFDevice;
SkPicture::EncodeBitmap fEncoder;
+ SkAutoTUnref<SkDocument> fPdfDoc;
private:
typedef SkRefCnt INHERITED;
@@ -58,7 +56,7 @@
public:
SimplePdfRenderer(SkPicture::EncodeBitmap encoder)
: PdfRenderer(encoder) {}
- virtual void render() SK_OVERRIDE;
+ virtual bool render() SK_OVERRIDE;
private:
typedef PdfRenderer INHERITED;
diff --git a/tools/render_pdfs_main.cpp b/tools/render_pdfs_main.cpp
index a710064..e07664c 100644
--- a/tools/render_pdfs_main.cpp
+++ b/tools/render_pdfs_main.cpp
@@ -131,28 +131,24 @@
* @param inputFilename The skp file that was read.
* @param renderer The object responsible to write the pdf file.
*/
-static bool write_output(const SkString& outputDir,
- const SkString& inputFilename,
- const sk_tools::PdfRenderer& renderer) {
+static SkWStream* open_stream(const SkString& outputDir,
+ const SkString& inputFilename) {
if (outputDir.isEmpty()) {
- SkDynamicMemoryWStream stream;
- renderer.write(&stream);
- return true;
+ return SkNEW(SkDynamicMemoryWStream);
}
SkString outputPath;
if (!make_output_filepath(&outputPath, outputDir, inputFilename)) {
- return false;
+ return NULL;
}
- SkFILEWStream stream(outputPath.c_str());
- if (!stream.isValid()) {
+ SkFILEWStream* stream = SkNEW_ARGS(SkFILEWStream, (outputPath.c_str()));
+ if (!stream->isValid()) {
SkDebugf("Could not write to file %s\n", outputPath.c_str());
- return false;
+ return NULL;
}
- renderer.write(&stream);
- return true;
+ return stream;
}
/** Reads an skp file, renders it to pdf and writes the output to a pdf file
@@ -182,13 +178,19 @@
SkDebugf("exporting... [%i %i] %s\n", picture->width(), picture->height(),
inputPath.c_str());
- renderer.init(picture);
+ SkWStream* stream(open_stream(outputDir, inputFilename));
- renderer.render();
+ if (!stream) {
+ return false;
+ }
- bool success = write_output(outputDir, inputFilename, renderer);
+ renderer.init(picture, stream);
+
+ bool success = renderer.render();
+ SkDELETE(stream);
renderer.end();
+
return success;
}