OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" | 7 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" |
8 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" | 8 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" |
9 #include "core/fpdfdoc/doc_utils.h" | 9 #include "core/fpdfdoc/doc_utils.h" |
10 #include "core/fpdfdoc/include/fpdf_doc.h" | 10 #include "core/fpdfdoc/include/fpdf_doc.h" |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 | 85 |
86 m_pRoot = pNames->GetDictBy(category); | 86 m_pRoot = pNames->GetDictBy(category); |
87 } | 87 } |
88 | 88 |
89 static CPDF_Object* SearchNameNode(CPDF_Dictionary* pNode, | 89 static CPDF_Object* SearchNameNode(CPDF_Dictionary* pNode, |
90 const CFX_ByteString& csName, | 90 const CFX_ByteString& csName, |
91 size_t& nIndex, | 91 size_t& nIndex, |
92 CPDF_Array** ppFind, | 92 CPDF_Array** ppFind, |
93 int nLevel = 0) { | 93 int nLevel = 0) { |
94 if (nLevel > nMaxRecursion) { | 94 if (nLevel > nMaxRecursion) { |
95 return NULL; | 95 return nullptr; |
96 } | 96 } |
97 CPDF_Array* pLimits = pNode->GetArrayBy("Limits"); | 97 CPDF_Array* pLimits = pNode->GetArrayBy("Limits"); |
98 if (pLimits) { | 98 if (pLimits) { |
99 CFX_ByteString csLeft = pLimits->GetStringAt(0); | 99 CFX_ByteString csLeft = pLimits->GetStringAt(0); |
100 CFX_ByteString csRight = pLimits->GetStringAt(1); | 100 CFX_ByteString csRight = pLimits->GetStringAt(1); |
101 if (csLeft.Compare(csRight.AsStringC()) > 0) { | 101 if (csLeft.Compare(csRight.AsStringC()) > 0) { |
102 CFX_ByteString csTmp = csRight; | 102 CFX_ByteString csTmp = csRight; |
103 csRight = csLeft; | 103 csRight = csLeft; |
104 csLeft = csTmp; | 104 csLeft = csTmp; |
105 } | 105 } |
106 if (csName.Compare(csLeft.AsStringC()) < 0 || | 106 if (csName.Compare(csLeft.AsStringC()) < 0 || |
107 csName.Compare(csRight.AsStringC()) > 0) { | 107 csName.Compare(csRight.AsStringC()) > 0) { |
108 return NULL; | 108 return nullptr; |
109 } | 109 } |
110 } | 110 } |
111 CPDF_Array* pNames = pNode->GetArrayBy("Names"); | 111 CPDF_Array* pNames = pNode->GetArrayBy("Names"); |
112 if (pNames) { | 112 if (pNames) { |
113 size_t dwCount = pNames->GetCount() / 2; | 113 size_t dwCount = pNames->GetCount() / 2; |
114 for (size_t i = 0; i < dwCount; i++) { | 114 for (size_t i = 0; i < dwCount; i++) { |
115 CFX_ByteString csValue = pNames->GetStringAt(i * 2); | 115 CFX_ByteString csValue = pNames->GetStringAt(i * 2); |
116 int32_t iCompare = csValue.Compare(csName.AsStringC()); | 116 int32_t iCompare = csValue.Compare(csName.AsStringC()); |
117 if (iCompare <= 0) { | 117 if (iCompare <= 0) { |
118 if (ppFind) { | 118 if (ppFind) { |
119 *ppFind = pNames; | 119 *ppFind = pNames; |
120 } | 120 } |
121 if (iCompare < 0) { | 121 if (iCompare < 0) { |
122 continue; | 122 continue; |
123 } | 123 } |
124 } else { | 124 } else { |
125 break; | 125 break; |
126 } | 126 } |
127 nIndex += i; | 127 nIndex += i; |
128 return pNames->GetDirectObjectAt(i * 2 + 1); | 128 return pNames->GetDirectObjectAt(i * 2 + 1); |
129 } | 129 } |
130 nIndex += dwCount; | 130 nIndex += dwCount; |
131 return NULL; | 131 return nullptr; |
132 } | 132 } |
133 CPDF_Array* pKids = pNode->GetArrayBy("Kids"); | 133 CPDF_Array* pKids = pNode->GetArrayBy("Kids"); |
134 if (!pKids) { | 134 if (!pKids) { |
135 return NULL; | 135 return nullptr; |
136 } | 136 } |
137 for (size_t i = 0; i < pKids->GetCount(); i++) { | 137 for (size_t i = 0; i < pKids->GetCount(); i++) { |
138 CPDF_Dictionary* pKid = pKids->GetDictAt(i); | 138 CPDF_Dictionary* pKid = pKids->GetDictAt(i); |
139 if (!pKid) { | 139 if (!pKid) { |
140 continue; | 140 continue; |
141 } | 141 } |
142 CPDF_Object* pFound = | 142 CPDF_Object* pFound = |
143 SearchNameNode(pKid, csName, nIndex, ppFind, nLevel + 1); | 143 SearchNameNode(pKid, csName, nIndex, ppFind, nLevel + 1); |
144 if (pFound) { | 144 if (pFound) { |
145 return pFound; | 145 return pFound; |
146 } | 146 } |
147 } | 147 } |
148 return NULL; | 148 return nullptr; |
149 } | 149 } |
150 | 150 |
151 static CPDF_Object* SearchNameNode(CPDF_Dictionary* pNode, | 151 static CPDF_Object* SearchNameNode(CPDF_Dictionary* pNode, |
152 size_t nIndex, | 152 size_t nIndex, |
153 size_t& nCurIndex, | 153 size_t& nCurIndex, |
154 CFX_ByteString& csName, | 154 CFX_ByteString& csName, |
155 CPDF_Array** ppFind, | 155 CPDF_Array** ppFind, |
156 int nLevel = 0) { | 156 int nLevel = 0) { |
157 if (nLevel > nMaxRecursion) | 157 if (nLevel > nMaxRecursion) |
158 return NULL; | 158 return nullptr; |
159 | 159 |
160 CPDF_Array* pNames = pNode->GetArrayBy("Names"); | 160 CPDF_Array* pNames = pNode->GetArrayBy("Names"); |
161 if (pNames) { | 161 if (pNames) { |
162 size_t nCount = pNames->GetCount() / 2; | 162 size_t nCount = pNames->GetCount() / 2; |
163 if (nIndex >= nCurIndex + nCount) { | 163 if (nIndex >= nCurIndex + nCount) { |
164 nCurIndex += nCount; | 164 nCurIndex += nCount; |
165 return NULL; | 165 return nullptr; |
166 } | 166 } |
167 if (ppFind) | 167 if (ppFind) |
168 *ppFind = pNames; | 168 *ppFind = pNames; |
169 csName = pNames->GetStringAt((nIndex - nCurIndex) * 2); | 169 csName = pNames->GetStringAt((nIndex - nCurIndex) * 2); |
170 return pNames->GetDirectObjectAt((nIndex - nCurIndex) * 2 + 1); | 170 return pNames->GetDirectObjectAt((nIndex - nCurIndex) * 2 + 1); |
171 } | 171 } |
172 CPDF_Array* pKids = pNode->GetArrayBy("Kids"); | 172 CPDF_Array* pKids = pNode->GetArrayBy("Kids"); |
173 if (!pKids) | 173 if (!pKids) |
174 return NULL; | 174 return nullptr; |
175 for (size_t i = 0; i < pKids->GetCount(); i++) { | 175 for (size_t i = 0; i < pKids->GetCount(); i++) { |
176 CPDF_Dictionary* pKid = pKids->GetDictAt(i); | 176 CPDF_Dictionary* pKid = pKids->GetDictAt(i); |
177 if (!pKid) | 177 if (!pKid) |
178 continue; | 178 continue; |
179 CPDF_Object* pFound = | 179 CPDF_Object* pFound = |
180 SearchNameNode(pKid, nIndex, nCurIndex, csName, ppFind, nLevel + 1); | 180 SearchNameNode(pKid, nIndex, nCurIndex, csName, ppFind, nLevel + 1); |
181 if (pFound) | 181 if (pFound) |
182 return pFound; | 182 return pFound; |
183 } | 183 } |
184 return NULL; | 184 return nullptr; |
185 } | 185 } |
186 | 186 |
187 static size_t CountNames(CPDF_Dictionary* pNode, int nLevel = 0) { | 187 static size_t CountNames(CPDF_Dictionary* pNode, int nLevel = 0) { |
188 if (nLevel > nMaxRecursion) { | 188 if (nLevel > nMaxRecursion) { |
189 return 0; | 189 return 0; |
190 } | 190 } |
191 CPDF_Array* pNames = pNode->GetArrayBy("Names"); | 191 CPDF_Array* pNames = pNode->GetArrayBy("Names"); |
192 if (pNames) { | 192 if (pNames) { |
193 return pNames->GetCount() / 2; | 193 return pNames->GetCount() / 2; |
194 } | 194 } |
(...skipping 17 matching lines...) Expand all Loading... |
212 return 0; | 212 return 0; |
213 } | 213 } |
214 return ::CountNames(m_pRoot); | 214 return ::CountNames(m_pRoot); |
215 } | 215 } |
216 | 216 |
217 int CPDF_NameTree::GetIndex(const CFX_ByteString& csName) const { | 217 int CPDF_NameTree::GetIndex(const CFX_ByteString& csName) const { |
218 if (!m_pRoot) { | 218 if (!m_pRoot) { |
219 return -1; | 219 return -1; |
220 } | 220 } |
221 size_t nIndex = 0; | 221 size_t nIndex = 0; |
222 if (!SearchNameNode(m_pRoot, csName, nIndex, NULL)) { | 222 if (!SearchNameNode(m_pRoot, csName, nIndex, nullptr)) { |
223 return -1; | 223 return -1; |
224 } | 224 } |
225 return nIndex; | 225 return nIndex; |
226 } | 226 } |
227 CPDF_Object* CPDF_NameTree::LookupValue(int nIndex, | 227 CPDF_Object* CPDF_NameTree::LookupValue(int nIndex, |
228 CFX_ByteString& csName) const { | 228 CFX_ByteString& csName) const { |
229 if (!m_pRoot) { | 229 if (!m_pRoot) { |
230 return NULL; | 230 return nullptr; |
231 } | 231 } |
232 size_t nCurIndex = 0; | 232 size_t nCurIndex = 0; |
233 return SearchNameNode(m_pRoot, nIndex, nCurIndex, csName, NULL); | 233 return SearchNameNode(m_pRoot, nIndex, nCurIndex, csName, nullptr); |
234 } | 234 } |
235 CPDF_Object* CPDF_NameTree::LookupValue(const CFX_ByteString& csName) const { | 235 CPDF_Object* CPDF_NameTree::LookupValue(const CFX_ByteString& csName) const { |
236 if (!m_pRoot) { | 236 if (!m_pRoot) { |
237 return NULL; | 237 return nullptr; |
238 } | 238 } |
239 size_t nIndex = 0; | 239 size_t nIndex = 0; |
240 return SearchNameNode(m_pRoot, csName, nIndex, NULL); | 240 return SearchNameNode(m_pRoot, csName, nIndex, nullptr); |
241 } | 241 } |
242 CPDF_Array* CPDF_NameTree::LookupNamedDest(CPDF_Document* pDoc, | 242 CPDF_Array* CPDF_NameTree::LookupNamedDest(CPDF_Document* pDoc, |
243 const CFX_ByteString& sName) { | 243 const CFX_ByteString& sName) { |
244 CPDF_Object* pValue = LookupValue(sName); | 244 CPDF_Object* pValue = LookupValue(sName); |
245 if (!pValue) { | 245 if (!pValue) { |
246 CPDF_Dictionary* pDests = pDoc->GetRoot()->GetDictBy("Dests"); | 246 CPDF_Dictionary* pDests = pDoc->GetRoot()->GetDictBy("Dests"); |
247 if (!pDests) | 247 if (!pDests) |
248 return nullptr; | 248 return nullptr; |
249 pValue = pDests->GetDirectObjectBy(sName); | 249 pValue = pDests->GetDirectObjectBy(sName); |
250 } | 250 } |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 CFX_WideString wsLabel; | 467 CFX_WideString wsLabel; |
468 if (!m_pDocument) { | 468 if (!m_pDocument) { |
469 return wsLabel; | 469 return wsLabel; |
470 } | 470 } |
471 CPDF_Dictionary* pPDFRoot = m_pDocument->GetRoot(); | 471 CPDF_Dictionary* pPDFRoot = m_pDocument->GetRoot(); |
472 if (!pPDFRoot) { | 472 if (!pPDFRoot) { |
473 return wsLabel; | 473 return wsLabel; |
474 } | 474 } |
475 CPDF_Dictionary* pLabels = pPDFRoot->GetDictBy("PageLabels"); | 475 CPDF_Dictionary* pLabels = pPDFRoot->GetDictBy("PageLabels"); |
476 CPDF_NumberTree numberTree(pLabels); | 476 CPDF_NumberTree numberTree(pLabels); |
477 CPDF_Object* pValue = NULL; | 477 CPDF_Object* pValue = nullptr; |
478 int n = nPage; | 478 int n = nPage; |
479 while (n >= 0) { | 479 while (n >= 0) { |
480 pValue = numberTree.LookupValue(n); | 480 pValue = numberTree.LookupValue(n); |
481 if (pValue) { | 481 if (pValue) { |
482 break; | 482 break; |
483 } | 483 } |
484 n--; | 484 n--; |
485 } | 485 } |
486 if (pValue) { | 486 if (pValue) { |
487 pValue = pValue->GetDirect(); | 487 pValue = pValue->GetDirect(); |
488 if (CPDF_Dictionary* pLabel = pValue->AsDictionary()) { | 488 if (CPDF_Dictionary* pLabel = pValue->AsDictionary()) { |
489 if (pLabel->KeyExist("P")) { | 489 if (pLabel->KeyExist("P")) { |
490 wsLabel += pLabel->GetUnicodeTextBy("P"); | 490 wsLabel += pLabel->GetUnicodeTextBy("P"); |
491 } | 491 } |
492 CFX_ByteString bsNumberingStyle = pLabel->GetStringBy("S", nullptr); | 492 CFX_ByteString bsNumberingStyle = pLabel->GetStringBy("S", ""); |
493 int nLabelNum = nPage - n + pLabel->GetIntegerBy("St", 1); | 493 int nLabelNum = nPage - n + pLabel->GetIntegerBy("St", 1); |
494 CFX_WideString wsNumPortion = | 494 CFX_WideString wsNumPortion = |
495 _GetLabelNumPortion(nLabelNum, bsNumberingStyle); | 495 _GetLabelNumPortion(nLabelNum, bsNumberingStyle); |
496 wsLabel += wsNumPortion; | 496 wsLabel += wsNumPortion; |
497 return wsLabel; | 497 return wsLabel; |
498 } | 498 } |
499 } | 499 } |
500 wsLabel.Format(L"%d", nPage + 1); | 500 wsLabel.Format(L"%d", nPage + 1); |
501 return wsLabel; | 501 return wsLabel; |
502 } | 502 } |
(...skipping 12 matching lines...) Expand all Loading... |
515 return i; | 515 return i; |
516 } | 516 } |
517 | 517 |
518 int nPage = FXSYS_atoi(CFX_ByteString(bsLabel).c_str()); // NUL terminate. | 518 int nPage = FXSYS_atoi(CFX_ByteString(bsLabel).c_str()); // NUL terminate. |
519 return nPage > 0 && nPage <= nPages ? nPage : -1; | 519 return nPage > 0 && nPage <= nPages ? nPage : -1; |
520 } | 520 } |
521 | 521 |
522 int32_t CPDF_PageLabel::GetPageByLabel(const CFX_WideStringC& wsLabel) const { | 522 int32_t CPDF_PageLabel::GetPageByLabel(const CFX_WideStringC& wsLabel) const { |
523 return GetPageByLabel(PDF_EncodeText(wsLabel.c_str()).AsStringC()); | 523 return GetPageByLabel(PDF_EncodeText(wsLabel.c_str()).AsStringC()); |
524 } | 524 } |
OLD | NEW |