blob: e50e9ecb70fcaa194e7e20668b29bbe1615a5855 [file] [log] [blame]
mtklein30bf3e22014-06-03 13:57:14 -07001/*
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
8#include "DMPDFTask.h"
9#include "DMExpectationsTask.h"
10#include "DMPDFRasterizeTask.h"
11#include "DMUtil.h"
12#include "DMWriteTask.h"
13#include "SkCommandLineFlags.h"
14#include "SkDocument.h"
15
mtkleine696a592014-06-03 15:59:23 -070016// The PDF backend is not threadsafe. If you run dm with --pdf repeatedly, you
17// will quickly find yourself crashed. (while catchsegv out/Release/dm;; end).
18//
19// TODO(mtklein): re-enable by default, maybe moving to its own single thread.
20DEFINE_bool(pdf, false, "PDF backend master switch.");
mtklein30bf3e22014-06-03 13:57:14 -070021
22namespace DM {
23
24PDFTask::PDFTask(const char* suffix,
25 Reporter* reporter,
26 TaskRunner* taskRunner,
27 const Expectations& expectations,
28 skiagm::GMRegistry::Factory factory,
29 RasterizePdfProc rasterizePdfProc)
30 : CpuTask(reporter, taskRunner)
31 , fGM(factory(NULL))
32 , fName(UnderJoin(fGM->getName(), suffix))
33 , fExpectations(expectations)
34 , fRasterize(rasterizePdfProc) {}
35
36namespace {
37
38class SinglePagePDF {
39public:
40 SinglePagePDF(SkScalar width, SkScalar height)
41 : fDocument(SkDocument::CreatePDF(&fWriteStream))
42 , fCanvas(fDocument->beginPage(width, height)) {}
43
44 SkCanvas* canvas() { return fCanvas; }
45
46 SkData* end() {
47 fCanvas->flush();
48 fDocument->endPage();
49 fDocument->close();
50 return fWriteStream.copyToData();
51 }
52
53private:
54 SkDynamicMemoryWStream fWriteStream;
55 SkAutoTUnref<SkDocument> fDocument;
56 SkCanvas* fCanvas;
57};
58
59} // namespace
60
61void PDFTask::draw() {
62 SinglePagePDF pdf(fGM->width(), fGM->height());
63 //TODO(mtklein): GM doesn't do this. Why not?
64 //pdf.canvas()->concat(fGM->getInitialTransform());
65 fGM->draw(pdf.canvas());
66
67 SkAutoTUnref<SkData> pdfData(pdf.end());
68 SkASSERT(pdfData.get());
69
70 if (!(fGM->getFlags() & skiagm::GM::kSkipPDFRasterization_Flag)) {
71 this->spawnChild(SkNEW_ARGS(PDFRasterizeTask,
72 (*this, pdfData.get(), fExpectations, fRasterize)));
73 }
74 this->spawnChild(SkNEW_ARGS(WriteTask, (*this, pdfData.get(), ".pdf")));
75}
76
77bool PDFTask::shouldSkip() const {
78 if (!FLAGS_pdf) {
79 return true;
80 }
81 if (fGM->getFlags() & skiagm::GM::kSkipPDF_Flag) {
82 return true;
83 }
84 return false;
85}
86
87} // namespace DM