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 "../../include/fpdfapi/fpdf_parser.h" | 7 #include "../../include/fpdfapi/fpdf_parser.h" |
8 #include "../../include/fpdfapi/fpdf_page.h" | 8 #include "../../include/fpdfapi/fpdf_page.h" |
9 #include "../../include/fpdfdoc/fpdf_tagged.h" | 9 #include "../../include/fpdfdoc/fpdf_tagged.h" |
10 #include "tagged_int.h" | 10 #include "tagged_int.h" |
11 const int nMaxRecursion = 32; | 11 const int nMaxRecursion = 32; |
12 static FX_BOOL IsTagged(const CPDF_Document* pDoc) | 12 static bool IsTagged(const CPDF_Document* pDoc) |
13 { | 13 { |
14 CPDF_Dictionary* pCatalog = pDoc->GetRoot(); | 14 CPDF_Dictionary* pCatalog = pDoc->GetRoot(); |
15 CPDF_Dictionary* pMarkInfo = pCatalog->GetDict(FX_BSTRC("MarkInfo")); | 15 CPDF_Dictionary* pMarkInfo = pCatalog->GetDict(FX_BSTRC("MarkInfo")); |
16 return pMarkInfo != NULL && pMarkInfo->GetInteger(FX_BSTRC("Marked")); | 16 return pMarkInfo != NULL && pMarkInfo->GetInteger(FX_BSTRC("Marked")); |
17 } | 17 } |
18 CPDF_StructTree* CPDF_StructTree::LoadPage(const CPDF_Document* pDoc, const CPDF
_Dictionary* pPageDict) | 18 CPDF_StructTree* CPDF_StructTree::LoadPage(const CPDF_Document* pDoc, const CPDF
_Dictionary* pPageDict) |
19 { | 19 { |
20 if (!IsTagged(pDoc)) { | 20 if (!IsTagged(pDoc)) { |
21 return NULL; | 21 return NULL; |
22 } | 22 } |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 pElement = new CPDF_StructElementImpl(this, NULL, pDict); | 131 pElement = new CPDF_StructElementImpl(this, NULL, pDict); |
132 map.SetAt(pDict, pElement); | 132 map.SetAt(pDict, pElement); |
133 CPDF_Dictionary* pParent = pDict->GetDict(FX_BSTRC("P")); | 133 CPDF_Dictionary* pParent = pDict->GetDict(FX_BSTRC("P")); |
134 if (pParent == NULL || pParent->GetString(FX_BSTRC("Type")) == FX_BSTRC("Str
uctTreeRoot")) { | 134 if (pParent == NULL || pParent->GetString(FX_BSTRC("Type")) == FX_BSTRC("Str
uctTreeRoot")) { |
135 if (!AddTopLevelNode(pDict, pElement)) { | 135 if (!AddTopLevelNode(pDict, pElement)) { |
136 pElement->Release(); | 136 pElement->Release(); |
137 map.RemoveKey(pDict); | 137 map.RemoveKey(pDict); |
138 } | 138 } |
139 } else { | 139 } else { |
140 CPDF_StructElementImpl* pParentElement = AddPageNode(pParent, map, nLeve
l + 1); | 140 CPDF_StructElementImpl* pParentElement = AddPageNode(pParent, map, nLeve
l + 1); |
141 FX_BOOL bSave = FALSE; | 141 bool bSave = false; |
142 for (int i = 0; i < pParentElement->m_Kids.GetSize(); i ++) { | 142 for (int i = 0; i < pParentElement->m_Kids.GetSize(); i ++) { |
143 if (pParentElement->m_Kids[i].m_Type != CPDF_StructKid::Element) { | 143 if (pParentElement->m_Kids[i].m_Type != CPDF_StructKid::Element) { |
144 continue; | 144 continue; |
145 } | 145 } |
146 if (pParentElement->m_Kids[i].m_Element.m_pDict != pDict) { | 146 if (pParentElement->m_Kids[i].m_Element.m_pDict != pDict) { |
147 continue; | 147 continue; |
148 } | 148 } |
149 pParentElement->m_Kids[i].m_Element.m_pElement = pElement->Retain(); | 149 pParentElement->m_Kids[i].m_Element.m_pElement = pElement->Retain(); |
150 bSave = TRUE; | 150 bSave = true; |
151 } | 151 } |
152 if (!bSave) { | 152 if (!bSave) { |
153 pElement->Release(); | 153 pElement->Release(); |
154 map.RemoveKey(pDict); | 154 map.RemoveKey(pDict); |
155 } | 155 } |
156 } | 156 } |
157 return pElement; | 157 return pElement; |
158 } | 158 } |
159 FX_BOOL CPDF_StructTreeImpl::AddTopLevelNode(CPDF_Dictionary* pDict, CPDF_Struct
ElementImpl* pElement) | 159 bool CPDF_StructTreeImpl::AddTopLevelNode(CPDF_Dictionary* pDict, CPDF_StructEle
mentImpl* pElement) |
160 { | 160 { |
161 CPDF_Object *pObj = m_pTreeRoot->GetElementValue(FX_BSTRC("K")); | 161 CPDF_Object *pObj = m_pTreeRoot->GetElementValue(FX_BSTRC("K")); |
162 if (!pObj) { | 162 if (!pObj) { |
163 return FALSE; | 163 return false; |
164 } | 164 } |
165 if (pObj->GetType() == PDFOBJ_DICTIONARY) { | 165 if (pObj->GetType() == PDFOBJ_DICTIONARY) { |
166 if (pObj->GetObjNum() == pDict->GetObjNum()) { | 166 if (pObj->GetObjNum() == pDict->GetObjNum()) { |
167 if (m_Kids[0]) { | 167 if (m_Kids[0]) { |
168 m_Kids[0]->Release(); | 168 m_Kids[0]->Release(); |
169 } | 169 } |
170 m_Kids[0] = pElement->Retain(); | 170 m_Kids[0] = pElement->Retain(); |
171 } else { | 171 } else { |
172 return FALSE; | 172 return false; |
173 } | 173 } |
174 } | 174 } |
175 if (pObj->GetType() == PDFOBJ_ARRAY) { | 175 if (pObj->GetType() == PDFOBJ_ARRAY) { |
176 CPDF_Array* pTopKids = (CPDF_Array*)pObj; | 176 CPDF_Array* pTopKids = (CPDF_Array*)pObj; |
177 FX_DWORD i; | 177 FX_DWORD i; |
178 FX_BOOL bSave = FALSE; | 178 bool bSave = false; |
179 for (i = 0; i < pTopKids->GetCount(); i ++) { | 179 for (i = 0; i < pTopKids->GetCount(); i ++) { |
180 CPDF_Object* pKidRef = pTopKids->GetElement(i); | 180 CPDF_Object* pKidRef = pTopKids->GetElement(i); |
181 if (pKidRef == NULL || pKidRef->GetType() != PDFOBJ_REFERENCE) { | 181 if (pKidRef == NULL || pKidRef->GetType() != PDFOBJ_REFERENCE) { |
182 continue; | 182 continue; |
183 } | 183 } |
184 if (((CPDF_Reference*) pKidRef)->GetRefObjNum() != pDict->GetObjNum(
)) { | 184 if (((CPDF_Reference*) pKidRef)->GetRefObjNum() != pDict->GetObjNum(
)) { |
185 continue; | 185 continue; |
186 } | 186 } |
187 if (m_Kids[i]) { | 187 if (m_Kids[i]) { |
188 m_Kids[i]->Release(); | 188 m_Kids[i]->Release(); |
189 } | 189 } |
190 m_Kids[i] = pElement->Retain(); | 190 m_Kids[i] = pElement->Retain(); |
191 bSave = TRUE; | 191 bSave = true; |
192 } | 192 } |
193 if (!bSave) { | 193 if (!bSave) { |
194 return FALSE; | 194 return false; |
195 } | 195 } |
196 } | 196 } |
197 return TRUE; | 197 return true; |
198 } | 198 } |
199 CPDF_StructElementImpl::CPDF_StructElementImpl(CPDF_StructTreeImpl* pTree, CPDF_
StructElementImpl* pParent, CPDF_Dictionary* pDict) | 199 CPDF_StructElementImpl::CPDF_StructElementImpl(CPDF_StructTreeImpl* pTree, CPDF_
StructElementImpl* pParent, CPDF_Dictionary* pDict) |
200 : m_RefCount(0) | 200 : m_RefCount(0) |
201 { | 201 { |
202 m_pTree = pTree; | 202 m_pTree = pTree; |
203 m_pDict = pDict; | 203 m_pDict = pDict; |
204 m_Type = pDict->GetString(FX_BSTRC("S")); | 204 m_Type = pDict->GetString(FX_BSTRC("S")); |
205 if (pTree->m_pRoleMap) { | 205 if (pTree->m_pRoleMap) { |
206 CFX_ByteString mapped = pTree->m_pRoleMap->GetString(m_Type); | 206 CFX_ByteString mapped = pTree->m_pRoleMap->GetString(m_Type); |
207 if (!mapped.IsEmpty()) { | 207 if (!mapped.IsEmpty()) { |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 if (pDict) { | 333 if (pDict) { |
334 return pDict; | 334 return pDict; |
335 } | 335 } |
336 } | 336 } |
337 } | 337 } |
338 if (pDict && pDict->GetString(FX_BSTRC("O")) == owner) { | 338 if (pDict && pDict->GetString(FX_BSTRC("O")) == owner) { |
339 return pDict; | 339 return pDict; |
340 } | 340 } |
341 return NULL; | 341 return NULL; |
342 } | 342 } |
343 CPDF_Object* CPDF_StructElementImpl::GetAttr(const CFX_ByteStringC& owner, const
CFX_ByteStringC& name, FX_BOOL bInheritable, FX_FLOAT fLevel) | 343 CPDF_Object* CPDF_StructElementImpl::GetAttr(const CFX_ByteStringC& owner, const
CFX_ByteStringC& name, bool bInheritable, FX_FLOAT fLevel) |
344 { | 344 { |
345 if (fLevel > nMaxRecursion) { | 345 if (fLevel > nMaxRecursion) { |
346 return NULL; | 346 return NULL; |
347 } | 347 } |
348 if (bInheritable) { | 348 if (bInheritable) { |
349 CPDF_Object* pAttr = GetAttr(owner, name, FALSE); | 349 CPDF_Object* pAttr = GetAttr(owner, name, false); |
350 if (pAttr) { | 350 if (pAttr) { |
351 return pAttr; | 351 return pAttr; |
352 } | 352 } |
353 if (m_pParent == NULL) { | 353 if (m_pParent == NULL) { |
354 return NULL; | 354 return NULL; |
355 } | 355 } |
356 return m_pParent->GetAttr(owner, name, TRUE, fLevel + 1); | 356 return m_pParent->GetAttr(owner, name, true, fLevel + 1); |
357 } | 357 } |
358 CPDF_Object* pA = m_pDict->GetElementValue(FX_BSTRC("A")); | 358 CPDF_Object* pA = m_pDict->GetElementValue(FX_BSTRC("A")); |
359 if (pA) { | 359 if (pA) { |
360 CPDF_Dictionary* pAttrDict = FindAttrDict(pA, owner); | 360 CPDF_Dictionary* pAttrDict = FindAttrDict(pA, owner); |
361 if (pAttrDict) { | 361 if (pAttrDict) { |
362 CPDF_Object* pAttr = pAttrDict->GetElementValue(name); | 362 CPDF_Object* pAttr = pAttrDict->GetElementValue(name); |
363 if (pAttr) { | 363 if (pAttr) { |
364 return pAttr; | 364 return pAttr; |
365 } | 365 } |
366 } | 366 } |
(...skipping 17 matching lines...) Expand all Loading... |
384 } | 384 } |
385 return NULL; | 385 return NULL; |
386 } | 386 } |
387 CFX_ByteString class_name = pC->GetString(); | 387 CFX_ByteString class_name = pC->GetString(); |
388 CPDF_Dictionary* pClassDict = pClassMap->GetDict(class_name); | 388 CPDF_Dictionary* pClassDict = pClassMap->GetDict(class_name); |
389 if (pClassDict && pClassDict->GetString(FX_BSTRC("O")) == owner) { | 389 if (pClassDict && pClassDict->GetString(FX_BSTRC("O")) == owner) { |
390 return pClassDict->GetElementValue(name); | 390 return pClassDict->GetElementValue(name); |
391 } | 391 } |
392 return NULL; | 392 return NULL; |
393 } | 393 } |
394 CPDF_Object* CPDF_StructElementImpl::GetAttr(const CFX_ByteStringC& owner, const
CFX_ByteStringC& name, FX_BOOL bInheritable, int subindex) | 394 CPDF_Object* CPDF_StructElementImpl::GetAttr(const CFX_ByteStringC& owner, const
CFX_ByteStringC& name, bool bInheritable, int subindex) |
395 { | 395 { |
396 CPDF_Object* pAttr = GetAttr(owner, name, bInheritable); | 396 CPDF_Object* pAttr = GetAttr(owner, name, bInheritable); |
397 if (pAttr == NULL || subindex == -1 || pAttr->GetType() != PDFOBJ_ARRAY) { | 397 if (pAttr == NULL || subindex == -1 || pAttr->GetType() != PDFOBJ_ARRAY) { |
398 return pAttr; | 398 return pAttr; |
399 } | 399 } |
400 CPDF_Array* pArray = (CPDF_Array*)pAttr; | 400 CPDF_Array* pArray = (CPDF_Array*)pAttr; |
401 if (subindex >= (int)pArray->GetCount()) { | 401 if (subindex >= (int)pArray->GetCount()) { |
402 return pAttr; | 402 return pAttr; |
403 } | 403 } |
404 return pArray->GetElementValue(subindex); | 404 return pArray->GetElementValue(subindex); |
405 } | 405 } |
406 CFX_ByteString CPDF_StructElementImpl::GetName(const CFX_ByteStringC& owner, con
st CFX_ByteStringC& name, const CFX_ByteStringC& default_value, FX_BOOL bInherit
able, int subindex) | 406 CFX_ByteString CPDF_StructElementImpl::GetName(const CFX_ByteStringC& owner, con
st CFX_ByteStringC& name, const CFX_ByteStringC& default_value, bool bInheritabl
e, int subindex) |
407 { | 407 { |
408 CPDF_Object* pAttr = GetAttr(owner, name, bInheritable, subindex); | 408 CPDF_Object* pAttr = GetAttr(owner, name, bInheritable, subindex); |
409 if (pAttr == NULL || pAttr->GetType() != PDFOBJ_NAME) { | 409 if (pAttr == NULL || pAttr->GetType() != PDFOBJ_NAME) { |
410 return default_value; | 410 return default_value; |
411 } | 411 } |
412 return pAttr->GetString(); | 412 return pAttr->GetString(); |
413 } | 413 } |
414 FX_ARGB»CPDF_StructElementImpl::GetColor(const CFX_ByteStringC& owner, const CFX
_ByteStringC& name, FX_ARGB default_value, FX_BOOL bInheritable, int subindex) | 414 FX_ARGB»CPDF_StructElementImpl::GetColor(const CFX_ByteStringC& owner, const CFX
_ByteStringC& name, FX_ARGB default_value, bool bInheritable, int subindex) |
415 { | 415 { |
416 CPDF_Object* pAttr = GetAttr(owner, name, bInheritable, subindex); | 416 CPDF_Object* pAttr = GetAttr(owner, name, bInheritable, subindex); |
417 if (pAttr == NULL || pAttr->GetType() != PDFOBJ_ARRAY) { | 417 if (pAttr == NULL || pAttr->GetType() != PDFOBJ_ARRAY) { |
418 return default_value; | 418 return default_value; |
419 } | 419 } |
420 CPDF_Array* pArray = (CPDF_Array*)pAttr; | 420 CPDF_Array* pArray = (CPDF_Array*)pAttr; |
421 return 0xff000000 | ((int)(pArray->GetNumber(0) * 255) << 16) | ((int)(pArra
y->GetNumber(1) * 255) << 8) | (int)(pArray->GetNumber(2) * 255); | 421 return 0xff000000 | ((int)(pArray->GetNumber(0) * 255) << 16) | ((int)(pArra
y->GetNumber(1) * 255) << 8) | (int)(pArray->GetNumber(2) * 255); |
422 } | 422 } |
423 FX_FLOAT CPDF_StructElementImpl::GetNumber(const CFX_ByteStringC& owner, const C
FX_ByteStringC& name, FX_FLOAT default_value, FX_BOOL bInheritable, int subindex
) | 423 FX_FLOAT CPDF_StructElementImpl::GetNumber(const CFX_ByteStringC& owner, const C
FX_ByteStringC& name, FX_FLOAT default_value, bool bInheritable, int subindex) |
424 { | 424 { |
425 CPDF_Object* pAttr = GetAttr(owner, name, bInheritable, subindex); | 425 CPDF_Object* pAttr = GetAttr(owner, name, bInheritable, subindex); |
426 if (pAttr == NULL || pAttr->GetType() != PDFOBJ_NUMBER) { | 426 if (pAttr == NULL || pAttr->GetType() != PDFOBJ_NUMBER) { |
427 return default_value; | 427 return default_value; |
428 } | 428 } |
429 return pAttr->GetNumber(); | 429 return pAttr->GetNumber(); |
430 } | 430 } |
431 int» CPDF_StructElementImpl::GetInteger(const CFX_ByteStringC& owner, const C
FX_ByteStringC& name, int default_value, FX_BOOL bInheritable, int subindex) | 431 int» CPDF_StructElementImpl::GetInteger(const CFX_ByteStringC& owner, const C
FX_ByteStringC& name, int default_value, bool bInheritable, int subindex) |
432 { | 432 { |
433 CPDF_Object* pAttr = GetAttr(owner, name, bInheritable, subindex); | 433 CPDF_Object* pAttr = GetAttr(owner, name, bInheritable, subindex); |
434 if (pAttr == NULL || pAttr->GetType() != PDFOBJ_NUMBER) { | 434 if (pAttr == NULL || pAttr->GetType() != PDFOBJ_NUMBER) { |
435 return default_value; | 435 return default_value; |
436 } | 436 } |
437 return pAttr->GetInteger(); | 437 return pAttr->GetInteger(); |
438 } | 438 } |
OLD | NEW |