7#include "core/fpdfdoc/cpdf_structelement.h"
11#include "core/fpdfapi/parser/cpdf_array.h"
12#include "core/fpdfapi/parser/cpdf_dictionary.h"
13#include "core/fpdfapi/parser/cpdf_name.h"
14#include "core/fpdfapi/parser/cpdf_number.h"
15#include "core/fpdfapi/parser/cpdf_object.h"
16#include "core/fpdfapi/parser/cpdf_reference.h"
17#include "core/fpdfapi/parser/cpdf_stream.h"
18#include "core/fpdfdoc/cpdf_structtree.h"
19#include "third_party/base/check.h"
21CPDF_StructElement::Kid::Kid() =
default;
23CPDF_StructElement::Kid::Kid(
const Kid& that) =
default;
25CPDF_StructElement::Kid::~Kid() =
default;
30 m_pDict(std::move(pDict)),
31 m_Type(m_pTree->GetRoleMapNameFor(m_pDict->GetNameFor(
"S"))) {
36 for (
auto& kid : m_Kids) {
37 if (kid.m_Type == Kid::kElement && kid.m_pElement) {
38 kid.m_pElement->SetParent(
nullptr);
44 return m_pDict->GetByteStringFor(
"Type");
48 return m_pDict->GetUnicodeTextFor(
"Alt");
52 return m_pDict->GetUnicodeTextFor(
"ActualText");
55WideString CPDF_StructElement::
GetTitle()
const {
56 return m_pDict->GetUnicodeTextFor(
"T");
61 if (!obj || !obj->IsString())
63 return obj->GetUnicodeText();
68 if (!obj || !obj->IsString())
70 return obj->GetUnicodeText();
74 return m_pDict->GetObjectFor(
"A");
78 return m_pDict->GetObjectFor(
"K");
86 return m_Kids[index].m_Type == Kid::kElement ? m_Kids[index].m_pElement.Get()
91 return m_Kids[index].m_Type == Kid::kStreamContent ||
92 m_Kids[index].m_Type == Kid::kPageContent
93 ? m_Kids[index].m_ContentId
98 CPDF_StructElement* pElement) {
100 for (
auto& kid : m_Kids) {
101 if (kid.m_Type == Kid::kElement && kid.m_pDict == pDict) {
102 kid.m_pElement.Reset(pElement);
109void CPDF_StructElement::LoadKids() {
111 const CPDF_Reference* pRef = ToReference(pObj.Get());
117 DCHECK(m_Kids.empty());
118 if (
const CPDF_Array* pArray = pKids->AsArray()) {
119 m_Kids.resize(pArray->size());
120 for (size_t i = 0; i < pArray->size(); ++i) {
121 LoadKid(page_obj_num, pArray->GetDirectObjectAt(i), m_Kids[i]);
127 LoadKid(page_obj_num, std::move(pKids), m_Kids[0]);
130void CPDF_StructElement::LoadKid(uint32_t page_obj_num,
136 if (pKidObj->IsNumber()) {
137 if (m_pTree->GetPageObjNum() != page_obj_num) {
141 kid.m_Type = Kid::kPageContent;
142 kid.m_ContentId = pKidObj->GetInteger();
143 kid.m_PageObjNum = page_obj_num;
147 const CPDF_Dictionary* pKidDict = pKidObj->AsDictionary();
151 if (RetainPtr<
const CPDF_Reference> pRef =
152 ToReference(pKidDict->GetObjectFor(
"Pg"))) {
153 page_obj_num = pRef->GetRefObjNum();
156 if ((type ==
"MCR" || type ==
"OBJR") &&
157 m_pTree->GetPageObjNum() != page_obj_num) {
162 kid.m_Type = Kid::kStreamContent;
164 ToReference(pKidDict->GetObjectFor(
"Stm"));
165 kid.m_RefObjNum = pRef ? pRef->GetRefObjNum() : 0;
166 kid.m_PageObjNum = page_obj_num;
171 if (type
== "OBJR") {
172 kid.m_Type = Kid::kObject;
174 ToReference(pKidDict->GetObjectFor(
"Obj"));
175 kid.m_RefObjNum = pObj ? pObj->GetRefObjNum() : 0;
176 kid.m_PageObjNum = page_obj_num;
180 kid.m_Type = Kid::kElement;
181 kid.m_pDict.Reset(pKidDict);
int GetIntegerFor(const ByteString &key) const
ByteString GetNameFor(const ByteString &key) const
uint32_t GetRefObjNum() const
~CPDF_StructElement() override
int GetKidContentId(size_t index) const
absl::optional< WideString > GetID() const
bool UpdateKidIfElement(const CPDF_Dictionary *pDict, CPDF_StructElement *pElement)
RetainPtr< const CPDF_Object > GetK() const
WideString GetTitle() const
absl::optional< WideString > GetLang() const
CPDF_StructElement * GetKidIfElement(size_t index) const
WideString GetActualText() const
ByteString GetObjType() const
WideString GetAltText() const
RetainPtr< const CPDF_Object > GetA() const
bool operator==(const char *ptr) const