Index: core/fpdfdoc/doc_basic.cpp |
diff --git a/core/fpdfdoc/doc_basic.cpp b/core/fpdfdoc/doc_basic.cpp |
deleted file mode 100644 |
index 97acf2384fb4a6dc302c8872fea95103e708c0c8..0000000000000000000000000000000000000000 |
--- a/core/fpdfdoc/doc_basic.cpp |
+++ /dev/null |
@@ -1,568 +0,0 @@ |
-// Copyright 2014 PDFium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
- |
-#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" |
-#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" |
-#include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h" |
-#include "core/fpdfdoc/doc_utils.h" |
-#include "core/fpdfdoc/cpdf_pagelabel.h" |
-#include "core/fpdfdoc/include/cpdf_filespec.h" |
-#include "core/fpdfdoc/include/cpdf_nametree.h" |
-#include "core/fpdfdoc/include/ipdf_formnotify.h" |
- |
-namespace { |
- |
-const int nMaxRecursion = 32; |
-const FX_CHAR* const g_sZoomModes[] = {"XYZ", "Fit", "FitH", "FitV", "FitR", |
- "FitB", "FitBH", "FitBV", nullptr}; |
- |
-} // namespace |
- |
-int CPDF_Dest::GetPageIndex(CPDF_Document* pDoc) { |
- CPDF_Array* pArray = ToArray(m_pObj); |
- if (!pArray) |
- return 0; |
- |
- CPDF_Object* pPage = pArray->GetDirectObjectAt(0); |
- if (!pPage) |
- return 0; |
- if (pPage->IsNumber()) |
- return pPage->GetInteger(); |
- if (!pPage->IsDictionary()) |
- return 0; |
- return pDoc->GetPageIndex(pPage->GetObjNum()); |
-} |
- |
-uint32_t CPDF_Dest::GetPageObjNum() { |
- CPDF_Array* pArray = ToArray(m_pObj); |
- if (!pArray) |
- return 0; |
- |
- CPDF_Object* pPage = pArray->GetDirectObjectAt(0); |
- if (!pPage) |
- return 0; |
- if (pPage->IsNumber()) |
- return pPage->GetInteger(); |
- if (pPage->IsDictionary()) |
- return pPage->GetObjNum(); |
- return 0; |
-} |
- |
-int CPDF_Dest::GetZoomMode() { |
- CPDF_Array* pArray = ToArray(m_pObj); |
- if (!pArray) |
- return 0; |
- |
- CPDF_Object* pObj = pArray->GetDirectObjectAt(1); |
- if (!pObj) |
- return 0; |
- |
- CFX_ByteString mode = pObj->GetString(); |
- for (int i = 0; g_sZoomModes[i]; ++i) { |
- if (mode == g_sZoomModes[i]) |
- return i + 1; |
- } |
- |
- return 0; |
-} |
- |
-FX_FLOAT CPDF_Dest::GetParam(int index) { |
- CPDF_Array* pArray = ToArray(m_pObj); |
- return pArray ? pArray->GetNumberAt(2 + index) : 0; |
-} |
- |
-CFX_ByteString CPDF_Dest::GetRemoteName() { |
- return m_pObj ? m_pObj->GetString() : CFX_ByteString(); |
-} |
- |
-CPDF_NameTree::CPDF_NameTree(CPDF_Document* pDoc, |
- const CFX_ByteString& category) |
- : m_pRoot(nullptr) { |
- CPDF_Dictionary* pRoot = pDoc->GetRoot(); |
- if (!pRoot) |
- return; |
- |
- CPDF_Dictionary* pNames = pRoot->GetDictBy("Names"); |
- if (!pNames) |
- return; |
- |
- m_pRoot = pNames->GetDictBy(category); |
-} |
- |
-static CPDF_Object* SearchNameNode(CPDF_Dictionary* pNode, |
- const CFX_ByteString& csName, |
- size_t& nIndex, |
- CPDF_Array** ppFind, |
- int nLevel = 0) { |
- if (nLevel > nMaxRecursion) { |
- return nullptr; |
- } |
- CPDF_Array* pLimits = pNode->GetArrayBy("Limits"); |
- if (pLimits) { |
- CFX_ByteString csLeft = pLimits->GetStringAt(0); |
- CFX_ByteString csRight = pLimits->GetStringAt(1); |
- if (csLeft.Compare(csRight.AsStringC()) > 0) { |
- CFX_ByteString csTmp = csRight; |
- csRight = csLeft; |
- csLeft = csTmp; |
- } |
- if (csName.Compare(csLeft.AsStringC()) < 0 || |
- csName.Compare(csRight.AsStringC()) > 0) { |
- return nullptr; |
- } |
- } |
- CPDF_Array* pNames = pNode->GetArrayBy("Names"); |
- if (pNames) { |
- size_t dwCount = pNames->GetCount() / 2; |
- for (size_t i = 0; i < dwCount; i++) { |
- CFX_ByteString csValue = pNames->GetStringAt(i * 2); |
- int32_t iCompare = csValue.Compare(csName.AsStringC()); |
- if (iCompare <= 0) { |
- if (ppFind) { |
- *ppFind = pNames; |
- } |
- if (iCompare < 0) { |
- continue; |
- } |
- } else { |
- break; |
- } |
- nIndex += i; |
- return pNames->GetDirectObjectAt(i * 2 + 1); |
- } |
- nIndex += dwCount; |
- return nullptr; |
- } |
- CPDF_Array* pKids = pNode->GetArrayBy("Kids"); |
- if (!pKids) { |
- return nullptr; |
- } |
- for (size_t i = 0; i < pKids->GetCount(); i++) { |
- CPDF_Dictionary* pKid = pKids->GetDictAt(i); |
- if (!pKid) { |
- continue; |
- } |
- CPDF_Object* pFound = |
- SearchNameNode(pKid, csName, nIndex, ppFind, nLevel + 1); |
- if (pFound) { |
- return pFound; |
- } |
- } |
- return nullptr; |
-} |
- |
-static CPDF_Object* SearchNameNode(CPDF_Dictionary* pNode, |
- size_t nIndex, |
- size_t& nCurIndex, |
- CFX_ByteString& csName, |
- CPDF_Array** ppFind, |
- int nLevel = 0) { |
- if (nLevel > nMaxRecursion) |
- return nullptr; |
- |
- CPDF_Array* pNames = pNode->GetArrayBy("Names"); |
- if (pNames) { |
- size_t nCount = pNames->GetCount() / 2; |
- if (nIndex >= nCurIndex + nCount) { |
- nCurIndex += nCount; |
- return nullptr; |
- } |
- if (ppFind) |
- *ppFind = pNames; |
- csName = pNames->GetStringAt((nIndex - nCurIndex) * 2); |
- return pNames->GetDirectObjectAt((nIndex - nCurIndex) * 2 + 1); |
- } |
- CPDF_Array* pKids = pNode->GetArrayBy("Kids"); |
- if (!pKids) |
- return nullptr; |
- for (size_t i = 0; i < pKids->GetCount(); i++) { |
- CPDF_Dictionary* pKid = pKids->GetDictAt(i); |
- if (!pKid) |
- continue; |
- CPDF_Object* pFound = |
- SearchNameNode(pKid, nIndex, nCurIndex, csName, ppFind, nLevel + 1); |
- if (pFound) |
- return pFound; |
- } |
- return nullptr; |
-} |
- |
-static size_t CountNames(CPDF_Dictionary* pNode, int nLevel = 0) { |
- if (nLevel > nMaxRecursion) { |
- return 0; |
- } |
- CPDF_Array* pNames = pNode->GetArrayBy("Names"); |
- if (pNames) { |
- return pNames->GetCount() / 2; |
- } |
- CPDF_Array* pKids = pNode->GetArrayBy("Kids"); |
- if (!pKids) { |
- return 0; |
- } |
- size_t nCount = 0; |
- for (size_t i = 0; i < pKids->GetCount(); i++) { |
- CPDF_Dictionary* pKid = pKids->GetDictAt(i); |
- if (!pKid) { |
- continue; |
- } |
- nCount += CountNames(pKid, nLevel + 1); |
- } |
- return nCount; |
-} |
- |
-size_t CPDF_NameTree::GetCount() const { |
- if (!m_pRoot) { |
- return 0; |
- } |
- return ::CountNames(m_pRoot); |
-} |
- |
-int CPDF_NameTree::GetIndex(const CFX_ByteString& csName) const { |
- if (!m_pRoot) { |
- return -1; |
- } |
- size_t nIndex = 0; |
- if (!SearchNameNode(m_pRoot, csName, nIndex, nullptr)) { |
- return -1; |
- } |
- return nIndex; |
-} |
- |
-CPDF_Object* CPDF_NameTree::LookupValue(int nIndex, |
- CFX_ByteString& csName) const { |
- if (!m_pRoot) { |
- return nullptr; |
- } |
- size_t nCurIndex = 0; |
- return SearchNameNode(m_pRoot, nIndex, nCurIndex, csName, nullptr); |
-} |
- |
-CPDF_Object* CPDF_NameTree::LookupValue(const CFX_ByteString& csName) const { |
- if (!m_pRoot) { |
- return nullptr; |
- } |
- size_t nIndex = 0; |
- return SearchNameNode(m_pRoot, csName, nIndex, nullptr); |
-} |
- |
-CPDF_Array* CPDF_NameTree::LookupNamedDest(CPDF_Document* pDoc, |
- const CFX_ByteString& sName) { |
- CPDF_Object* pValue = LookupValue(sName); |
- if (!pValue) { |
- CPDF_Dictionary* pDests = pDoc->GetRoot()->GetDictBy("Dests"); |
- if (!pDests) |
- return nullptr; |
- pValue = pDests->GetDirectObjectBy(sName); |
- } |
- if (!pValue) |
- return nullptr; |
- if (CPDF_Array* pArray = pValue->AsArray()) |
- return pArray; |
- if (CPDF_Dictionary* pDict = pValue->AsDictionary()) |
- return pDict->GetArrayBy("D"); |
- return nullptr; |
-} |
- |
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ || \ |
- _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ |
-static CFX_WideString ChangeSlashToPlatform(const FX_WCHAR* str) { |
- CFX_WideString result; |
- while (*str) { |
- if (*str == '/') { |
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
- result += ':'; |
-#else |
- result += '\\'; |
-#endif |
- } else { |
- result += *str; |
- } |
- str++; |
- } |
- return result; |
-} |
- |
-static CFX_WideString ChangeSlashToPDF(const FX_WCHAR* str) { |
- CFX_WideString result; |
- while (*str) { |
- if (*str == '\\' || *str == ':') { |
- result += '/'; |
- } else { |
- result += *str; |
- } |
- str++; |
- } |
- return result; |
-} |
-#endif // _FXM_PLATFORM_APPLE_ || _FXM_PLATFORM_WINDOWS_ |
- |
-CFX_WideString CPDF_FileSpec::DecodeFileName(const CFX_WideStringC& filepath) { |
- if (filepath.GetLength() <= 1) |
- return CFX_WideString(); |
- |
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
- if (filepath.Left(sizeof("/Mac") - 1) == CFX_WideStringC(L"/Mac")) |
- return ChangeSlashToPlatform(filepath.c_str() + 1); |
- return ChangeSlashToPlatform(filepath.c_str()); |
-#elif _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ |
- if (filepath.GetAt(0) != '/') |
- return ChangeSlashToPlatform(filepath.c_str()); |
- if (filepath.GetAt(1) == '/') |
- return ChangeSlashToPlatform(filepath.c_str() + 1); |
- if (filepath.GetAt(2) == '/') { |
- CFX_WideString result; |
- result += filepath.GetAt(1); |
- result += ':'; |
- result += ChangeSlashToPlatform(filepath.c_str() + 2); |
- return result; |
- } |
- CFX_WideString result; |
- result += '\\'; |
- result += ChangeSlashToPlatform(filepath.c_str()); |
- return result; |
-#else |
- return CFX_WideString(filepath); |
-#endif |
-} |
- |
-bool CPDF_FileSpec::GetFileName(CFX_WideString* csFileName) const { |
- if (CPDF_Dictionary* pDict = m_pObj->AsDictionary()) { |
- *csFileName = pDict->GetUnicodeTextBy("UF"); |
- if (csFileName->IsEmpty()) { |
- *csFileName = |
- CFX_WideString::FromLocal(pDict->GetStringBy("F").AsStringC()); |
- } |
- if (pDict->GetStringBy("FS") == "URL") |
- return true; |
- if (csFileName->IsEmpty()) { |
- if (pDict->KeyExist("DOS")) { |
- *csFileName = |
- CFX_WideString::FromLocal(pDict->GetStringBy("DOS").AsStringC()); |
- } else if (pDict->KeyExist("Mac")) { |
- *csFileName = |
- CFX_WideString::FromLocal(pDict->GetStringBy("Mac").AsStringC()); |
- } else if (pDict->KeyExist("Unix")) { |
- *csFileName = |
- CFX_WideString::FromLocal(pDict->GetStringBy("Unix").AsStringC()); |
- } else { |
- return false; |
- } |
- } |
- } else if (m_pObj->IsString()) { |
- *csFileName = CFX_WideString::FromLocal(m_pObj->GetString().AsStringC()); |
- } else { |
- return false; |
- } |
- *csFileName = DecodeFileName(csFileName->AsStringC()); |
- return true; |
-} |
- |
-CPDF_FileSpec::CPDF_FileSpec() { |
- m_pObj = new CPDF_Dictionary; |
- m_pObj->AsDictionary()->SetAtName("Type", "Filespec"); |
-} |
- |
-CFX_WideString CPDF_FileSpec::EncodeFileName(const CFX_WideStringC& filepath) { |
- if (filepath.GetLength() <= 1) { |
- return CFX_WideString(); |
- } |
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ |
- if (filepath.GetAt(1) == ':') { |
- CFX_WideString result; |
- result = '/'; |
- result += filepath.GetAt(0); |
- if (filepath.GetAt(2) != '\\') { |
- result += '/'; |
- } |
- result += ChangeSlashToPDF(filepath.c_str() + 2); |
- return result; |
- } |
- if (filepath.GetAt(0) == '\\' && filepath.GetAt(1) == '\\') { |
- return ChangeSlashToPDF(filepath.c_str() + 1); |
- } |
- if (filepath.GetAt(0) == '\\') { |
- CFX_WideString result; |
- result = '/'; |
- result += ChangeSlashToPDF(filepath.c_str()); |
- return result; |
- } |
- return ChangeSlashToPDF(filepath.c_str()); |
-#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
- if (filepath.Left(sizeof("Mac") - 1) == FX_WSTRC(L"Mac")) { |
- CFX_WideString result; |
- result = '/'; |
- result += ChangeSlashToPDF(filepath.c_str()); |
- return result; |
- } |
- return ChangeSlashToPDF(filepath.c_str()); |
-#else |
- return CFX_WideString(filepath); |
-#endif |
-} |
- |
-void CPDF_FileSpec::SetFileName(const CFX_WideStringC& wsFileName) { |
- if (!m_pObj) |
- return; |
- |
- CFX_WideString wsStr = EncodeFileName(wsFileName); |
- if (m_pObj->IsString()) { |
- m_pObj->SetString(CFX_ByteString::FromUnicode(wsStr)); |
- } else if (CPDF_Dictionary* pDict = m_pObj->AsDictionary()) { |
- pDict->SetAtString("F", CFX_ByteString::FromUnicode(wsStr)); |
- pDict->SetAtString("UF", PDF_EncodeText(wsStr)); |
- } |
-} |
- |
-static CFX_WideString _MakeRoman(int num) { |
- const int arabic[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}; |
- const CFX_WideString roman[] = {L"m", L"cm", L"d", L"cd", L"c", |
- L"xc", L"l", L"xl", L"x", L"ix", |
- L"v", L"iv", L"i"}; |
- const int nMaxNum = 1000000; |
- num %= nMaxNum; |
- int i = 0; |
- CFX_WideString wsRomanNumber; |
- while (num > 0) { |
- while (num >= arabic[i]) { |
- num = num - arabic[i]; |
- wsRomanNumber += roman[i]; |
- } |
- i = i + 1; |
- } |
- return wsRomanNumber; |
-} |
- |
-static CFX_WideString _MakeLetters(int num) { |
- if (num == 0) { |
- return CFX_WideString(); |
- } |
- CFX_WideString wsLetters; |
- const int nMaxCount = 1000; |
- const int nLetterCount = 26; |
- num -= 1; |
- int count = num / nLetterCount + 1; |
- count %= nMaxCount; |
- FX_WCHAR ch = L'a' + num % nLetterCount; |
- for (int i = 0; i < count; i++) { |
- wsLetters += ch; |
- } |
- return wsLetters; |
-} |
- |
-static CFX_WideString _GetLabelNumPortion(int num, |
- const CFX_ByteString& bsStyle) { |
- CFX_WideString wsNumPortion; |
- if (bsStyle.IsEmpty()) { |
- return wsNumPortion; |
- } |
- if (bsStyle == "D") { |
- wsNumPortion.Format(L"%d", num); |
- } else if (bsStyle == "R") { |
- wsNumPortion = _MakeRoman(num); |
- wsNumPortion.MakeUpper(); |
- } else if (bsStyle == "r") { |
- wsNumPortion = _MakeRoman(num); |
- } else if (bsStyle == "A") { |
- wsNumPortion = _MakeLetters(num); |
- wsNumPortion.MakeUpper(); |
- } else if (bsStyle == "a") { |
- wsNumPortion = _MakeLetters(num); |
- } |
- return wsNumPortion; |
-} |
- |
-IPDF_FormNotify::~IPDF_FormNotify() {} |
- |
-int IPDF_FormNotify::BeforeValueChange(CPDF_FormField* pField, |
- const CFX_WideString& csValue) { |
- return 0; |
-} |
- |
-void IPDF_FormNotify::AfterValueChange(CPDF_FormField* pField) {} |
- |
-int IPDF_FormNotify::BeforeSelectionChange(CPDF_FormField* pField, |
- const CFX_WideString& csValue) { |
- return 0; |
-} |
- |
-void IPDF_FormNotify::AfterSelectionChange(CPDF_FormField* pField) {} |
- |
-void IPDF_FormNotify::AfterCheckedStatusChange(CPDF_FormField* pField) {} |
- |
-int IPDF_FormNotify::BeforeFormReset(CPDF_InterForm* pForm) { |
- return 0; |
-} |
- |
-void IPDF_FormNotify::AfterFormReset(CPDF_InterForm* pForm) {} |
- |
-int IPDF_FormNotify::BeforeFormImportData(CPDF_InterForm* pForm) { |
- return 0; |
-} |
- |
-void IPDF_FormNotify::AfterFormImportData(CPDF_InterForm* pForm) {} |
- |
-CPDF_PageLabel::CPDF_PageLabel(CPDF_Document* pDocument) |
- : m_pDocument(pDocument) {} |
- |
-CFX_WideString CPDF_PageLabel::GetLabel(int nPage) const { |
- CFX_WideString wsLabel; |
- if (!m_pDocument) { |
- return wsLabel; |
- } |
- CPDF_Dictionary* pPDFRoot = m_pDocument->GetRoot(); |
- if (!pPDFRoot) { |
- return wsLabel; |
- } |
- CPDF_Dictionary* pLabels = pPDFRoot->GetDictBy("PageLabels"); |
- CPDF_NumberTree numberTree(pLabels); |
- CPDF_Object* pValue = nullptr; |
- int n = nPage; |
- while (n >= 0) { |
- pValue = numberTree.LookupValue(n); |
- if (pValue) { |
- break; |
- } |
- n--; |
- } |
- if (pValue) { |
- pValue = pValue->GetDirect(); |
- if (CPDF_Dictionary* pLabel = pValue->AsDictionary()) { |
- if (pLabel->KeyExist("P")) { |
- wsLabel += pLabel->GetUnicodeTextBy("P"); |
- } |
- CFX_ByteString bsNumberingStyle = pLabel->GetStringBy("S", ""); |
- int nLabelNum = nPage - n + pLabel->GetIntegerBy("St", 1); |
- CFX_WideString wsNumPortion = |
- _GetLabelNumPortion(nLabelNum, bsNumberingStyle); |
- wsLabel += wsNumPortion; |
- return wsLabel; |
- } |
- } |
- wsLabel.Format(L"%d", nPage + 1); |
- return wsLabel; |
-} |
- |
-int32_t CPDF_PageLabel::GetPageByLabel(const CFX_ByteStringC& bsLabel) const { |
- if (!m_pDocument) |
- return -1; |
- |
- CPDF_Dictionary* pPDFRoot = m_pDocument->GetRoot(); |
- if (!pPDFRoot) |
- return -1; |
- |
- int nPages = m_pDocument->GetPageCount(); |
- for (int i = 0; i < nPages; i++) { |
- if (PDF_EncodeText(GetLabel(i)).Compare(bsLabel)) |
- return i; |
- } |
- |
- int nPage = FXSYS_atoi(CFX_ByteString(bsLabel).c_str()); // NUL terminate. |
- return nPage > 0 && nPage <= nPages ? nPage : -1; |
-} |
- |
-int32_t CPDF_PageLabel::GetPageByLabel(const CFX_WideStringC& wsLabel) const { |
- return GetPageByLabel(PDF_EncodeText(wsLabel.c_str()).AsStringC()); |
-} |