xref: /aosp_15_r20/external/pdfium/core/fpdfapi/page/cpdf_contentmarks.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2016 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #include "core/fpdfapi/page/cpdf_contentmarks.h"
8 
9 #include <algorithm>
10 #include <utility>
11 
12 #include "core/fpdfapi/parser/cpdf_dictionary.h"
13 #include "third_party/base/check_op.h"
14 
15 CPDF_ContentMarks::CPDF_ContentMarks() = default;
16 
17 CPDF_ContentMarks::~CPDF_ContentMarks() = default;
18 
Clone()19 std::unique_ptr<CPDF_ContentMarks> CPDF_ContentMarks::Clone() {
20   auto result = std::make_unique<CPDF_ContentMarks>();
21   if (m_pMarkData)
22     result->m_pMarkData = pdfium::MakeRetain<MarkData>(*m_pMarkData);
23   return result;
24 }
25 
CountItems() const26 size_t CPDF_ContentMarks::CountItems() const {
27   return m_pMarkData ? m_pMarkData->CountItems() : 0;
28 }
29 
ContainsItem(const CPDF_ContentMarkItem * pItem) const30 bool CPDF_ContentMarks::ContainsItem(const CPDF_ContentMarkItem* pItem) const {
31   return m_pMarkData && m_pMarkData->ContainsItem(pItem);
32 }
33 
GetItem(size_t index)34 CPDF_ContentMarkItem* CPDF_ContentMarks::GetItem(size_t index) {
35   return m_pMarkData->GetItem(index);
36 }
37 
GetItem(size_t index) const38 const CPDF_ContentMarkItem* CPDF_ContentMarks::GetItem(size_t index) const {
39   return m_pMarkData->GetItem(index);
40 }
41 
GetMarkedContentID() const42 int CPDF_ContentMarks::GetMarkedContentID() const {
43   return m_pMarkData ? m_pMarkData->GetMarkedContentID() : -1;
44 }
45 
AddMark(ByteString name)46 void CPDF_ContentMarks::AddMark(ByteString name) {
47   EnsureMarkDataExists();
48   m_pMarkData->AddMark(std::move(name));
49 }
50 
AddMarkWithDirectDict(ByteString name,RetainPtr<CPDF_Dictionary> pDict)51 void CPDF_ContentMarks::AddMarkWithDirectDict(
52     ByteString name,
53     RetainPtr<CPDF_Dictionary> pDict) {
54   EnsureMarkDataExists();
55   m_pMarkData->AddMarkWithDirectDict(std::move(name), std::move(pDict));
56 }
57 
AddMarkWithPropertiesHolder(const ByteString & name,RetainPtr<CPDF_Dictionary> pDict,const ByteString & property_name)58 void CPDF_ContentMarks::AddMarkWithPropertiesHolder(
59     const ByteString& name,
60     RetainPtr<CPDF_Dictionary> pDict,
61     const ByteString& property_name) {
62   EnsureMarkDataExists();
63   m_pMarkData->AddMarkWithPropertiesHolder(name, std::move(pDict),
64                                            property_name);
65 }
66 
RemoveMark(CPDF_ContentMarkItem * pMarkItem)67 bool CPDF_ContentMarks::RemoveMark(CPDF_ContentMarkItem* pMarkItem) {
68   return m_pMarkData && m_pMarkData->RemoveMark(pMarkItem);
69 }
70 
EnsureMarkDataExists()71 void CPDF_ContentMarks::EnsureMarkDataExists() {
72   if (!m_pMarkData)
73     m_pMarkData = pdfium::MakeRetain<MarkData>();
74 }
75 
FindFirstDifference(const CPDF_ContentMarks * other) const76 size_t CPDF_ContentMarks::FindFirstDifference(
77     const CPDF_ContentMarks* other) const {
78   if (m_pMarkData == other->m_pMarkData)
79     return CountItems();
80 
81   size_t min_len = std::min(CountItems(), other->CountItems());
82 
83   for (size_t i = 0; i < min_len; ++i) {
84     if (GetItem(i) != other->GetItem(i))
85       return i;
86   }
87   return min_len;
88 }
89 
90 CPDF_ContentMarks::MarkData::MarkData() = default;
91 
MarkData(const MarkData & src)92 CPDF_ContentMarks::MarkData::MarkData(const MarkData& src)
93     : m_Marks(src.m_Marks) {}
94 
95 CPDF_ContentMarks::MarkData::~MarkData() = default;
96 
CountItems() const97 size_t CPDF_ContentMarks::MarkData::CountItems() const {
98   return m_Marks.size();
99 }
100 
ContainsItem(const CPDF_ContentMarkItem * pItem) const101 bool CPDF_ContentMarks::MarkData::ContainsItem(
102     const CPDF_ContentMarkItem* pItem) const {
103   for (const auto& pMark : m_Marks) {
104     if (pMark == pItem)
105       return true;
106   }
107   return false;
108 }
109 
GetItem(size_t index)110 CPDF_ContentMarkItem* CPDF_ContentMarks::MarkData::GetItem(size_t index) {
111   CHECK_LT(index, m_Marks.size());
112   return m_Marks[index].Get();
113 }
114 
GetItem(size_t index) const115 const CPDF_ContentMarkItem* CPDF_ContentMarks::MarkData::GetItem(
116     size_t index) const {
117   CHECK_LT(index, m_Marks.size());
118   return m_Marks[index].Get();
119 }
120 
GetMarkedContentID() const121 int CPDF_ContentMarks::MarkData::GetMarkedContentID() const {
122   for (const auto& pMark : m_Marks) {
123     RetainPtr<const CPDF_Dictionary> pDict = pMark->GetParam();
124     if (pDict && pDict->KeyExist("MCID"))
125       return pDict->GetIntegerFor("MCID");
126   }
127   return -1;
128 }
129 
AddMark(ByteString name)130 void CPDF_ContentMarks::MarkData::AddMark(ByteString name) {
131   auto pItem = pdfium::MakeRetain<CPDF_ContentMarkItem>(std::move(name));
132   m_Marks.push_back(pItem);
133 }
134 
AddMarkWithDirectDict(ByteString name,RetainPtr<CPDF_Dictionary> pDict)135 void CPDF_ContentMarks::MarkData::AddMarkWithDirectDict(
136     ByteString name,
137     RetainPtr<CPDF_Dictionary> pDict) {
138   auto pItem = pdfium::MakeRetain<CPDF_ContentMarkItem>(std::move(name));
139   pItem->SetDirectDict(ToDictionary(pDict->Clone()));
140   m_Marks.push_back(pItem);
141 }
142 
AddMarkWithPropertiesHolder(const ByteString & name,RetainPtr<CPDF_Dictionary> pDict,const ByteString & property_name)143 void CPDF_ContentMarks::MarkData::AddMarkWithPropertiesHolder(
144     const ByteString& name,
145     RetainPtr<CPDF_Dictionary> pDict,
146     const ByteString& property_name) {
147   auto pItem = pdfium::MakeRetain<CPDF_ContentMarkItem>(name);
148   pItem->SetPropertiesHolder(std::move(pDict), property_name);
149   m_Marks.push_back(std::move(pItem));
150 }
151 
RemoveMark(CPDF_ContentMarkItem * pMarkItem)152 bool CPDF_ContentMarks::MarkData::RemoveMark(CPDF_ContentMarkItem* pMarkItem) {
153   for (auto it = m_Marks.begin(); it != m_Marks.end(); ++it) {
154     if (*it == pMarkItem) {
155       m_Marks.erase(it);
156       return true;
157     }
158   }
159   return false;
160 }
161