Home | History | Annotate | Download | only in tools
      1 /*
      2  * Copyright 2014 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 #include "SkCanvas.h"
      8 #include "SkDocument.h"
      9 #include "SkForceLinking.h"
     10 #include "SkGraphics.h"
     11 #include "SkNullCanvas.h"
     12 #include "SkPicture.h"
     13 #include "SkStream.h"
     14 #include "SkTemplates.h"
     15 #include "PageCachingDocument.h"
     16 #include "ProcStats.h"
     17 #include "flags/SkCommandLineFlags.h"
     18 
     19 DEFINE_string2(readPath,
     20                r,
     21                "",
     22                "(Required)  The path to a .skp Skia Picture file.");
     23 DEFINE_string2(writePath, w, "", "If set, write PDF output to this file.");
     24 DEFINE_bool(cachePages, false, "Use a PageCachingDocument.");
     25 DEFINE_bool(nullCanvas, true, "Render to a SkNullCanvas as a control.");
     26 
     27 __SK_FORCE_IMAGE_DECODER_LINKING;
     28 
     29 namespace {
     30 class NullWStream : public SkWStream {
     31 public:
     32     NullWStream() : fBytesWritten(0) {
     33     }
     34     bool write(const void*, size_t size) override {
     35         fBytesWritten += size;
     36         return true;
     37     }
     38     size_t bytesWritten() const override {
     39         return fBytesWritten;
     40     }
     41     size_t fBytesWritten;
     42 };
     43 
     44 SkDocument* CreatePDFDocument(SkWStream* out) {
     45     if (FLAGS_cachePages) {
     46         return CreatePageCachingDocument(out);
     47     } else {
     48         return SkDocument::CreatePDF(out);
     49     }
     50 }
     51 }  // namespace
     52 
     53 int main(int argc, char** argv) {
     54     SkCommandLineFlags::Parse(argc, argv);
     55     if (FLAGS_readPath.isEmpty()) {
     56         SkDebugf("Error: missing requires --readPath option\n");
     57         return 1;
     58     }
     59     const char* path = FLAGS_readPath[0];
     60     SkFILEStream inputStream(path);
     61 
     62     if (!inputStream.isValid()) {
     63         SkDebugf("Could not open file %s\n", path);
     64         return 2;
     65     }
     66     SkAutoGraphics ag;
     67     SkAutoTUnref<SkPicture> picture(SkPicture::CreateFromStream(&inputStream));
     68     if (NULL == picture.get()) {
     69         SkDebugf("Could not read an SkPicture from %s\n", path);
     70         return 3;
     71     }
     72 
     73     int width = picture->cullRect().width();
     74     int height = picture->cullRect().height();
     75 
     76     const int kLetterWidth = 612;   // 8.5 * 72
     77     const int kLetterHeight = 792;  // 11 * 72
     78     SkRect letterRect = SkRect::MakeWH(SkIntToScalar(kLetterWidth),
     79                                        SkIntToScalar(kLetterHeight));
     80 
     81     int xPages = ((width - 1) / kLetterWidth) + 1;
     82     int yPages = ((height - 1) / kLetterHeight) + 1;
     83 
     84     SkAutoTDelete<SkWStream> out(SkNEW(NullWStream));
     85 
     86     if (!FLAGS_writePath.isEmpty()) {
     87         SkAutoTDelete<SkFILEWStream> fileStream(
     88             SkNEW_ARGS(SkFILEWStream, (FLAGS_writePath[0])));
     89         if (!fileStream->isValid()) {
     90             SkDebugf("Can't open file \"%s\" for writing.", FLAGS_writePath[0]);
     91             return 1;
     92         }
     93         out.reset(fileStream.detach());
     94     }
     95 
     96     SkCanvas* nullCanvas = SkCreateNullCanvas();
     97 
     98     SkAutoTUnref<SkDocument> pdfDocument;
     99     if (!FLAGS_nullCanvas) {
    100         pdfDocument.reset(CreatePDFDocument(out.get()));
    101     }
    102 
    103     for (int y = 0; y < yPages; ++y) {
    104         for (int x = 0; x < xPages; ++x) {
    105             SkCanvas* canvas;
    106             if (FLAGS_nullCanvas) {
    107                 canvas = nullCanvas;
    108             } else {
    109                 int w = SkTMin(kLetterWidth, width - (x * kLetterWidth));
    110                 int h = SkTMin(kLetterHeight, height - (y * kLetterHeight));
    111                 canvas = pdfDocument->beginPage(w, h);
    112             }
    113             {
    114                 SkAutoCanvasRestore autoCanvasRestore(canvas, true);
    115                 canvas->clipRect(letterRect);
    116                 canvas->translate(SkIntToScalar(-kLetterWidth * x),
    117                                   SkIntToScalar(-kLetterHeight * y));
    118                 picture->playback(canvas);
    119                 //canvas->drawPicture(picture);
    120             }
    121             canvas->flush();
    122             if (!FLAGS_nullCanvas) {
    123                 pdfDocument->endPage();
    124             }
    125         }
    126     }
    127     if (!FLAGS_nullCanvas) {
    128         pdfDocument->close();
    129         pdfDocument.reset(NULL);
    130     }
    131     printf(SK_SIZE_T_SPECIFIER "\t%4d\n",
    132            inputStream.getLength(),
    133            sk_tools::getMaxResidentSetSizeMB());
    134     return 0;
    135 }
    136