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 23CPDF_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 87CPDF_Page::~CPDF_Page() {} 88 89void 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 98void CPDF_Page::ParseContent() { 99 StartParse(); 100 ContinueParse(nullptr); 101} 102 103void CPDF_Page::SetRenderContext( 104 std::unique_ptr<CPDF_PageRenderContext> pContext) { 105 m_pRenderContext = std::move(pContext); 106} 107 108CPDF_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 123CFX_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 179bool GraphicsData::operator<(const GraphicsData& other) const { 180 if (fillAlpha != other.fillAlpha) 181 return fillAlpha < other.fillAlpha; 182 return strokeAlpha < other.strokeAlpha; 183} 184 185bool FontData::operator<(const FontData& other) const { 186 return baseFont < other.baseFont; 187} 188