1c319abeeef205627dafd52d977157beafd409313edisonn@google.com/*
2c319abeeef205627dafd52d977157beafd409313edisonn@google.com * Copyright 2012 Google Inc.
3c319abeeef205627dafd52d977157beafd409313edisonn@google.com *
4c319abeeef205627dafd52d977157beafd409313edisonn@google.com * Use of this source code is governed by a BSD-style license that can be
5c319abeeef205627dafd52d977157beafd409313edisonn@google.com * found in the LICENSE file.
6c319abeeef205627dafd52d977157beafd409313edisonn@google.com */
7c319abeeef205627dafd52d977157beafd409313edisonn@google.com
8c319abeeef205627dafd52d977157beafd409313edisonn@google.com#include "SkCanvas.h"
90bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary#include "SkCommandLineFlags.h"
108b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary#include "SkDocument.h"
117def5e1630d47cdbfa4b58a9c86bc060693c4d79scroggo@google.com#include "SkForceLinking.h"
12c319abeeef205627dafd52d977157beafd409313edisonn@google.com#include "SkGraphics.h"
13d9dfa18372119c8e1318125d2075fa80e0819094edisonn@google.com#include "SkImageEncoder.h"
14c319abeeef205627dafd52d977157beafd409313edisonn@google.com#include "SkOSFile.h"
15c319abeeef205627dafd52d977157beafd409313edisonn@google.com#include "SkPicture.h"
16c319abeeef205627dafd52d977157beafd409313edisonn@google.com#include "SkStream.h"
17c319abeeef205627dafd52d977157beafd409313edisonn@google.com#include "SkTArray.h"
180bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary#include "SkTSort.h"
190d154eeaebc640b7bd83e0b212fac22587610a4bhalcanary#include "ProcStats.h"
20c319abeeef205627dafd52d977157beafd409313edisonn@google.com
217def5e1630d47cdbfa4b58a9c86bc060693c4d79scroggo@google.com__SK_FORCE_IMAGE_DECODER_LINKING;
227def5e1630d47cdbfa4b58a9c86bc060693c4d79scroggo@google.com
23184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#ifdef SK_USE_CDB
24184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#include "win_dbghelp.h"
25184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#endif
26184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com
27c319abeeef205627dafd52d977157beafd409313edisonn@google.com/**
28c319abeeef205627dafd52d977157beafd409313edisonn@google.com * render_pdfs
29c319abeeef205627dafd52d977157beafd409313edisonn@google.com *
30c319abeeef205627dafd52d977157beafd409313edisonn@google.com * Given list of directories and files to use as input, expects to find .skp
31c319abeeef205627dafd52d977157beafd409313edisonn@google.com * files and it will convert them to .pdf files writing them in the output
32c319abeeef205627dafd52d977157beafd409313edisonn@google.com * directory.
33c319abeeef205627dafd52d977157beafd409313edisonn@google.com *
34c319abeeef205627dafd52d977157beafd409313edisonn@google.com * Returns zero exit code if all .skp files were converted successfully,
35c319abeeef205627dafd52d977157beafd409313edisonn@google.com * otherwise returns error code 1.
36c319abeeef205627dafd52d977157beafd409313edisonn@google.com */
37c319abeeef205627dafd52d977157beafd409313edisonn@google.com
38c319abeeef205627dafd52d977157beafd409313edisonn@google.comstatic const char PDF_FILE_EXTENSION[] = "pdf";
39c319abeeef205627dafd52d977157beafd409313edisonn@google.comstatic const char SKP_FILE_EXTENSION[] = "skp";
40c319abeeef205627dafd52d977157beafd409313edisonn@google.com
410bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary
420bef17a678d3d1d551f77f73c716c996ae05c5cahalcanaryDEFINE_string2(inputPaths, r, "",
430bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary              "A list of directories and files to use as input. "
440bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary              "Files are expected to have the .skp extension.");
450bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary
460bef17a678d3d1d551f77f73c716c996ae05c5cahalcanaryDEFINE_string2(outputDir, w, "",
470bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary               "Directory to write the rendered pdfs.");
480bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary
490bef17a678d3d1d551f77f73c716c996ae05c5cahalcanaryDEFINE_string2(match, m, "",
500bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary               "[~][^]substring[$] [...] of filenames to run.\n"
510bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary               "Multiple matches may be separated by spaces.\n"
520bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary               "~ causes a matching file to always be skipped\n"
530bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary               "^ requires the start of the file to match\n"
540bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary               "$ requires the end of the file to match\n"
550bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary               "^ and $ requires an exact match\n"
560bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary               "If a file does not match any list entry,\n"
570bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary               "it is skipped unless some list entry starts with ~");
580bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary
59c319abeeef205627dafd52d977157beafd409313edisonn@google.com/** Replaces the extension of a file.
60c319abeeef205627dafd52d977157beafd409313edisonn@google.com * @param path File name whose extension will be changed.
61c319abeeef205627dafd52d977157beafd409313edisonn@google.com * @param old_extension The old extension.
62c319abeeef205627dafd52d977157beafd409313edisonn@google.com * @param new_extension The new extension.
63c319abeeef205627dafd52d977157beafd409313edisonn@google.com * @returns false if the file did not has the expected extension.
64c319abeeef205627dafd52d977157beafd409313edisonn@google.com *  if false is returned, contents of path are undefined.
65c319abeeef205627dafd52d977157beafd409313edisonn@google.com */
66c319abeeef205627dafd52d977157beafd409313edisonn@google.comstatic bool replace_filename_extension(SkString* path,
67c319abeeef205627dafd52d977157beafd409313edisonn@google.com                                       const char old_extension[],
68c319abeeef205627dafd52d977157beafd409313edisonn@google.com                                       const char new_extension[]) {
69c319abeeef205627dafd52d977157beafd409313edisonn@google.com    if (path->endsWith(old_extension)) {
70c319abeeef205627dafd52d977157beafd409313edisonn@google.com        path->remove(path->size() - strlen(old_extension),
71c319abeeef205627dafd52d977157beafd409313edisonn@google.com                     strlen(old_extension));
72c319abeeef205627dafd52d977157beafd409313edisonn@google.com        if (!path->endsWith(".")) {
73c319abeeef205627dafd52d977157beafd409313edisonn@google.com            return false;
74c319abeeef205627dafd52d977157beafd409313edisonn@google.com        }
75c319abeeef205627dafd52d977157beafd409313edisonn@google.com        path->append(new_extension);
76c319abeeef205627dafd52d977157beafd409313edisonn@google.com        return true;
77c319abeeef205627dafd52d977157beafd409313edisonn@google.com    }
78c319abeeef205627dafd52d977157beafd409313edisonn@google.com    return false;
79c319abeeef205627dafd52d977157beafd409313edisonn@google.com}
80c319abeeef205627dafd52d977157beafd409313edisonn@google.com
81760f2d95dd22efce0066b663421aa604812c447fskia.committer@gmail.com/** Builds the output filename. path = dir/name, and it replaces expected
82c319abeeef205627dafd52d977157beafd409313edisonn@google.com * .skp extension with .pdf extention.
83c319abeeef205627dafd52d977157beafd409313edisonn@google.com * @param path Output filename.
84c319abeeef205627dafd52d977157beafd409313edisonn@google.com * @param name The name of the file.
85c319abeeef205627dafd52d977157beafd409313edisonn@google.com * @returns false if the file did not has the expected extension.
86c319abeeef205627dafd52d977157beafd409313edisonn@google.com *  if false is returned, contents of path are undefined.
87c319abeeef205627dafd52d977157beafd409313edisonn@google.com */
88c319abeeef205627dafd52d977157beafd409313edisonn@google.comstatic bool make_output_filepath(SkString* path, const SkString& dir,
89c319abeeef205627dafd52d977157beafd409313edisonn@google.com                                 const SkString& name) {
90a8e2e1504b9af6ba791637f228debaa23953064atfarina    *path = SkOSPath::Join(dir.c_str(), name.c_str());
91c319abeeef205627dafd52d977157beafd409313edisonn@google.com    return replace_filename_extension(path,
92c319abeeef205627dafd52d977157beafd409313edisonn@google.com                                      SKP_FILE_EXTENSION,
93c319abeeef205627dafd52d977157beafd409313edisonn@google.com                                      PDF_FILE_EXTENSION);
94c319abeeef205627dafd52d977157beafd409313edisonn@google.com}
95c319abeeef205627dafd52d977157beafd409313edisonn@google.com
968b2cb3391d75f0e7b522ab3180da833370f413bdhalcanarynamespace {
978b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary// This is a write-only stream.
988b2cb3391d75f0e7b522ab3180da833370f413bdhalcanaryclass NullWStream : public SkWStream {
998b2cb3391d75f0e7b522ab3180da833370f413bdhalcanarypublic:
1008b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary    NullWStream() : fBytesWritten(0) { }
10136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool write(const void*, size_t size) override {
1028b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary        fBytesWritten += size;
1038b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary        return true;
1048b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary    }
10536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    size_t bytesWritten() const override { return fBytesWritten; }
1068b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary    size_t fBytesWritten;
1078b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary};
1088b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary}  // namespace
1098b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary
110c319abeeef205627dafd52d977157beafd409313edisonn@google.com/** Write the output of pdf renderer to a file.
111c319abeeef205627dafd52d977157beafd409313edisonn@google.com * @param outputDir Output dir.
112c319abeeef205627dafd52d977157beafd409313edisonn@google.com * @param inputFilename The skp file that was read.
113c319abeeef205627dafd52d977157beafd409313edisonn@google.com * @param renderer The object responsible to write the pdf file.
114c319abeeef205627dafd52d977157beafd409313edisonn@google.com */
1155e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.orgstatic SkWStream* open_stream(const SkString& outputDir,
1165e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org                              const SkString& inputFilename) {
1174fa566b34ac19d1b8bbddd75d284c9db6eefab5bedisonn@google.com    if (outputDir.isEmpty()) {
1188b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary        return SkNEW(NullWStream);
1194fa566b34ac19d1b8bbddd75d284c9db6eefab5bedisonn@google.com    }
1204fa566b34ac19d1b8bbddd75d284c9db6eefab5bedisonn@google.com
121c319abeeef205627dafd52d977157beafd409313edisonn@google.com    SkString outputPath;
122c319abeeef205627dafd52d977157beafd409313edisonn@google.com    if (!make_output_filepath(&outputPath, outputDir, inputFilename)) {
1235e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org        return NULL;
124c319abeeef205627dafd52d977157beafd409313edisonn@google.com    }
1254fa566b34ac19d1b8bbddd75d284c9db6eefab5bedisonn@google.com
1268b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary    SkAutoTDelete<SkFILEWStream> stream(
1278b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary            SkNEW_ARGS(SkFILEWStream, (outputPath.c_str())));
1288b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary    if (!stream.get() ||  !stream->isValid()) {
129c319abeeef205627dafd52d977157beafd409313edisonn@google.com        SkDebugf("Could not write to file %s\n", outputPath.c_str());
1305e00989a283111cef05bed8102e45c16651e43e4commit-bot@chromium.org        return NULL;
131c319abeeef205627dafd52d977157beafd409313edisonn@google.com    }
1324fa566b34ac19d1b8bbddd75d284c9db6eefab5bedisonn@google.com
1338b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary    return stream.detach();
134c319abeeef205627dafd52d977157beafd409313edisonn@google.com}
135c319abeeef205627dafd52d977157beafd409313edisonn@google.com
1368b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary/**
1378b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary *  Given a SkPicture, write a one-page PDF document to the given
1388b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary *  output, using the provided encoder.
139c319abeeef205627dafd52d977157beafd409313edisonn@google.com */
1408b2cb3391d75f0e7b522ab3180da833370f413bdhalcanarystatic bool pdf_to_stream(SkPicture* picture,
1418c92dc1dc281649f9e6b0ff534c25bc89dded3eahalcanary                          SkWStream* output) {
1428b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary    SkAutoTUnref<SkDocument> pdfDocument(
1438c92dc1dc281649f9e6b0ff534c25bc89dded3eahalcanary            SkDocument::CreatePDF(output));
144a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips    SkCanvas* canvas = pdfDocument->beginPage(picture->cullRect().width(),
145a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips                                              picture->cullRect().height());
1468b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary    canvas->drawPicture(picture);
1478b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary    canvas->flush();
1488b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary    return pdfDocument->close();
149c319abeeef205627dafd52d977157beafd409313edisonn@google.com}
150c319abeeef205627dafd52d977157beafd409313edisonn@google.com
1510bef17a678d3d1d551f77f73c716c996ae05c5cahalcanarystatic bool operator<(const SkString& a, const SkString& b) {
1520bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary    return strcmp(a.c_str(), b.c_str()) < 0;
1530bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary}
1540bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary
1558b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary/**
1568b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary * @param A list of directories or a skp files.
1578b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary * @returns an alphabetical list of skp files.
158c319abeeef205627dafd52d977157beafd409313edisonn@google.com */
1598b2cb3391d75f0e7b522ab3180da833370f413bdhalcanarystatic void process_input_files(
1600bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary        const SkCommandLineFlags::StringArray& inputs,
1618b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary        SkTArray<SkString>* files) {
1620bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary    for (int i = 0; i < inputs.count(); i ++) {
1630bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary        const char* input = inputs[i];
1640bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary        if (sk_isdir(input)) {
1650bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary            SkOSFile::Iter iter(input, SKP_FILE_EXTENSION);
1660bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary            SkString inputFilename;
1670bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary            while (iter.next(&inputFilename)) {
1680bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary                if (!SkCommandLineFlags::ShouldSkip(
1690bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary                            FLAGS_match, inputFilename.c_str())) {
1708b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary                    files->push_back(
1710bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary                            SkOSPath::Join(input, inputFilename.c_str()));
1720bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary                }
1730bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary            }
1740bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary        } else {
1750bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary            if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, input)) {
1768b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary                files->push_back(SkString(input));
177c319abeeef205627dafd52d977157beafd409313edisonn@google.com            }
178c319abeeef205627dafd52d977157beafd409313edisonn@google.com        }
1790bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary    }
1808b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary    if (files->count() > 0) {
1818b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary        SkTQSort<SkString>(files->begin(), files->end() - 1);
182c319abeeef205627dafd52d977157beafd409313edisonn@google.com    }
183c319abeeef205627dafd52d977157beafd409313edisonn@google.com}
184c319abeeef205627dafd52d977157beafd409313edisonn@google.com
1858b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary/** For each input skp file, read it, render it to pdf and write. the
1868b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary *  output to a pdf file
1878b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary */
188184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.comint tool_main_core(int argc, char** argv);
189184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.comint tool_main_core(int argc, char** argv) {
1900bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary    SkCommandLineFlags::Parse(argc, argv);
1910bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary
192c319abeeef205627dafd52d977157beafd409313edisonn@google.com    SkAutoGraphics ag;
193c319abeeef205627dafd52d977157beafd409313edisonn@google.com
1944fa566b34ac19d1b8bbddd75d284c9db6eefab5bedisonn@google.com    SkString outputDir;
1950bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary    if (FLAGS_outputDir.count() > 0) {
1960bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary        outputDir = FLAGS_outputDir[0];
1978b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary        if (!sk_mkdir(outputDir.c_str())) {
1988b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary            SkDebugf("Unable to mkdir '%s'\n", outputDir.c_str());
1998b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary            return 1;
2008b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary        }
201c319abeeef205627dafd52d977157beafd409313edisonn@google.com    }
202c319abeeef205627dafd52d977157beafd409313edisonn@google.com
2038b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary    SkTArray<SkString> files;
2048b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary    process_input_files(FLAGS_inputPaths, &files);
2050bef17a678d3d1d551f77f73c716c996ae05c5cahalcanary
2068b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary    size_t maximumPathLength = 0;
2078b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary    for (int i = 0; i < files.count(); i ++) {
2088b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary        SkString basename = SkOSPath::Basename(files[i].c_str());
2098b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary        maximumPathLength = SkTMax(maximumPathLength, basename.size());
2100d154eeaebc640b7bd83e0b212fac22587610a4bhalcanary    }
2110d154eeaebc640b7bd83e0b212fac22587610a4bhalcanary
2128b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary    int failures = 0;
2138b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary    for (int i = 0; i < files.count(); i ++) {
2148b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary        SkString basename = SkOSPath::Basename(files[i].c_str());
2158b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary
2168b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary        SkFILEStream inputStream;
2178b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary        inputStream.setPath(files[i].c_str());
2188b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary        if (!inputStream.isValid()) {
2198b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary            SkDebugf("Could not open file %s\n", files[i].c_str());
2208b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary            ++failures;
2218b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary            continue;
2228b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary        }
2238b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary
2248b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary        SkAutoTUnref<SkPicture> picture(
2258b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary                SkPicture::CreateFromStream(&inputStream));
2268b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary        if (NULL == picture.get()) {
2278b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary            SkDebugf("Could not read an SkPicture from %s\n",
2288b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary                     files[i].c_str());
2298b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary            ++failures;
2308b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary            continue;
2318b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary        }
2325bb9700b7ef952f2664e059afb4f9f137f7d5a7dhalcanary        SkDebugf("[%6g %6g %6g %6g] %-*s",
233a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips            picture->cullRect().fLeft, picture->cullRect().fTop,
234a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips            picture->cullRect().fRight, picture->cullRect().fBottom,
235a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips            maximumPathLength, basename.c_str());
2368b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary
2378b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary        SkAutoTDelete<SkWStream> stream(open_stream(outputDir, files[i]));
2388b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary        if (!stream.get()) {
2398b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary            ++failures;
2408b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary            continue;
2418b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary        }
2428c92dc1dc281649f9e6b0ff534c25bc89dded3eahalcanary        if (!pdf_to_stream(picture, stream.get())) {
2438b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary            SkDebugf("Error in PDF Serialization.");
2448b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary            ++failures;
2458b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary        }
2468b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary
247afb4379dbca4d4d3824ace183a7348d24bc1589fmtklein        int max_rss_mb = sk_tools::getMaxResidentSetSizeMB();
248afb4379dbca4d4d3824ace183a7348d24bc1589fmtklein        if (max_rss_mb >= 0) {
249afb4379dbca4d4d3824ace183a7348d24bc1589fmtklein            SkDebugf(" %4dM peak rss", max_rss_mb);
2508b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary        }
2518b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary
2528b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary        SkDebugf("\n");
2538b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary    }
254c319abeeef205627dafd52d977157beafd409313edisonn@google.com    if (failures != 0) {
2558b2cb3391d75f0e7b522ab3180da833370f413bdhalcanary        SkDebugf("Failed to render %i of %i PDFs.\n", failures, files.count());
256c319abeeef205627dafd52d977157beafd409313edisonn@google.com        return 1;
257c319abeeef205627dafd52d977157beafd409313edisonn@google.com    }
258184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com
259184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com    return 0;
260184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com}
261184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com
262184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.comint tool_main(int argc, char** argv);
263184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.comint tool_main(int argc, char** argv) {
264184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#ifdef SK_USE_CDB
265184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com    setUpDebuggingFromArgs(argv[0]);
266184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com    __try {
267184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#endif
268184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com      return tool_main_core(argc, argv);
269184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#ifdef SK_USE_CDB
270184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com    }
271184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com    __except(GenerateDumpAndPrintCallstack(GetExceptionInformation()))
272184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com    {
273184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com        return -1;
274184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com    }
275184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#endif
276f286329ad13b43a8e398df3e0c376403882f1690humper@google.com    return 0;
277c319abeeef205627dafd52d977157beafd409313edisonn@google.com}
2789cf5b28648fa9d14bc407dda52477f3292d31d0dedisonn@google.com#if !defined SK_BUILD_FOR_IOS
2799cf5b28648fa9d14bc407dda52477f3292d31d0dedisonn@google.comint main(int argc, char * const argv[]) {
2809cf5b28648fa9d14bc407dda52477f3292d31d0dedisonn@google.com    return tool_main(argc, (char**) argv);
2819cf5b28648fa9d14bc407dda52477f3292d31d0dedisonn@google.com}
2829cf5b28648fa9d14bc407dda52477f3292d31d0dedisonn@google.com#endif
283