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 19DEFINE_string2(readPath, 20 r, 21 "", 22 "(Required) The path to a .skp Skia Picture file."); 23DEFINE_string2(writePath, w, "", "If set, write PDF output to this file."); 24DEFINE_bool(cachePages, false, "Use a PageCachingDocument."); 25DEFINE_bool(nullCanvas, true, "Render to a SkNullCanvas as a control."); 26 27__SK_FORCE_IMAGE_DECODER_LINKING; 28 29namespace { 30class NullWStream : public SkWStream { 31public: 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 44SkDocument* CreatePDFDocument(SkWStream* out) { 45 if (FLAGS_cachePages) { 46 return CreatePageCachingDocument(out); 47 } else { 48 return SkDocument::CreatePDF(out); 49 } 50} 51} // namespace 52 53int 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