blob: 68a8781e756ef5b5d0d675e13a74277c8ece1311 [file] [log] [blame]
halcanary23f4d4d2016-03-12 05:59:39 -08001/*
2 * Copyright 2016 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 */
Hal Canary23564b92018-09-07 14:33:14 -04007#ifndef SkPDFDocumentPriv_DEFINED
8#define SkPDFDocumentPriv_DEFINED
halcanary23f4d4d2016-03-12 05:59:39 -08009
Hal Canary2473d942018-09-10 13:06:42 -040010#include "SkCanvas.h"
Hal Canary4ca9fa32018-12-21 16:15:01 -050011#include "SkMutex.h"
Hal Canary9a3f5542018-12-10 19:59:07 -050012#include "SkPDFDocument.h"
Hal Canary2473d942018-09-10 13:06:42 -040013#include "SkPDFMetadata.h"
Hal Canaryf34131a2018-12-18 15:11:03 -050014#include "SkPDFTag.h"
Hal Canary2111d5f2019-01-02 09:44:41 -050015#include "SkStream.h"
Hal Canary4ca9fa32018-12-21 16:15:01 -050016#include "SkTHash.h"
Hal Canary9a3f5542018-12-10 19:59:07 -050017
18#include <atomic>
Hal Canary4ca9fa32018-12-21 16:15:01 -050019#include <vector>
20#include <memory>
halcanary23f4d4d2016-03-12 05:59:39 -080021
Hal Canary9a3f5542018-12-10 19:59:07 -050022class SkExecutor;
Hal Canary4ca9fa32018-12-21 16:15:01 -050023class SkPDFDevice;
24class SkPDFFont;
25struct SkAdvancedTypefaceMetrics;
26struct SkBitmapKey;
27struct SkPDFFillGraphicState;
28struct SkPDFImageShaderKey;
29struct SkPDFStrokeGraphicState;
30
31namespace SkPDFGradientShader {
32struct Key;
33struct KeyHash;
34}
Dominic Mazzoni656cefe2018-09-25 20:29:15 -070035
36const char* SkPDFGetNodeIdKey();
halcanary989da4a2016-03-21 14:33:17 -070037
Hal Canary4ca9fa32018-12-21 16:15:01 -050038// Logically part of SkPDFDocument, but separate to keep similar functionality together.
Hal Canary1addaff2018-12-21 11:54:37 -050039class SkPDFOffsetMap {
40public:
41 void markStartOfDocument(const SkWStream*);
42 void markStartOfObject(int referenceNumber, const SkWStream*);
43 int objectCount() const;
44 int emitCrossReferenceTable(SkWStream* s) const;
45private:
46 std::vector<int> fOffsets;
Hal Canaryf6462c42018-11-13 16:19:59 -050047 size_t fBaseOffset = SIZE_MAX;
halcanary50e82e62016-03-21 13:45:05 -070048};
49
50/** Concrete implementation of SkDocument that creates PDF files. This
51 class does not produced linearized or optimized PDFs; instead it
52 it attempts to use a minimum amount of RAM. */
53class SkPDFDocument : public SkDocument {
54public:
Hal Canary23564b92018-09-07 14:33:14 -040055 SkPDFDocument(SkWStream*, SkPDF::Metadata);
Brian Salomond3b65972017-03-22 12:05:03 -040056 ~SkPDFDocument() override;
Hal Canaryb1de5f92017-07-01 22:17:15 -040057 SkCanvas* onBeginPage(SkScalar, SkScalar) override;
halcanary50e82e62016-03-21 13:45:05 -070058 void onEndPage() override;
reedd14df7c2016-09-22 14:12:46 -070059 void onClose(SkWStream*) override;
halcanary50e82e62016-03-21 13:45:05 -070060 void onAbort() override;
halcanarye86134f2016-09-06 09:32:13 -070061
halcanary50e82e62016-03-21 13:45:05 -070062 /**
63 Serialize the object, as well as any other objects it
64 indirectly refers to. If any any other objects have been added
65 to the SkPDFObjNumMap without serializing them, they will be
66 serialized as well.
67
68 It might go without saying that objects should not be changed
69 after calling serialize, since those changes will be too late.
halcanary50e82e62016-03-21 13:45:05 -070070 */
Hal Canary9a3f5542018-12-10 19:59:07 -050071 SkPDFIndirectReference emit(const SkPDFObject&, SkPDFIndirectReference);
72 SkPDFIndirectReference emit(const SkPDFObject& o) { return this->emit(o, this->reserveRef()); }
Hal Canary2111d5f2019-01-02 09:44:41 -050073
74 template <typename T>
75 void emitStream(const SkPDFDict& dict, T writeStream, SkPDFIndirectReference ref) {
76 SkWStream* stream = this->beginObject(ref);
77 dict.emitObject(stream);
78 stream->writeText(" stream\n");
79 writeStream(stream);
80 stream->writeText("\nendstream");
81 this->endObject();
82 }
83
Hal Canary23564b92018-09-07 14:33:14 -040084 const SkPDF::Metadata& metadata() const { return fMetadata; }
halcanary50e82e62016-03-21 13:45:05 -070085
Hal Canaryfba5b6c2018-12-18 12:55:18 -050086 SkPDFIndirectReference getPage(size_t pageIndex) const;
Dominic Mazzoni656cefe2018-09-25 20:29:15 -070087 // Returns -1 if no mark ID.
88 int getMarkIdForNodeId(int nodeId);
89
Hal Canaryf34131a2018-12-18 15:11:03 -050090 SkPDFIndirectReference reserveRef() { return SkPDFIndirectReference{fNextObjectNumber++}; }
Hal Canarya1211832018-11-13 16:45:14 -050091
Hal Canary9a3f5542018-12-10 19:59:07 -050092 SkExecutor* executor() const { return fExecutor; }
Hal Canarydd9003a2018-12-21 13:44:31 -050093 void incrementJobCount();
94 void signalJobComplete();
Hal Canaryfba5b6c2018-12-18 12:55:18 -050095 size_t currentPageIndex() { return fPages.size(); }
96 size_t pageCount() { return fPageRefs.size(); }
Hal Canary9a3f5542018-12-10 19:59:07 -050097
Hal Canary4ca9fa32018-12-21 16:15:01 -050098 // Canonicalized objects
99 SkTHashMap<SkPDFImageShaderKey, SkPDFIndirectReference> fImageShaderMap;
100 SkTHashMap<SkPDFGradientShader::Key, SkPDFIndirectReference, SkPDFGradientShader::KeyHash>
101 fGradientPatternMap;
102 SkTHashMap<SkBitmapKey, SkPDFIndirectReference> fPDFBitmapMap;
103 SkTHashMap<uint32_t, std::unique_ptr<SkAdvancedTypefaceMetrics>> fTypefaceMetrics;
104 SkTHashMap<uint32_t, std::vector<SkString>> fType1GlyphNames;
105 SkTHashMap<uint32_t, std::vector<SkUnichar>> fToUnicodeMap;
106 SkTHashMap<uint32_t, SkPDFIndirectReference> fFontDescriptors;
107 SkTHashMap<uint32_t, SkPDFIndirectReference> fType3FontDescriptors;
108 SkTHashMap<uint64_t, SkPDFFont> fFontMap;
109 SkTHashMap<SkPDFStrokeGraphicState, SkPDFIndirectReference> fStrokeGSMap;
110 SkTHashMap<SkPDFFillGraphicState, SkPDFIndirectReference> fFillGSMap;
111 SkPDFIndirectReference fInvertFunction;
112 SkPDFIndirectReference fNoSmaskGraphicState;
113
halcanary50e82e62016-03-21 13:45:05 -0700114private:
Hal Canary1addaff2018-12-21 11:54:37 -0500115 SkPDFOffsetMap fOffsetMap;
Hal Canary2473d942018-09-10 13:06:42 -0400116 SkCanvas fCanvas;
Hal Canary74801582018-12-18 16:30:41 -0500117 std::vector<std::unique_ptr<SkPDFDict>> fPages;
Hal Canaryfba5b6c2018-12-18 12:55:18 -0500118 std::vector<SkPDFIndirectReference> fPageRefs;
119 SkPDFDict fDests;
halcanarycc77c122016-03-23 06:26:31 -0700120 sk_sp<SkPDFDevice> fPageDevice;
Hal Canaryf34131a2018-12-18 15:11:03 -0500121 std::atomic<int> fNextObjectNumber = {1};
Hal Canarydd9003a2018-12-21 13:44:31 -0500122 std::atomic<int> fJobCount = {0};
Hal Canary9a3f5542018-12-10 19:59:07 -0500123 SkUUID fUUID;
124 SkPDFIndirectReference fInfoDict;
125 SkPDFIndirectReference fXMP;
Hal Canary23564b92018-09-07 14:33:14 -0400126 SkPDF::Metadata fMetadata;
Hal Canary7d06ab22018-09-10 14:39:13 -0400127 SkScalar fRasterScale = 1;
128 SkScalar fInverseRasterScale = 1;
Hal Canary9a3f5542018-12-10 19:59:07 -0500129 SkExecutor* fExecutor = nullptr;
halcanary530032a2016-08-18 14:22:52 -0700130
Dominic Mazzoni656cefe2018-09-25 20:29:15 -0700131 // For tagged PDFs.
Hal Canaryf34131a2018-12-18 15:11:03 -0500132 SkPDFTagTree fTagTree;
Dominic Mazzoni656cefe2018-09-25 20:29:15 -0700133
Hal Canary9a3f5542018-12-10 19:59:07 -0500134 SkMutex fMutex;
135 SkSemaphore fSemaphore;
Hal Canarya1211832018-11-13 16:45:14 -0500136
Hal Canarydd9003a2018-12-21 13:44:31 -0500137 void waitForJobs();
Hal Canary2111d5f2019-01-02 09:44:41 -0500138 SkWStream* beginObject(SkPDFIndirectReference);
139 void endObject();
halcanary50e82e62016-03-21 13:45:05 -0700140};
141
Hal Canary23564b92018-09-07 14:33:14 -0400142#endif // SkPDFDocumentPriv_DEFINED