• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 PDFium Authors. All rights reserved.
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_page.h"
8 
9 #include <set>
10 #include <utility>
11 
12 #include "core/fpdfapi/cpdf_pagerendercontext.h"
13 #include "core/fpdfapi/page/cpdf_contentparser.h"
14 #include "core/fpdfapi/page/cpdf_pageobject.h"
15 #include "core/fpdfapi/page/pageint.h"
16 #include "core/fpdfapi/parser/cpdf_array.h"
17 #include "core/fpdfapi/parser/cpdf_dictionary.h"
18 #include "core/fpdfapi/parser/cpdf_object.h"
19 #include "core/fpdfapi/render/cpdf_pagerendercache.h"
20 #include "third_party/base/ptr_util.h"
21 #include "third_party/base/stl_util.h"
22 
CPDF_Page(CPDF_Document * pDocument,CPDF_Dictionary * pPageDict,bool bPageCache)23 CPDF_Page::CPDF_Page(CPDF_Document* pDocument,
24                      CPDF_Dictionary* pPageDict,
25                      bool bPageCache)
26     : m_PageWidth(100),
27       m_PageHeight(100),
28       m_pView(nullptr),
29       m_pPageRender(bPageCache ? new CPDF_PageRenderCache(this) : nullptr) {
30   m_pFormDict = pPageDict;
31   m_pDocument = pDocument;
32   if (!pPageDict)
33     return;
34 
35   CPDF_Object* pageAttr = GetPageAttr("Resources");
36   m_pResources = pageAttr ? pageAttr->GetDict() : nullptr;
37   m_pPageResources = m_pResources;
38   CPDF_Object* pRotate = GetPageAttr("Rotate");
39   int rotate = pRotate ? pRotate->GetInteger() / 90 % 4 : 0;
40   if (rotate < 0)
41     rotate += 4;
42 
43   CPDF_Array* pMediaBox = ToArray(GetPageAttr("MediaBox"));
44   CFX_FloatRect mediabox;
45   if (pMediaBox) {
46     mediabox = pMediaBox->GetRect();
47     mediabox.Normalize();
48   }
49   if (mediabox.IsEmpty())
50     mediabox = CFX_FloatRect(0, 0, 612, 792);
51 
52   CPDF_Array* pCropBox = ToArray(GetPageAttr("CropBox"));
53   if (pCropBox) {
54     m_BBox = pCropBox->GetRect();
55     m_BBox.Normalize();
56   }
57   if (m_BBox.IsEmpty())
58     m_BBox = mediabox;
59   else
60     m_BBox.Intersect(mediabox);
61 
62   m_PageWidth = m_BBox.right - m_BBox.left;
63   m_PageHeight = m_BBox.top - m_BBox.bottom;
64   if (rotate % 2)
65     std::swap(m_PageWidth, m_PageHeight);
66 
67   switch (rotate) {
68     case 0:
69       m_PageMatrix = CFX_Matrix(1.0f, 0, 0, 1.0f, -m_BBox.left, -m_BBox.bottom);
70       break;
71     case 1:
72       m_PageMatrix =
73           CFX_Matrix(0, -1.0f, 1.0f, 0, -m_BBox.bottom, m_BBox.right);
74       break;
75     case 2:
76       m_PageMatrix = CFX_Matrix(-1.0f, 0, 0, -1.0f, m_BBox.right, m_BBox.top);
77       break;
78     case 3:
79       m_PageMatrix = CFX_Matrix(0, 1.0f, -1.0f, 0, m_BBox.top, -m_BBox.left);
80       break;
81   }
82 
83   m_Transparency = PDFTRANS_ISOLATED;
84   LoadTransInfo();
85 }
86 
~CPDF_Page()87 CPDF_Page::~CPDF_Page() {}
88 
StartParse()89 void CPDF_Page::StartParse() {
90   if (m_ParseState == CONTENT_PARSED || m_ParseState == CONTENT_PARSING)
91     return;
92 
93   m_pParser = pdfium::MakeUnique<CPDF_ContentParser>();
94   m_pParser->Start(this);
95   m_ParseState = CONTENT_PARSING;
96 }
97 
ParseContent()98 void CPDF_Page::ParseContent() {
99   StartParse();
100   ContinueParse(nullptr);
101 }
102 
SetRenderContext(std::unique_ptr<CPDF_PageRenderContext> pContext)103 void CPDF_Page::SetRenderContext(
104     std::unique_ptr<CPDF_PageRenderContext> pContext) {
105   m_pRenderContext = std::move(pContext);
106 }
107 
GetPageAttr(const CFX_ByteString & name) const108 CPDF_Object* CPDF_Page::GetPageAttr(const CFX_ByteString& name) const {
109   CPDF_Dictionary* pPageDict = m_pFormDict;
110   std::set<CPDF_Dictionary*> visited;
111   while (1) {
112     visited.insert(pPageDict);
113     if (CPDF_Object* pObj = pPageDict->GetDirectObjectFor(name))
114       return pObj;
115 
116     pPageDict = pPageDict->GetDictFor("Parent");
117     if (!pPageDict || pdfium::ContainsKey(visited, pPageDict))
118       break;
119   }
120   return nullptr;
121 }
122 
GetDisplayMatrix(int xPos,int yPos,int xSize,int ySize,int iRotate) const123 CFX_Matrix CPDF_Page::GetDisplayMatrix(int xPos,
124                                        int yPos,
125                                        int xSize,
126                                        int ySize,
127                                        int iRotate) const {
128   if (m_PageWidth == 0 || m_PageHeight == 0)
129     return CFX_Matrix();
130 
131   float x0 = 0;
132   float y0 = 0;
133   float x1 = 0;
134   float y1 = 0;
135   float x2 = 0;
136   float y2 = 0;
137   iRotate %= 4;
138   switch (iRotate) {
139     case 0:
140       x0 = xPos;
141       y0 = yPos + ySize;
142       x1 = xPos;
143       y1 = yPos;
144       x2 = xPos + xSize;
145       y2 = yPos + ySize;
146       break;
147     case 1:
148       x0 = xPos;
149       y0 = yPos;
150       x1 = xPos + xSize;
151       y1 = yPos;
152       x2 = xPos;
153       y2 = yPos + ySize;
154       break;
155     case 2:
156       x0 = xPos + xSize;
157       y0 = yPos;
158       x1 = xPos + xSize;
159       y1 = yPos + ySize;
160       x2 = xPos;
161       y2 = yPos;
162       break;
163     case 3:
164       x0 = xPos + xSize;
165       y0 = yPos + ySize;
166       x1 = xPos;
167       y1 = yPos + ySize;
168       x2 = xPos + xSize;
169       y2 = yPos;
170       break;
171   }
172   CFX_Matrix matrix = m_PageMatrix;
173   matrix.Concat(CFX_Matrix((x2 - x0) / m_PageWidth, (y2 - y0) / m_PageWidth,
174                            (x1 - x0) / m_PageHeight, (y1 - y0) / m_PageHeight,
175                            x0, y0));
176   return matrix;
177 }
178 
operator <(const GraphicsData & other) const179 bool GraphicsData::operator<(const GraphicsData& other) const {
180   if (fillAlpha != other.fillAlpha)
181     return fillAlpha < other.fillAlpha;
182   return strokeAlpha < other.strokeAlpha;
183 }
184 
operator <(const FontData & other) const185 bool FontData::operator<(const FontData& other) const {
186   return baseFont < other.baseFont;
187 }
188