1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Copyright 2014 PDFium Authors. All rights reserved.
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Use of this source code is governed by a BSD-style license that can be
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// found in the LICENSE file.
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fpdfapi/fpdf_parser.h"
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fpdfapi/fpdf_module.h"
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovextern FX_LPVOID PDFPreviewInitCache(CPDF_Document* pDoc);
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovextern void PDFPreviewClearCache(FX_LPVOID pCache);
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Document::CPDF_Document(IPDF_DocParser* pParser) : CPDF_IndirectObjects(pParser)
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(pParser != NULL);
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pRootDict = NULL;
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pInfoDict = NULL;
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bLinearized = FALSE;
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_dwFirstPageNo = 0;
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_dwFirstPageObjNum = 0;
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pDocPage = CPDF_ModuleMgr::Get()->GetPageModule()->CreateDocData(this);
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pDocRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreateDocData(this);
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_DocPageData* CPDF_Document::GetValidatePageData()
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pDocPage) {
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return m_pDocPage;
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pDocPage = CPDF_ModuleMgr::Get()->GetPageModule()->CreateDocData(this);
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_pDocPage;
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_DocRenderData* CPDF_Document::GetValidateRenderData()
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pDocRender) {
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return m_pDocRender;
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pDocRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreateDocData(this);
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_pDocRender;
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_Document::LoadDoc()
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_LastObjNum = m_pParser->GetLastObjNum();
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Object* pRootObj = GetIndirectObject(m_pParser->GetRootObjNum());
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pRootObj == NULL) {
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pRootDict = pRootObj->GetDict();
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pRootDict == NULL) {
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Object* pInfoObj = GetIndirectObject(m_pParser->GetInfoObjNum());
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pInfoObj) {
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pInfoDict = pInfoObj->GetDict();
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Array* pIDArray = m_pParser->GetIDArray();
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pIDArray) {
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_ID1 = pIDArray->GetString(0);
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_ID2 = pIDArray->GetString(1);
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_PageList.SetSize(_GetPageCount());
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_Document::LoadAsynDoc(CPDF_Dictionary *pLinearized)
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bLinearized = TRUE;
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_LastObjNum = m_pParser->GetLastObjNum();
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pRootDict = GetIndirectObject(m_pParser->GetRootObjNum())->GetDict();
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pRootDict == NULL) {
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pInfoDict = GetIndirectObject(m_pParser->GetInfoObjNum())->GetDict();
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Array* pIDArray = m_pParser->GetIDArray();
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pIDArray) {
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_ID1 = pIDArray->GetString(0);
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_ID2 = pIDArray->GetString(1);
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD dwPageCount = 0;
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Object *pCount = pLinearized->GetElement(FX_BSTRC("N"));
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pCount && pCount->GetType() == PDFOBJ_NUMBER) {
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dwPageCount = pCount->GetInteger();
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_PageList.SetSize(dwPageCount);
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Object *pNo = pLinearized->GetElement(FX_BSTRC("P"));
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pNo && pNo->GetType() == PDFOBJ_NUMBER) {
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_dwFirstPageNo = pNo->GetInteger();
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Object *pObjNum = pLinearized->GetElement(FX_BSTRC("O"));
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pObjNum && pObjNum->GetType() == PDFOBJ_NUMBER) {
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_dwFirstPageObjNum = pObjNum->GetInteger();
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_Document::LoadPages()
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_PageList.SetSize(_GetPageCount());
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovextern void FPDF_TTFaceMapper_ReleaseDoc(CPDF_Document*);
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Document::~CPDF_Document()
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pDocRender) {
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_ModuleMgr::Get()->GetRenderModule()->DestroyDocData(m_pDocRender);
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pDocPage) {
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_ModuleMgr::Get()->GetPageModule()->ReleaseDoc(this);
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_ModuleMgr::Get()->GetPageModule()->ClearStockFont(this);
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define		FX_MAX_PAGE_LEVEL			1024
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Dictionary* CPDF_Document::_FindPDFPage(CPDF_Dictionary* pPages, int iPage, int nPagesToGo, int level)
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Array* pKidList = pPages->GetArray(FX_BSTRC("Kids"));
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pKidList == NULL) {
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (nPagesToGo == 0) {
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return pPages;
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (level >= FX_MAX_PAGE_LEVEL) {
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int nKids = pKidList->GetCount();
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < nKids; i ++) {
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Dictionary* pKid = pKidList->GetDict(i);
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pKid == NULL) {
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            nPagesToGo --;
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pKid == pPages) {
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!pKid->KeyExist(FX_BSTRC("Kids"))) {
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (nPagesToGo == 0) {
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return pKid;
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_PageList.SetAt(iPage - nPagesToGo, pKid->GetObjNum());
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            nPagesToGo --;
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int nPages = pKid->GetInteger(FX_BSTRC("Count"));
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (nPagesToGo < nPages) {
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return _FindPDFPage(pKid, iPage, nPagesToGo, level + 1);
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            nPagesToGo -= nPages;
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return NULL;
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Dictionary* CPDF_Document::GetPage(int iPage)
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (iPage < 0 || iPage >= m_PageList.GetSize()) {
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_bLinearized && (iPage == (int)m_dwFirstPageNo)) {
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Object* pObj = GetIndirectObject(m_dwFirstPageObjNum);
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pObj && pObj->GetType() == PDFOBJ_DICTIONARY) {
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return (CPDF_Dictionary*)pObj;
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int objnum = m_PageList.GetAt(iPage);
155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (objnum) {
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Object* pObj = GetIndirectObject(objnum);
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ASSERT(pObj->GetType() == PDFOBJ_DICTIONARY);
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return (CPDF_Dictionary*)pObj;
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pRoot = GetRoot();
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pRoot == NULL) {
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages"));
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pPages == NULL) {
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pPage = _FindPDFPage(pPages, iPage, iPage, 0);
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pPage == NULL) {
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_PageList.SetAt(iPage, pPage->GetObjNum());
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pPage;
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint CPDF_Document::_FindPageIndex(CPDF_Dictionary* pNode, FX_DWORD& skip_count, FX_DWORD objnum, int& index, int level)
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pNode->KeyExist(FX_BSTRC("Kids"))) {
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Array* pKidList = pNode->GetArray(FX_BSTRC("Kids"));
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pKidList == NULL) {
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return -1;
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (level >= FX_MAX_PAGE_LEVEL) {
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return -1;
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_DWORD count = pNode->GetInteger(FX_BSTRC("Count"));
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (count <= skip_count) {
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            skip_count -= count;
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            index += count;
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return -1;
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (count && count == pKidList->GetCount()) {
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (FX_DWORD i = 0; i < count; i ++) {
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                CPDF_Reference* pKid = (CPDF_Reference*)pKidList->GetElement(i);
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (pKid && pKid->GetType() == PDFOBJ_REFERENCE) {
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (pKid->GetRefObjNum() == objnum) {
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        m_PageList.SetAt(index + i, objnum);
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        return index + i;
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (FX_DWORD i = 0; i < pKidList->GetCount(); i ++) {
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CPDF_Dictionary* pKid = pKidList->GetDict(i);
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pKid == NULL) {
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pKid == pNode) {
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int found_index = _FindPageIndex(pKid, skip_count, objnum, index, level + 1);
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (found_index >= 0) {
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return found_index;
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (objnum == pNode->GetObjNum()) {
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return index;
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (skip_count) {
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            skip_count--;
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        index ++;
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return -1;
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint CPDF_Document::GetPageIndex(FX_DWORD objnum)
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD nPages = m_PageList.GetSize();
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD skip_count = 0;
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bSkipped = FALSE;
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (FX_DWORD i = 0; i < nPages; i ++) {
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_DWORD objnum1 = m_PageList.GetAt(i);
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (objnum1 == objnum) {
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return i;
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!bSkipped && objnum1 == 0) {
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            skip_count = i;
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bSkipped = TRUE;
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pRoot = GetRoot();
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pRoot == NULL) {
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return -1;
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages"));
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pPages == NULL) {
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return -1;
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int index = 0;
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return _FindPageIndex(pPages, skip_count, objnum, index);
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint CPDF_Document::GetPageCount() const
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_PageList.GetSize();
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic int _CountPages(CPDF_Dictionary* pPages, int level)
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (level > 128) {
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int count = pPages->GetInteger(FX_BSTRC("Count"));
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (count > 0 && count < FPDF_PAGE_MAX_NUM) {
263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return count;
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Array* pKidList = pPages->GetArray(FX_BSTRC("Kids"));
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pKidList == NULL) {
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    count = 0;
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (FX_DWORD i = 0; i < pKidList->GetCount(); i ++) {
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Dictionary* pKid = pKidList->GetDict(i);
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pKid == NULL) {
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!pKid->KeyExist(FX_BSTRC("Kids"))) {
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            count ++;
277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            count += _CountPages(pKid, level + 1);
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pPages->SetAtInteger(FX_BSTRC("Count"), count);
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return count;
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint CPDF_Document::_GetPageCount() const
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pRoot = GetRoot();
287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pRoot == NULL) {
288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages"));
291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pPages == NULL) {
292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!pPages->KeyExist(FX_BSTRC("Kids"))) {
295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 1;
296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return _CountPages(pPages, 0);
298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic FX_BOOL _EnumPages(CPDF_Dictionary* pPages, IPDF_EnumPageHandler* pHandler)
300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Array* pKidList = pPages->GetArray(FX_BSTRC("Kids"));
302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pKidList == NULL) {
303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return pHandler->EnumPage(pPages);
304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (FX_DWORD i = 0; i < pKidList->GetCount(); i ++) {
306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Dictionary* pKid = pKidList->GetDict(i);
307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pKid == NULL) {
308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!pKid->KeyExist(FX_BSTRC("Kids"))) {
311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (!pHandler->EnumPage(pKid)) {
312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return FALSE;
313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return _EnumPages(pKid, pHandler);
316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_Document::EnumPages(IPDF_EnumPageHandler* pHandler)
321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pRoot = GetRoot();
323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pRoot == NULL) {
324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages"));
327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pPages == NULL) {
328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _EnumPages(pPages, pHandler);
331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
332ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_Document::IsContentUsedElsewhere(FX_DWORD objnum, CPDF_Dictionary* pThisPageDict)
333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < m_PageList.GetSize(); i ++) {
335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Dictionary* pPageDict = GetPage(i);
336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pPageDict == pThisPageDict) {
337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Object* pContents = pPageDict->GetElement(FX_BSTRC("Contents"));
340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pContents == NULL) {
341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pContents->GetDirectType() == PDFOBJ_ARRAY) {
344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CPDF_Array* pArray = (CPDF_Array*)pContents->GetDirect();
345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (FX_DWORD j = 0; j < pArray->GetCount(); j ++) {
346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                CPDF_Reference* pRef = (CPDF_Reference*)pArray->GetElement(j);
347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (pRef->GetRefObjNum() == objnum) {
348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return TRUE;
349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (pContents->GetObjNum() == objnum) {
352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return TRUE;
353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FALSE;
356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
357ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_DWORD CPDF_Document::GetUserPermissions(FX_BOOL bCheckRevision) const
358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pParser == NULL) {
360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return (FX_DWORD) - 1;
361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_pParser->GetPermissions(bCheckRevision);
363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
364ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_Document::IsOwner() const
365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pParser == NULL) {
367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_pParser->IsOwner();
370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
371ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_Document::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) const
372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Object* pObj;
375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_IndirectObjs.Lookup((FX_LPVOID)(FX_UINTPTR)objnum, (FX_LPVOID&)pObj)) {
376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bForm = pObj->GetType() == PDFOBJ_STREAM &&
377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    ((CPDF_Stream*)pObj)->GetDict()->GetString(FX_BSTRC("Subtype")) == FX_BSTRC("Form");
378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return TRUE;
379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pParser == NULL) {
382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bForm = FALSE;
383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_pParser->IsFormStream(objnum, bForm);
386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_Document::ClearPageData()
388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pDocPage) {
390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_ModuleMgr::Get()->GetPageModule()->ClearDoc(this);
391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_Document::ClearRenderData()
394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pDocRender) {
396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_ModuleMgr::Get()->GetRenderModule()->ClearDocData(m_pDocRender);
397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
399