• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "core/fpdfapi/page/cpdf_form.h"
8 
9 #include <algorithm>
10 #include <memory>
11 
12 #include "core/fpdfapi/page/cpdf_contentparser.h"
13 #include "core/fpdfapi/page/cpdf_imageobject.h"
14 #include "core/fpdfapi/page/cpdf_pageobject.h"
15 #include "core/fpdfapi/page/cpdf_pageobjectholder.h"
16 #include "core/fpdfapi/parser/cpdf_dictionary.h"
17 #include "core/fpdfapi/parser/cpdf_stream.h"
18 #include "core/fxge/dib/cfx_dibitmap.h"
19 #include "third_party/base/check_op.h"
20 
21 // static
ChooseResourcesDict(CPDF_Dictionary * pResources,CPDF_Dictionary * pParentResources,CPDF_Dictionary * pPageResources)22 CPDF_Dictionary* CPDF_Form::ChooseResourcesDict(
23     CPDF_Dictionary* pResources,
24     CPDF_Dictionary* pParentResources,
25     CPDF_Dictionary* pPageResources) {
26   if (pResources)
27     return pResources;
28   return pParentResources ? pParentResources : pPageResources;
29 }
30 
CPDF_Form(CPDF_Document * pDoc,RetainPtr<CPDF_Dictionary> pPageResources,RetainPtr<CPDF_Stream> pFormStream)31 CPDF_Form::CPDF_Form(CPDF_Document* pDoc,
32                      RetainPtr<CPDF_Dictionary> pPageResources,
33                      RetainPtr<CPDF_Stream> pFormStream)
34     : CPDF_Form(pDoc,
35                 std::move(pPageResources),
36                 std::move(pFormStream),
37                 nullptr) {}
38 
CPDF_Form(CPDF_Document * pDoc,RetainPtr<CPDF_Dictionary> pPageResources,RetainPtr<CPDF_Stream> pFormStream,CPDF_Dictionary * pParentResources)39 CPDF_Form::CPDF_Form(CPDF_Document* pDoc,
40                      RetainPtr<CPDF_Dictionary> pPageResources,
41                      RetainPtr<CPDF_Stream> pFormStream,
42                      CPDF_Dictionary* pParentResources)
43     : CPDF_PageObjectHolder(pDoc,
44                             pFormStream->GetMutableDict(),
45                             pPageResources,
46                             pdfium::WrapRetain(ChooseResourcesDict(
47                                 pFormStream->GetMutableDict()
48                                     ->GetMutableDictFor("Resources")
49                                     .Get(),
50                                 pParentResources,
51                                 pPageResources.Get()))),
52       m_pFormStream(std::move(pFormStream)) {
53   LoadTransparencyInfo();
54 }
55 
56 CPDF_Form::~CPDF_Form() = default;
57 
ParseContent()58 void CPDF_Form::ParseContent() {
59   ParseContentInternal(nullptr, nullptr, nullptr, nullptr);
60 }
61 
ParseContent(const CPDF_AllStates * pGraphicStates,const CFX_Matrix * pParentMatrix,std::set<const uint8_t * > * pParsedSet)62 void CPDF_Form::ParseContent(const CPDF_AllStates* pGraphicStates,
63                              const CFX_Matrix* pParentMatrix,
64                              std::set<const uint8_t*>* pParsedSet) {
65   ParseContentInternal(pGraphicStates, pParentMatrix, nullptr, pParsedSet);
66 }
67 
ParseContentForType3Char(CPDF_Type3Char * pType3Char)68 void CPDF_Form::ParseContentForType3Char(CPDF_Type3Char* pType3Char) {
69   ParseContentInternal(nullptr, nullptr, pType3Char, nullptr);
70 }
71 
ParseContentInternal(const CPDF_AllStates * pGraphicStates,const CFX_Matrix * pParentMatrix,CPDF_Type3Char * pType3Char,std::set<const uint8_t * > * pParsedSet)72 void CPDF_Form::ParseContentInternal(const CPDF_AllStates* pGraphicStates,
73                                      const CFX_Matrix* pParentMatrix,
74                                      CPDF_Type3Char* pType3Char,
75                                      std::set<const uint8_t*>* pParsedSet) {
76   if (GetParseState() == ParseState::kParsed)
77     return;
78 
79   if (GetParseState() == ParseState::kNotParsed) {
80     StartParse(std::make_unique<CPDF_ContentParser>(
81         GetStream(), this, pGraphicStates, pParentMatrix, pType3Char,
82         pParsedSet ? pParsedSet : &m_ParsedSet));
83   }
84   DCHECK_EQ(GetParseState(), ParseState::kParsing);
85   ContinueParse(nullptr);
86 }
87 
HasPageObjects() const88 bool CPDF_Form::HasPageObjects() const {
89   return GetPageObjectCount() != 0;
90 }
91 
CalcBoundingBox() const92 CFX_FloatRect CPDF_Form::CalcBoundingBox() const {
93   if (GetPageObjectCount() == 0)
94     return CFX_FloatRect();
95 
96   float left = 1000000.0f;
97   float right = -1000000.0f;
98   float bottom = 1000000.0f;
99   float top = -1000000.0f;
100   for (const auto& pObj : *this) {
101     const auto& rect = pObj->GetRect();
102     left = std::min(left, rect.left);
103     right = std::max(right, rect.right);
104     bottom = std::min(bottom, rect.bottom);
105     top = std::max(top, rect.top);
106   }
107   return CFX_FloatRect(left, bottom, right, top);
108 }
109 
GetStream() const110 RetainPtr<const CPDF_Stream> CPDF_Form::GetStream() const {
111   return m_pFormStream;
112 }
113 
114 absl::optional<std::pair<RetainPtr<CFX_DIBitmap>, CFX_Matrix>>
GetBitmapAndMatrixFromSoleImageOfForm() const115 CPDF_Form::GetBitmapAndMatrixFromSoleImageOfForm() const {
116   if (GetPageObjectCount() != 1)
117     return absl::nullopt;
118 
119   CPDF_ImageObject* pImageObject = (*begin())->AsImage();
120   if (!pImageObject)
121     return absl::nullopt;
122 
123   return {{pImageObject->GetIndependentBitmap(), pImageObject->matrix()}};
124 }
125