Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: core/fpdfdoc/doc_ocg.cpp

Issue 2187073005: Splitting fpdfdoc/doc_* part II. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@fpdf_doc_III
Patch Set: Rebase to master Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « core/fpdfdoc/doc_basic_unittest.cpp ('k') | core/fpdfdoc/doc_vt.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 PDFium Authors. All rights reserved.
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/fpdfdoc/include/cpdf_occontext.h"
8
9 #include "core/fpdfapi/fpdf_page/cpdf_contentmarkdata.h"
10 #include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h"
11 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
12 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
13
14 namespace {
15
16 int32_t FPDFDOC_OCG_FindGroup(const CPDF_Array* pArray,
17 const CPDF_Dictionary* pGroupDict) {
18 if (!pArray || !pGroupDict)
19 return -1;
20
21 for (size_t i = 0; i < pArray->GetCount(); i++) {
22 if (pArray->GetDictAt(i) == pGroupDict)
23 return i;
24 }
25 return -1;
26 }
27
28 bool FPDFDOC_OCG_HasIntent(const CPDF_Dictionary* pDict,
29 const CFX_ByteStringC& csElement,
30 const CFX_ByteStringC& csDef) {
31 CPDF_Object* pIntent = pDict->GetDirectObjectBy("Intent");
32 if (!pIntent)
33 return csElement == csDef;
34
35 CFX_ByteString bsIntent;
36 if (CPDF_Array* pArray = pIntent->AsArray()) {
37 for (size_t i = 0; i < pArray->GetCount(); i++) {
38 bsIntent = pArray->GetStringAt(i);
39 if (bsIntent == "All" || bsIntent == csElement)
40 return true;
41 }
42 return false;
43 }
44 bsIntent = pIntent->GetString();
45 return bsIntent == "All" || bsIntent == csElement;
46 }
47
48 CPDF_Dictionary* FPDFDOC_OCG_GetConfig(CPDF_Document* pDoc,
49 const CPDF_Dictionary* pOCGDict) {
50 ASSERT(pOCGDict);
51 CPDF_Dictionary* pOCProperties = pDoc->GetRoot()->GetDictBy("OCProperties");
52 if (!pOCProperties)
53 return nullptr;
54
55 CPDF_Array* pOCGs = pOCProperties->GetArrayBy("OCGs");
56 if (!pOCGs)
57 return nullptr;
58
59 if (FPDFDOC_OCG_FindGroup(pOCGs, pOCGDict) < 0)
60 return nullptr;
61
62 CPDF_Dictionary* pConfig = pOCProperties->GetDictBy("D");
63 CPDF_Array* pConfigs = pOCProperties->GetArrayBy("Configs");
64 if (!pConfigs)
65 return pConfig;
66
67 for (size_t i = 0; i < pConfigs->GetCount(); i++) {
68 CPDF_Dictionary* pFind = pConfigs->GetDictAt(i);
69 if (pFind && FPDFDOC_OCG_HasIntent(pFind, "View", "View"))
70 return pFind;
71 }
72 return pConfig;
73 }
74
75 CFX_ByteString FPDFDOC_OCG_GetUsageTypeString(CPDF_OCContext::UsageType eType) {
76 CFX_ByteString csState;
77 switch (eType) {
78 case CPDF_OCContext::Design:
79 csState = "Design";
80 break;
81 case CPDF_OCContext::Print:
82 csState = "Print";
83 break;
84 case CPDF_OCContext::Export:
85 csState = "Export";
86 break;
87 default:
88 csState = "View";
89 break;
90 }
91 return csState;
92 }
93
94 } // namespace
95
96 CPDF_OCContext::CPDF_OCContext(CPDF_Document* pDoc, UsageType eUsageType)
97 : m_pDocument(pDoc), m_eUsageType(eUsageType) {
98 ASSERT(pDoc);
99 }
100
101 CPDF_OCContext::~CPDF_OCContext() {
102 }
103
104 bool CPDF_OCContext::LoadOCGStateFromConfig(
105 const CFX_ByteString& csConfig,
106 const CPDF_Dictionary* pOCGDict) const {
107 CPDF_Dictionary* pConfig = FPDFDOC_OCG_GetConfig(m_pDocument, pOCGDict);
108 if (!pConfig)
109 return true;
110
111 bool bState = pConfig->GetStringBy("BaseState", "ON") != "OFF";
112 CPDF_Array* pArray = pConfig->GetArrayBy("ON");
113 if (pArray) {
114 if (FPDFDOC_OCG_FindGroup(pArray, pOCGDict) >= 0)
115 bState = true;
116 }
117 pArray = pConfig->GetArrayBy("OFF");
118 if (pArray) {
119 if (FPDFDOC_OCG_FindGroup(pArray, pOCGDict) >= 0)
120 bState = false;
121 }
122 pArray = pConfig->GetArrayBy("AS");
123 if (!pArray)
124 return bState;
125
126 CFX_ByteString csFind = csConfig + "State";
127 for (size_t i = 0; i < pArray->GetCount(); i++) {
128 CPDF_Dictionary* pUsage = pArray->GetDictAt(i);
129 if (!pUsage)
130 continue;
131
132 if (pUsage->GetStringBy("Event", "View") != csConfig)
133 continue;
134
135 CPDF_Array* pOCGs = pUsage->GetArrayBy("OCGs");
136 if (!pOCGs)
137 continue;
138
139 if (FPDFDOC_OCG_FindGroup(pOCGs, pOCGDict) < 0)
140 continue;
141
142 CPDF_Dictionary* pState = pUsage->GetDictBy(csConfig);
143 if (!pState)
144 continue;
145
146 bState = pState->GetStringBy(csFind) != "OFF";
147 }
148 return bState;
149 }
150
151 bool CPDF_OCContext::LoadOCGState(const CPDF_Dictionary* pOCGDict) const {
152 if (!FPDFDOC_OCG_HasIntent(pOCGDict, "View", "View"))
153 return true;
154
155 CFX_ByteString csState = FPDFDOC_OCG_GetUsageTypeString(m_eUsageType);
156 CPDF_Dictionary* pUsage = pOCGDict->GetDictBy("Usage");
157 if (pUsage) {
158 CPDF_Dictionary* pState = pUsage->GetDictBy(csState);
159 if (pState) {
160 CFX_ByteString csFind = csState + "State";
161 if (pState->KeyExist(csFind)) {
162 return pState->GetStringBy(csFind) != "OFF";
163 }
164 }
165 if (csState != "View") {
166 pState = pUsage->GetDictBy("View");
167 if (pState && pState->KeyExist("ViewState")) {
168 return pState->GetStringBy("ViewState") != "OFF";
169 }
170 }
171 }
172 return LoadOCGStateFromConfig(csState, pOCGDict);
173 }
174
175 bool CPDF_OCContext::GetOCGVisible(const CPDF_Dictionary* pOCGDict) {
176 if (!pOCGDict)
177 return false;
178
179 const auto it = m_OCGStates.find(pOCGDict);
180 if (it != m_OCGStates.end())
181 return it->second;
182
183 bool bState = LoadOCGState(pOCGDict);
184 m_OCGStates[pOCGDict] = bState;
185 return bState;
186 }
187
188 bool CPDF_OCContext::CheckObjectVisible(const CPDF_PageObject* pObj) {
189 const CPDF_ContentMarkData* pData = pObj->m_ContentMark.GetObject();
190 for (int i = 0; i < pData->CountItems(); i++) {
191 const CPDF_ContentMarkItem& item = pData->GetItem(i);
192 if (item.GetName() == "OC" &&
193 item.GetParamType() == CPDF_ContentMarkItem::PropertiesDict &&
194 !CheckOCGVisible(item.GetParam())) {
195 return false;
196 }
197 }
198 return true;
199 }
200
201 bool CPDF_OCContext::GetOCGVE(CPDF_Array* pExpression, int nLevel) {
202 if (nLevel > 32 || !pExpression)
203 return false;
204
205 CFX_ByteString csOperator = pExpression->GetStringAt(0);
206 if (csOperator == "Not") {
207 CPDF_Object* pOCGObj = pExpression->GetDirectObjectAt(1);
208 if (!pOCGObj)
209 return false;
210 if (CPDF_Dictionary* pDict = pOCGObj->AsDictionary())
211 return !GetOCGVisible(pDict);
212 if (CPDF_Array* pArray = pOCGObj->AsArray())
213 return !GetOCGVE(pArray, nLevel + 1);
214 return false;
215 }
216
217 if (csOperator != "Or" && csOperator != "And")
218 return false;
219
220 bool bValue = false;
221 for (size_t i = 1; i < pExpression->GetCount(); i++) {
222 CPDF_Object* pOCGObj = pExpression->GetDirectObjectAt(1);
223 if (!pOCGObj)
224 continue;
225
226 bool bItem = false;
227 if (CPDF_Dictionary* pDict = pOCGObj->AsDictionary())
228 bItem = GetOCGVisible(pDict);
229 else if (CPDF_Array* pArray = pOCGObj->AsArray())
230 bItem = GetOCGVE(pArray, nLevel + 1);
231
232 if (i == 1) {
233 bValue = bItem;
234 } else {
235 if (csOperator == "Or") {
236 bValue = bValue || bItem;
237 } else {
238 bValue = bValue && bItem;
239 }
240 }
241 }
242 return bValue;
243 }
244
245 bool CPDF_OCContext::LoadOCMDState(const CPDF_Dictionary* pOCMDDict) {
246 CPDF_Array* pVE = pOCMDDict->GetArrayBy("VE");
247 if (pVE)
248 return GetOCGVE(pVE, 0);
249
250 CFX_ByteString csP = pOCMDDict->GetStringBy("P", "AnyOn");
251 CPDF_Object* pOCGObj = pOCMDDict->GetDirectObjectBy("OCGs");
252 if (!pOCGObj)
253 return true;
254
255 if (const CPDF_Dictionary* pDict = pOCGObj->AsDictionary())
256 return GetOCGVisible(pDict);
257
258 CPDF_Array* pArray = pOCGObj->AsArray();
259 if (!pArray)
260 return true;
261
262 bool bState = (csP == "AllOn" || csP == "AllOff");
263 for (size_t i = 0; i < pArray->GetCount(); i++) {
264 bool bItem = true;
265 CPDF_Dictionary* pItemDict = pArray->GetDictAt(i);
266 if (pItemDict)
267 bItem = GetOCGVisible(pItemDict);
268
269 if ((csP == "AnyOn" && bItem) || (csP == "AnyOff" && !bItem))
270 return true;
271 if ((csP == "AllOn" && !bItem) || (csP == "AllOff" && bItem))
272 return false;
273 }
274 return bState;
275 }
276
277 bool CPDF_OCContext::CheckOCGVisible(const CPDF_Dictionary* pOCGDict) {
278 if (!pOCGDict)
279 return true;
280
281 CFX_ByteString csType = pOCGDict->GetStringBy("Type", "OCG");
282 if (csType == "OCG")
283 return GetOCGVisible(pOCGDict);
284 return LoadOCMDState(pOCGDict);
285 }
OLDNEW
« no previous file with comments | « core/fpdfdoc/doc_basic_unittest.cpp ('k') | core/fpdfdoc/doc_vt.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698