Line data Source code
1 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #include "PrintTargetSkPDF.h"
7 :
8 : #include "mozilla/gfx/2D.h"
9 : #include "nsString.h"
10 : #include <vector>
11 :
12 : namespace mozilla {
13 : namespace gfx {
14 :
15 0 : PrintTargetSkPDF::PrintTargetSkPDF(const IntSize& aSize,
16 0 : UniquePtr<SkWStream> aStream)
17 : : PrintTarget(/* not using cairo_surface_t */ nullptr, aSize)
18 0 : , mOStream(Move(aStream))
19 0 : , mPageCanvas(nullptr)
20 : {
21 0 : }
22 :
23 0 : PrintTargetSkPDF::~PrintTargetSkPDF()
24 : {
25 0 : Finish(); // ensure stream is flushed
26 :
27 : // Make sure mPDFDoc and mRefPDFDoc are destroyed before our member streams
28 : // (which they wrap) are destroyed:
29 0 : mPDFDoc = nullptr;
30 0 : mRefPDFDoc = nullptr;
31 0 : }
32 :
33 : /* static */ already_AddRefed<PrintTargetSkPDF>
34 0 : PrintTargetSkPDF::CreateOrNull(UniquePtr<SkWStream> aStream,
35 : const IntSize& aSizeInPoints)
36 : {
37 0 : return do_AddRef(new PrintTargetSkPDF(aSizeInPoints, Move(aStream)));
38 : }
39 :
40 : nsresult
41 0 : PrintTargetSkPDF::BeginPrinting(const nsAString& aTitle,
42 : const nsAString& aPrintToFileName,
43 : int32_t aStartPage,
44 : int32_t aEndPage)
45 : {
46 : // We need to create the SkPDFDocument here rather than in CreateOrNull
47 : // because it's only now that we are given aTitle which we want for the
48 : // PDF metadata.
49 :
50 0 : SkDocument::PDFMetadata metadata;
51 0 : metadata.fTitle = NS_ConvertUTF16toUTF8(aTitle).get();
52 0 : metadata.fCreator = "Firefox";
53 : SkTime::DateTime now;
54 0 : SkTime::GetDateTime(&now);
55 0 : metadata.fCreation.fEnabled = true;
56 0 : metadata.fCreation.fDateTime = now;
57 0 : metadata.fModified.fEnabled = true;
58 0 : metadata.fModified.fDateTime = now;
59 :
60 : // SkDocument stores a non-owning raw pointer to aStream
61 0 : mPDFDoc = SkDocument::MakePDF(mOStream.get(), SK_ScalarDefaultRasterDPI,
62 0 : metadata, /*jpegEncoder*/ nullptr, true);
63 :
64 0 : return mPDFDoc ? NS_OK : NS_ERROR_FAILURE;
65 : }
66 :
67 : nsresult
68 0 : PrintTargetSkPDF::BeginPage()
69 : {
70 0 : mPageCanvas = mPDFDoc->beginPage(mSize.width, mSize.height);
71 :
72 0 : return !mPageCanvas ? NS_ERROR_FAILURE : PrintTarget::BeginPage();
73 : }
74 :
75 : nsresult
76 0 : PrintTargetSkPDF::EndPage()
77 : {
78 0 : mPageCanvas = nullptr;
79 0 : mPageDT = nullptr;
80 0 : return PrintTarget::EndPage();
81 : }
82 :
83 : nsresult
84 0 : PrintTargetSkPDF::EndPrinting()
85 : {
86 0 : mPDFDoc->close();
87 0 : if (mRefPDFDoc) {
88 0 : mRefPDFDoc->close();
89 : }
90 0 : mPageCanvas = nullptr;
91 0 : mPageDT = nullptr;
92 0 : return NS_OK;
93 : }
94 :
95 : void
96 0 : PrintTargetSkPDF::Finish()
97 : {
98 0 : if (mIsFinished) {
99 0 : return;
100 : }
101 0 : mOStream->flush();
102 0 : PrintTarget::Finish();
103 : }
104 :
105 : already_AddRefed<DrawTarget>
106 0 : PrintTargetSkPDF::MakeDrawTarget(const IntSize& aSize,
107 : DrawEventRecorder* aRecorder)
108 : {
109 0 : if (aRecorder) {
110 0 : return PrintTarget::MakeDrawTarget(aSize, aRecorder);
111 : }
112 : //MOZ_ASSERT(aSize == mSize, "Should mPageCanvas size match?");
113 0 : if (!mPageCanvas) {
114 0 : return nullptr;
115 : }
116 0 : mPageDT = Factory::CreateDrawTargetWithSkCanvas(mPageCanvas);
117 0 : if (!mPageDT) {
118 0 : mPageCanvas = nullptr;
119 0 : return nullptr;
120 : }
121 0 : return do_AddRef(mPageDT);
122 : }
123 :
124 : already_AddRefed<DrawTarget>
125 0 : PrintTargetSkPDF::GetReferenceDrawTarget(DrawEventRecorder* aRecorder)
126 : {
127 0 : if (!mRefDT) {
128 0 : SkDocument::PDFMetadata metadata;
129 : // SkDocument stores a non-owning raw pointer to aStream
130 0 : mRefPDFDoc = SkDocument::MakePDF(&mRefOStream,
131 : SK_ScalarDefaultRasterDPI,
132 0 : metadata, nullptr, true);
133 0 : if (!mRefPDFDoc) {
134 0 : return nullptr;
135 : }
136 0 : mRefCanvas = mRefPDFDoc->beginPage(mSize.width, mSize.height);
137 0 : if (!mRefCanvas) {
138 0 : return nullptr;
139 : }
140 : RefPtr<DrawTarget> dt =
141 0 : Factory::CreateDrawTargetWithSkCanvas(mRefCanvas);
142 0 : if (!dt) {
143 0 : return nullptr;
144 : }
145 0 : mRefDT = dt.forget();
146 : }
147 :
148 0 : if (aRecorder) {
149 0 : if (!mRecordingRefDT) {
150 0 : RefPtr<DrawTarget> dt = CreateWrapAndRecordDrawTarget(aRecorder, mRefDT);
151 0 : if (!dt || !dt->IsValid()) {
152 0 : return nullptr;
153 : }
154 0 : mRecordingRefDT = dt.forget();
155 : #ifdef DEBUG
156 0 : mRecorder = aRecorder;
157 : #endif
158 : }
159 : #ifdef DEBUG
160 : else {
161 0 : MOZ_ASSERT(aRecorder == mRecorder,
162 : "Caching mRecordingRefDT assumes the aRecorder is an invariant");
163 : }
164 : #endif
165 :
166 0 : return do_AddRef(mRecordingRefDT);
167 : }
168 :
169 0 : return do_AddRef(mRefDT);
170 : }
171 :
172 : } // namespace gfx
173 : } // namespace mozilla
|