1 /* 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 */ 7 #ifndef SkPDFDocumentPriv_DEFINED 8 #define SkPDFDocumentPriv_DEFINED 9 10 #include "SkCanvas.h" 11 #include "SkMutex.h" 12 #include "SkPDFDocument.h" 13 #include "SkPDFMetadata.h" 14 #include "SkPDFTag.h" 15 #include "SkStream.h" 16 #include "SkTHash.h" 17 18 #include <atomic> 19 #include <vector> 20 #include <memory> 21 22 class SkExecutor; 23 class SkPDFDevice; 24 class SkPDFFont; 25 struct SkAdvancedTypefaceMetrics; 26 struct SkBitmapKey; 27 struct SkPDFFillGraphicState; 28 struct SkPDFImageShaderKey; 29 struct SkPDFStrokeGraphicState; 30 31 namespace SkPDFGradientShader { 32 struct Key; 33 struct KeyHash; 34 } 35 36 const char* SkPDFGetNodeIdKey(); 37 38 // Logically part of SkPDFDocument, but separate to keep similar functionality together. 39 class SkPDFOffsetMap { 40 public: 41 void markStartOfDocument(const SkWStream*); 42 void markStartOfObject(int referenceNumber, const SkWStream*); 43 int objectCount() const; 44 int emitCrossReferenceTable(SkWStream* s) const; 45 private: 46 std::vector<int> fOffsets; 47 size_t fBaseOffset = SIZE_MAX; 48 }; 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. */ 53 class SkPDFDocument : public SkDocument { 54 public: 55 SkPDFDocument(SkWStream*, SkPDF::Metadata); 56 ~SkPDFDocument() override; 57 SkCanvas* onBeginPage(SkScalar, SkScalar) override; 58 void onEndPage() override; 59 void onClose(SkWStream*) override; 60 void onAbort() override; 61 62 /** 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. 70 */ 71 SkPDFIndirectReference emit(const SkPDFObject&, SkPDFIndirectReference); emit(const SkPDFObject & o)72 SkPDFIndirectReference emit(const SkPDFObject& o) { return this->emit(o, this->reserveRef()); } 73 74 template <typename T> emitStream(const SkPDFDict & dict,T writeStream,SkPDFIndirectReference ref)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 metadata()84 const SkPDF::Metadata& metadata() const { return fMetadata; } 85 86 SkPDFIndirectReference getPage(size_t pageIndex) const; 87 // Returns -1 if no mark ID. 88 int getMarkIdForNodeId(int nodeId); 89 reserveRef()90 SkPDFIndirectReference reserveRef() { return SkPDFIndirectReference{fNextObjectNumber++}; } 91 executor()92 SkExecutor* executor() const { return fExecutor; } 93 void incrementJobCount(); 94 void signalJobComplete(); currentPageIndex()95 size_t currentPageIndex() { return fPages.size(); } pageCount()96 size_t pageCount() { return fPageRefs.size(); } 97 98 // 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 114 private: 115 SkPDFOffsetMap fOffsetMap; 116 SkCanvas fCanvas; 117 std::vector<std::unique_ptr<SkPDFDict>> fPages; 118 std::vector<SkPDFIndirectReference> fPageRefs; 119 SkPDFDict fDests; 120 sk_sp<SkPDFDevice> fPageDevice; 121 std::atomic<int> fNextObjectNumber = {1}; 122 std::atomic<int> fJobCount = {0}; 123 SkUUID fUUID; 124 SkPDFIndirectReference fInfoDict; 125 SkPDFIndirectReference fXMP; 126 SkPDF::Metadata fMetadata; 127 SkScalar fRasterScale = 1; 128 SkScalar fInverseRasterScale = 1; 129 SkExecutor* fExecutor = nullptr; 130 131 // For tagged PDFs. 132 SkPDFTagTree fTagTree; 133 134 SkMutex fMutex; 135 SkSemaphore fSemaphore; 136 137 void waitForJobs(); 138 SkWStream* beginObject(SkPDFIndirectReference); 139 void endObject(); 140 }; 141 142 #endif // SkPDFDocumentPriv_DEFINED 143