Index: tools/render_pdfs_main.cpp |
diff --git a/tools/render_pdfs_main.cpp b/tools/render_pdfs_main.cpp |
index 34e5e58f53d0eac4949c4e236f02b3e5c47e9133..a1bd62d4f460228b52d47fcdd4e5a8700dff734a 100644 |
--- a/tools/render_pdfs_main.cpp |
+++ b/tools/render_pdfs_main.cpp |
@@ -7,19 +7,16 @@ |
#include "SkCanvas.h" |
#include "SkCommandLineFlags.h" |
-#include "SkDevice.h" |
+#include "SkDocument.h" |
#include "SkForceLinking.h" |
#include "SkGraphics.h" |
#include "SkImageEncoder.h" |
#include "SkOSFile.h" |
#include "SkPicture.h" |
-#include "SkPixelRef.h" |
#include "SkStream.h" |
#include "SkTArray.h" |
#include "SkTSort.h" |
-#include "PdfRenderer.h" |
#include "ProcStats.h" |
-#include "picture_utils.h" |
__SK_FORCE_IMAGE_DECODER_LINKING; |
@@ -120,6 +117,20 @@ static bool make_output_filepath(SkString* path, const SkString& dir, |
PDF_FILE_EXTENSION); |
} |
+namespace { |
+// This is a write-only stream. |
+class NullWStream : public SkWStream { |
+public: |
+ NullWStream() : fBytesWritten(0) { } |
+ virtual bool write(const void*, size_t size) SK_OVERRIDE { |
+ fBytesWritten += size; |
+ return true; |
+ } |
+ virtual size_t bytesWritten() const SK_OVERRIDE { return fBytesWritten; } |
+ size_t fBytesWritten; |
+}; |
+} // namespace |
+ |
/** Write the output of pdf renderer to a file. |
* @param outputDir Output dir. |
* @param inputFilename The skp file that was read. |
@@ -128,7 +139,7 @@ static bool make_output_filepath(SkString* path, const SkString& dir, |
static SkWStream* open_stream(const SkString& outputDir, |
const SkString& inputFilename) { |
if (outputDir.isEmpty()) { |
- return SkNEW(SkDynamicMemoryWStream); |
+ return SkNEW(NullWStream); |
} |
SkString outputPath; |
@@ -136,72 +147,44 @@ static SkWStream* open_stream(const SkString& outputDir, |
return NULL; |
} |
- SkFILEWStream* stream = SkNEW_ARGS(SkFILEWStream, (outputPath.c_str())); |
- if (!stream->isValid()) { |
+ SkAutoTDelete<SkFILEWStream> stream( |
+ SkNEW_ARGS(SkFILEWStream, (outputPath.c_str()))); |
+ if (!stream.get() || !stream->isValid()) { |
SkDebugf("Could not write to file %s\n", outputPath.c_str()); |
return NULL; |
} |
- return stream; |
+ return stream.detach(); |
} |
-/** Reads an skp file, renders it to pdf and writes the output to a pdf file |
- * @param inputPath The skp file to be read. |
- * @param outputDir Output dir. |
- * @param renderer The object responsible to render the skp object into pdf. |
+/** |
+ * Given a SkPicture, write a one-page PDF document to the given |
+ * output, using the provided encoder. |
*/ |
-static bool render_pdf(const SkString& inputPath, const SkString& outputDir, |
- sk_tools::PdfRenderer& renderer) { |
- SkString inputFilename = SkOSPath::Basename(inputPath.c_str()); |
- |
- SkFILEStream inputStream; |
- inputStream.setPath(inputPath.c_str()); |
- if (!inputStream.isValid()) { |
- SkDebugf("Could not open file %s\n", inputPath.c_str()); |
- return false; |
- } |
- |
- SkAutoTUnref<SkPicture> picture(SkPicture::CreateFromStream(&inputStream)); |
- |
- if (NULL == picture.get()) { |
- SkDebugf("Could not read an SkPicture from %s\n", inputPath.c_str()); |
- return false; |
- } |
- |
- SkDebugf("exporting... [%-4i %6i] %s\n", |
- picture->width(), picture->height(), inputPath.c_str()); |
- |
- SkWStream* stream(open_stream(outputDir, inputFilename)); |
- |
- if (!stream) { |
- return false; |
- } |
- |
- renderer.init(picture, stream); |
- |
- bool success = renderer.render(); |
- SkDELETE(stream); |
- |
- renderer.end(); |
- |
- return success; |
+static bool pdf_to_stream(SkPicture* picture, |
+ SkWStream* output, |
+ SkPicture::EncodeBitmap encoder) { |
+ SkAutoTUnref<SkDocument> pdfDocument( |
+ SkDocument::CreatePDF(output, NULL, encoder)); |
+ SkCanvas* canvas = pdfDocument->beginPage( |
+ SkIntToScalar(picture->width()), |
+ SkIntToScalar(picture->height())); |
+ canvas->drawPicture(picture); |
+ canvas->flush(); |
+ return pdfDocument->close(); |
} |
static bool operator<(const SkString& a, const SkString& b) { |
return strcmp(a.c_str(), b.c_str()) < 0; |
} |
-/** For each file in the directory or for the file passed in input, call |
- * render_pdf. |
- * @param input A directory or an skp file. |
- * @param outputDir Output dir. |
- * @param renderer The object responsible to render the skp object into pdf. |
+/** |
+ * @param A list of directories or a skp files. |
+ * @returns an alphabetical list of skp files. |
*/ |
-static int process_input( |
+static void process_input_files( |
const SkCommandLineFlags::StringArray& inputs, |
- const SkString& outputDir, |
- sk_tools::PdfRenderer& renderer) { |
- SkTArray<SkString> files; |
+ SkTArray<SkString>* files) { |
for (int i = 0; i < inputs.count(); i ++) { |
const char* input = inputs[i]; |
if (sk_isdir(input)) { |
@@ -210,52 +193,90 @@ static int process_input( |
while (iter.next(&inputFilename)) { |
if (!SkCommandLineFlags::ShouldSkip( |
FLAGS_match, inputFilename.c_str())) { |
- files.push_back( |
+ files->push_back( |
SkOSPath::Join(input, inputFilename.c_str())); |
} |
} |
} else { |
if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, input)) { |
- files.push_back(SkString(input)); |
+ files->push_back(SkString(input)); |
} |
} |
} |
- if (files.count() > 0) { |
- SkTQSort<SkString>(files.begin(), files.end() - 1); |
- } |
- int failures = 0; |
- for (int i = 0; i < files.count(); i ++) { |
- if (!render_pdf(files[i], outputDir, renderer)) { |
- ++failures; |
- } |
+ if (files->count() > 0) { |
+ SkTQSort<SkString>(files->begin(), files->end() - 1); |
} |
- return failures; |
} |
+/** For each input skp file, read it, render it to pdf and write. the |
+ * output to a pdf file |
+ */ |
int tool_main_core(int argc, char** argv); |
int tool_main_core(int argc, char** argv) { |
SkCommandLineFlags::Parse(argc, argv); |
SkAutoGraphics ag; |
- SkAutoTUnref<sk_tools::PdfRenderer> |
- renderer(SkNEW_ARGS(sk_tools::SimplePdfRenderer, (encode_to_dct_data))); |
- SkASSERT(renderer.get()); |
- |
SkString outputDir; |
if (FLAGS_outputDir.count() > 0) { |
outputDir = FLAGS_outputDir[0]; |
+ if (!sk_mkdir(outputDir.c_str())) { |
+ SkDebugf("Unable to mkdir '%s'\n", outputDir.c_str()); |
+ return 1; |
+ } |
} |
- int failures = process_input(FLAGS_inputPaths, outputDir, *renderer); |
+ SkTArray<SkString> files; |
+ process_input_files(FLAGS_inputPaths, &files); |
- int max_rss_kb = sk_tools::getMaxResidentSetSizeKB(); |
- if (max_rss_kb >= 0) { |
- SkDebugf("%4dM peak ResidentSetSize\n", max_rss_kb / 1024); |
+ size_t maximumPathLength = 0; |
+ for (int i = 0; i < files.count(); i ++) { |
+ SkString basename = SkOSPath::Basename(files[i].c_str()); |
+ maximumPathLength = SkTMax(maximumPathLength, basename.size()); |
} |
+ int failures = 0; |
+ for (int i = 0; i < files.count(); i ++) { |
+ SkString basename = SkOSPath::Basename(files[i].c_str()); |
+ |
+ SkFILEStream inputStream; |
+ inputStream.setPath(files[i].c_str()); |
+ if (!inputStream.isValid()) { |
+ SkDebugf("Could not open file %s\n", files[i].c_str()); |
+ ++failures; |
+ continue; |
+ } |
+ |
+ SkAutoTUnref<SkPicture> picture( |
+ SkPicture::CreateFromStream(&inputStream)); |
+ if (NULL == picture.get()) { |
+ SkDebugf("Could not read an SkPicture from %s\n", |
+ files[i].c_str()); |
+ ++failures; |
+ continue; |
+ } |
+ SkDebugf("[%-4i %6i] %-*s", picture->width(), picture->height(), |
+ maximumPathLength, basename.c_str()); |
+ |
+ SkAutoTDelete<SkWStream> stream(open_stream(outputDir, files[i])); |
+ if (!stream.get()) { |
+ ++failures; |
+ continue; |
+ } |
+ if (!pdf_to_stream(picture, stream.get(), encode_to_dct_data)) { |
+ SkDebugf("Error in PDF Serialization."); |
+ ++failures; |
+ } |
+ |
+ int max_rss_kb = sk_tools::getMaxResidentSetSizeKB(); |
+ if (max_rss_kb >= 0) { |
+ SkDebugf(" %4dM peak rss", max_rss_kb / 1024); |
+ } |
+ |
+ SkDebugf("\n"); |
+ } |
if (failures != 0) { |
- SkDebugf("Failed to render %i PDFs.\n", failures); |
+ SkDebugf("Failed to render %i of %i PDFs.\n", failures, files.count()); |
return 1; |
} |
@@ -278,7 +299,6 @@ int tool_main(int argc, char** argv) { |
#endif |
return 0; |
} |
- |
#if !defined SK_BUILD_FOR_IOS |
int main(int argc, char * const argv[]) { |
return tool_main(argc, (char**) argv); |