1 // Copyright 2016 The PDFium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #ifndef CORE_FPDFAPI_PAGE_CPDF_PAGEOBJECTHOLDER_H_ 8 #define CORE_FPDFAPI_PAGE_CPDF_PAGEOBJECTHOLDER_H_ 9 10 #include <stddef.h> 11 #include <stdint.h> 12 13 #include <deque> 14 #include <map> 15 #include <memory> 16 #include <set> 17 #include <utility> 18 #include <vector> 19 20 #include "core/fpdfapi/page/cpdf_transparency.h" 21 #include "core/fpdfapi/parser/cpdf_dictionary.h" 22 #include "core/fxcrt/bytestring.h" 23 #include "core/fxcrt/fx_coordinates.h" 24 #include "core/fxcrt/retain_ptr.h" 25 #include "core/fxcrt/unowned_ptr.h" 26 #include "core/fxge/dib/fx_dib.h" 27 #include "third_party/abseil-cpp/absl/types/optional.h" 28 29 class CPDF_ContentParser; 30 class CPDF_Document; 31 class CPDF_PageObject; 32 class PauseIndicatorIface; 33 34 // These structs are used to keep track of resources that have already been 35 // generated in the page object holder. 36 struct GraphicsData { 37 float fillAlpha; 38 float strokeAlpha; 39 BlendMode blendType; 40 41 bool operator<(const GraphicsData& other) const; 42 }; 43 44 struct FontData { 45 ByteString baseFont; 46 ByteString type; 47 48 bool operator<(const FontData& other) const; 49 }; 50 51 class CPDF_PageObjectHolder { 52 public: 53 enum class ParseState : uint8_t { kNotParsed, kParsing, kParsed }; 54 55 using iterator = std::deque<std::unique_ptr<CPDF_PageObject>>::iterator; 56 using const_iterator = 57 std::deque<std::unique_ptr<CPDF_PageObject>>::const_iterator; 58 59 CPDF_PageObjectHolder(CPDF_Document* pDoc, 60 RetainPtr<CPDF_Dictionary> pDict, 61 RetainPtr<CPDF_Dictionary> pPageResources, 62 RetainPtr<CPDF_Dictionary> pResources); 63 virtual ~CPDF_PageObjectHolder(); 64 65 virtual bool IsPage() const; 66 67 void StartParse(std::unique_ptr<CPDF_ContentParser> pParser); 68 void ContinueParse(PauseIndicatorIface* pPause); GetParseState()69 ParseState GetParseState() const { return m_ParseState; } 70 GetDocument()71 CPDF_Document* GetDocument() const { return m_pDocument; } GetDict()72 RetainPtr<const CPDF_Dictionary> GetDict() const { return m_pDict; } GetMutableDict()73 RetainPtr<CPDF_Dictionary> GetMutableDict() { return m_pDict; } GetResources()74 RetainPtr<const CPDF_Dictionary> GetResources() const { return m_pResources; } GetMutableResources()75 RetainPtr<CPDF_Dictionary> GetMutableResources() { return m_pResources; } SetResources(RetainPtr<CPDF_Dictionary> pDict)76 void SetResources(RetainPtr<CPDF_Dictionary> pDict) { 77 m_pResources = std::move(pDict); 78 } GetPageResources()79 RetainPtr<const CPDF_Dictionary> GetPageResources() const { 80 return m_pPageResources; 81 } GetMutablePageResources()82 RetainPtr<CPDF_Dictionary> GetMutablePageResources() { 83 return m_pPageResources; 84 } GetPageObjectCount()85 size_t GetPageObjectCount() const { return m_PageObjectList.size(); } 86 CPDF_PageObject* GetPageObjectByIndex(size_t index) const; 87 void AppendPageObject(std::unique_ptr<CPDF_PageObject> pPageObj); 88 89 // Remove `pPageObj` if present, and transfer ownership to the caller. 90 std::unique_ptr<CPDF_PageObject> RemovePageObject(CPDF_PageObject* pPageObj); 91 bool ErasePageObjectAtIndex(size_t index); 92 begin()93 iterator begin() { return m_PageObjectList.begin(); } begin()94 const_iterator begin() const { return m_PageObjectList.begin(); } 95 end()96 iterator end() { return m_PageObjectList.end(); } end()97 const_iterator end() const { return m_PageObjectList.end(); } 98 GetLastCTM()99 const CFX_Matrix& GetLastCTM() const { return m_LastCTM; } GetBBox()100 const CFX_FloatRect& GetBBox() const { return m_BBox; } 101 GetTransparency()102 const CPDF_Transparency& GetTransparency() const { return m_Transparency; } BackgroundAlphaNeeded()103 bool BackgroundAlphaNeeded() const { return m_bBackgroundAlphaNeeded; } SetBackgroundAlphaNeeded(bool needed)104 void SetBackgroundAlphaNeeded(bool needed) { 105 m_bBackgroundAlphaNeeded = needed; 106 } 107 HasImageMask()108 bool HasImageMask() const { return !m_MaskBoundingBoxes.empty(); } GetMaskBoundingBoxes()109 const std::vector<CFX_FloatRect>& GetMaskBoundingBoxes() const { 110 return m_MaskBoundingBoxes; 111 } 112 void AddImageMaskBoundingBox(const CFX_FloatRect& box); HasDirtyStreams()113 bool HasDirtyStreams() const { return !m_DirtyStreams.empty(); } 114 std::set<int32_t> TakeDirtyStreams(); 115 116 absl::optional<ByteString> GraphicsMapSearch(const GraphicsData& gd); 117 void GraphicsMapInsert(const GraphicsData& gd, const ByteString& str); 118 119 absl::optional<ByteString> FontsMapSearch(const FontData& fd); 120 void FontsMapInsert(const FontData& fd, const ByteString& str); 121 122 protected: 123 void LoadTransparencyInfo(); 124 125 RetainPtr<CPDF_Dictionary> m_pPageResources; 126 RetainPtr<CPDF_Dictionary> m_pResources; 127 std::map<GraphicsData, ByteString> m_GraphicsMap; 128 std::map<FontData, ByteString> m_FontsMap; 129 CFX_FloatRect m_BBox; 130 CPDF_Transparency m_Transparency; 131 132 private: 133 bool m_bBackgroundAlphaNeeded = false; 134 ParseState m_ParseState = ParseState::kNotParsed; 135 RetainPtr<CPDF_Dictionary> const m_pDict; 136 UnownedPtr<CPDF_Document> m_pDocument; 137 std::vector<CFX_FloatRect> m_MaskBoundingBoxes; 138 std::unique_ptr<CPDF_ContentParser> m_pParser; 139 std::deque<std::unique_ptr<CPDF_PageObject>> m_PageObjectList; 140 CFX_Matrix m_LastCTM; 141 142 // The indexes of Content streams that are dirty and need to be regenerated. 143 std::set<int32_t> m_DirtyStreams; 144 }; 145 146 #endif // CORE_FPDFAPI_PAGE_CPDF_PAGEOBJECTHOLDER_H_ 147