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/include/fpdf_doc.h" | 9 #include "core/fpdfdoc/include/fpdf_doc.h" |
10 | 10 |
11 static int32_t FPDFDOC_OCG_FindGroup(const CPDF_Object* pObject, | 11 static int32_t FPDFDOC_OCG_FindGroup(const CPDF_Object* pObject, |
12 const CPDF_Dictionary* pGroupDict) { | 12 const CPDF_Dictionary* pGroupDict) { |
13 if (!pObject || !pGroupDict) | 13 if (!pObject || !pGroupDict) |
14 return -1; | 14 return -1; |
15 | 15 |
16 if (const CPDF_Array* pArray = pObject->AsArray()) { | 16 if (const CPDF_Array* pArray = pObject->AsArray()) { |
17 uint32_t dwCount = pArray->GetCount(); | 17 for (size_t i = 0; i < pArray->GetCount(); i++) { |
18 for (uint32_t i = 0; i < dwCount; i++) { | |
19 if (pArray->GetDictAt(i) == pGroupDict) | 18 if (pArray->GetDictAt(i) == pGroupDict) |
20 return i; | 19 return i; |
21 } | 20 } |
22 return -1; | 21 return -1; |
23 } | 22 } |
24 return pObject->GetDict() == pGroupDict ? 0 : -1; | 23 return pObject->GetDict() == pGroupDict ? 0 : -1; |
25 } | 24 } |
26 static FX_BOOL FPDFDOC_OCG_HasIntent(const CPDF_Dictionary* pDict, | 25 static FX_BOOL FPDFDOC_OCG_HasIntent(const CPDF_Dictionary* pDict, |
27 const CFX_ByteStringC& csElement, | 26 const CFX_ByteStringC& csElement, |
28 const CFX_ByteStringC& csDef = "") { | 27 const CFX_ByteStringC& csDef = "") { |
29 CPDF_Object* pIntent = pDict->GetDirectObjectBy("Intent"); | 28 CPDF_Object* pIntent = pDict->GetDirectObjectBy("Intent"); |
30 if (!pIntent) { | 29 if (!pIntent) { |
31 return csElement == csDef; | 30 return csElement == csDef; |
32 } | 31 } |
33 CFX_ByteString bsIntent; | 32 CFX_ByteString bsIntent; |
34 if (CPDF_Array* pArray = pIntent->AsArray()) { | 33 if (CPDF_Array* pArray = pIntent->AsArray()) { |
35 uint32_t dwCount = pArray->GetCount(); | 34 for (size_t i = 0; i < pArray->GetCount(); i++) { |
36 for (uint32_t i = 0; i < dwCount; i++) { | |
37 bsIntent = pArray->GetStringAt(i); | 35 bsIntent = pArray->GetStringAt(i); |
38 if (bsIntent == "All" || bsIntent == csElement) | 36 if (bsIntent == "All" || bsIntent == csElement) |
39 return TRUE; | 37 return TRUE; |
40 } | 38 } |
41 return FALSE; | 39 return FALSE; |
42 } | 40 } |
43 bsIntent = pIntent->GetString(); | 41 bsIntent = pIntent->GetString(); |
44 return bsIntent == "All" || bsIntent == csElement; | 42 return bsIntent == "All" || bsIntent == csElement; |
45 } | 43 } |
46 static CPDF_Dictionary* FPDFDOC_OCG_GetConfig(CPDF_Document* pDoc, | 44 static CPDF_Dictionary* FPDFDOC_OCG_GetConfig(CPDF_Document* pDoc, |
47 const CPDF_Dictionary* pOCGDict, | 45 const CPDF_Dictionary* pOCGDict, |
48 const CFX_ByteStringC& bsState) { | 46 const CFX_ByteStringC& bsState) { |
49 FXSYS_assert(pDoc && pOCGDict); | 47 FXSYS_assert(pDoc && pOCGDict); |
50 CPDF_Dictionary* pOCProperties = pDoc->GetRoot()->GetDictBy("OCProperties"); | 48 CPDF_Dictionary* pOCProperties = pDoc->GetRoot()->GetDictBy("OCProperties"); |
51 if (!pOCProperties) { | 49 if (!pOCProperties) { |
52 return NULL; | 50 return NULL; |
53 } | 51 } |
54 CPDF_Array* pOCGs = pOCProperties->GetArrayBy("OCGs"); | 52 CPDF_Array* pOCGs = pOCProperties->GetArrayBy("OCGs"); |
55 if (!pOCGs) { | 53 if (!pOCGs) { |
56 return NULL; | 54 return NULL; |
57 } | 55 } |
58 if (FPDFDOC_OCG_FindGroup(pOCGs, pOCGDict) < 0) { | 56 if (FPDFDOC_OCG_FindGroup(pOCGs, pOCGDict) < 0) { |
59 return NULL; | 57 return NULL; |
60 } | 58 } |
61 CPDF_Dictionary* pConfig = pOCProperties->GetDictBy("D"); | 59 CPDF_Dictionary* pConfig = pOCProperties->GetDictBy("D"); |
62 CPDF_Array* pConfigs = pOCProperties->GetArrayBy("Configs"); | 60 CPDF_Array* pConfigs = pOCProperties->GetArrayBy("Configs"); |
63 if (pConfigs) { | 61 if (pConfigs) { |
64 CPDF_Dictionary* pFind; | 62 CPDF_Dictionary* pFind; |
65 int32_t iCount = pConfigs->GetCount(); | 63 for (size_t i = 0; i < pConfigs->GetCount(); i++) { |
66 for (int32_t i = 0; i < iCount; i++) { | |
67 pFind = pConfigs->GetDictAt(i); | 64 pFind = pConfigs->GetDictAt(i); |
68 if (!pFind) { | 65 if (!pFind) { |
69 continue; | 66 continue; |
70 } | 67 } |
71 if (!FPDFDOC_OCG_HasIntent(pFind, "View", "View")) { | 68 if (!FPDFDOC_OCG_HasIntent(pFind, "View", "View")) { |
72 continue; | 69 continue; |
73 } | 70 } |
74 pConfig = pFind; | 71 pConfig = pFind; |
75 break; | 72 break; |
76 } | 73 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 } | 112 } |
116 pArray = pConfig->GetArrayBy("OFF"); | 113 pArray = pConfig->GetArrayBy("OFF"); |
117 if (pArray) { | 114 if (pArray) { |
118 if (FPDFDOC_OCG_FindGroup(pArray, pOCGDict) >= 0) { | 115 if (FPDFDOC_OCG_FindGroup(pArray, pOCGDict) >= 0) { |
119 bState = FALSE; | 116 bState = FALSE; |
120 } | 117 } |
121 } | 118 } |
122 pArray = pConfig->GetArrayBy("AS"); | 119 pArray = pConfig->GetArrayBy("AS"); |
123 if (pArray) { | 120 if (pArray) { |
124 CFX_ByteString csFind = csConfig + "State"; | 121 CFX_ByteString csFind = csConfig + "State"; |
125 int32_t iCount = pArray->GetCount(); | 122 for (size_t i = 0; i < pArray->GetCount(); i++) { |
126 for (int32_t i = 0; i < iCount; i++) { | |
127 CPDF_Dictionary* pUsage = pArray->GetDictAt(i); | 123 CPDF_Dictionary* pUsage = pArray->GetDictAt(i); |
128 if (!pUsage) { | 124 if (!pUsage) { |
129 continue; | 125 continue; |
130 } | 126 } |
131 if (pUsage->GetStringBy("Event", "View") != csConfig) { | 127 if (pUsage->GetStringBy("Event", "View") != csConfig) { |
132 continue; | 128 continue; |
133 } | 129 } |
134 CPDF_Array* pOCGs = pUsage->GetArrayBy("OCGs"); | 130 CPDF_Array* pOCGs = pUsage->GetArrayBy("OCGs"); |
135 if (!pOCGs) { | 131 if (!pOCGs) { |
136 continue; | 132 continue; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 | 183 |
188 FX_BOOL CPDF_OCContext::GetOCGVE(CPDF_Array* pExpression, | 184 FX_BOOL CPDF_OCContext::GetOCGVE(CPDF_Array* pExpression, |
189 FX_BOOL bFromConfig, | 185 FX_BOOL bFromConfig, |
190 int nLevel) { | 186 int nLevel) { |
191 if (nLevel > 32) { | 187 if (nLevel > 32) { |
192 return FALSE; | 188 return FALSE; |
193 } | 189 } |
194 if (!pExpression) { | 190 if (!pExpression) { |
195 return FALSE; | 191 return FALSE; |
196 } | 192 } |
197 int32_t iCount = pExpression->GetCount(); | |
198 CPDF_Object* pOCGObj; | 193 CPDF_Object* pOCGObj; |
199 CFX_ByteString csOperator = pExpression->GetStringAt(0); | 194 CFX_ByteString csOperator = pExpression->GetStringAt(0); |
200 if (csOperator == "Not") { | 195 if (csOperator == "Not") { |
201 pOCGObj = pExpression->GetDirectObjectAt(1); | 196 pOCGObj = pExpression->GetDirectObjectAt(1); |
202 if (!pOCGObj) | 197 if (!pOCGObj) |
203 return FALSE; | 198 return FALSE; |
204 if (CPDF_Dictionary* pDict = pOCGObj->AsDictionary()) | 199 if (CPDF_Dictionary* pDict = pOCGObj->AsDictionary()) |
205 return !(bFromConfig ? LoadOCGState(pDict) : GetOCGVisible(pDict)); | 200 return !(bFromConfig ? LoadOCGState(pDict) : GetOCGVisible(pDict)); |
206 if (CPDF_Array* pArray = pOCGObj->AsArray()) | 201 if (CPDF_Array* pArray = pOCGObj->AsArray()) |
207 return !GetOCGVE(pArray, bFromConfig, nLevel + 1); | 202 return !GetOCGVE(pArray, bFromConfig, nLevel + 1); |
208 return FALSE; | 203 return FALSE; |
209 } | 204 } |
210 if (csOperator == "Or" || csOperator == "And") { | 205 if (csOperator == "Or" || csOperator == "And") { |
211 FX_BOOL bValue = FALSE; | 206 FX_BOOL bValue = FALSE; |
212 for (int32_t i = 1; i < iCount; i++) { | 207 for (size_t i = 1; i < pExpression->GetCount(); i++) { |
213 pOCGObj = pExpression->GetDirectObjectAt(1); | 208 pOCGObj = pExpression->GetDirectObjectAt(1); |
214 if (!pOCGObj) { | 209 if (!pOCGObj) { |
215 continue; | 210 continue; |
216 } | 211 } |
217 FX_BOOL bItem = FALSE; | 212 FX_BOOL bItem = FALSE; |
218 if (CPDF_Dictionary* pDict = pOCGObj->AsDictionary()) | 213 if (CPDF_Dictionary* pDict = pOCGObj->AsDictionary()) |
219 bItem = bFromConfig ? LoadOCGState(pDict) : GetOCGVisible(pDict); | 214 bItem = bFromConfig ? LoadOCGState(pDict) : GetOCGVisible(pDict); |
220 else if (CPDF_Array* pArray = pOCGObj->AsArray()) | 215 else if (CPDF_Array* pArray = pOCGObj->AsArray()) |
221 bItem = GetOCGVE(pArray, bFromConfig, nLevel + 1); | 216 bItem = GetOCGVE(pArray, bFromConfig, nLevel + 1); |
222 | 217 |
(...skipping 25 matching lines...) Expand all Loading... |
248 return bFromConfig ? LoadOCGState(pDict) : GetOCGVisible(pDict); | 243 return bFromConfig ? LoadOCGState(pDict) : GetOCGVisible(pDict); |
249 | 244 |
250 CPDF_Array* pArray = pOCGObj->AsArray(); | 245 CPDF_Array* pArray = pOCGObj->AsArray(); |
251 if (!pArray) | 246 if (!pArray) |
252 return TRUE; | 247 return TRUE; |
253 | 248 |
254 FX_BOOL bState = FALSE; | 249 FX_BOOL bState = FALSE; |
255 if (csP == "AllOn" || csP == "AllOff") { | 250 if (csP == "AllOn" || csP == "AllOff") { |
256 bState = TRUE; | 251 bState = TRUE; |
257 } | 252 } |
258 int32_t iCount = pArray->GetCount(); | 253 for (size_t i = 0; i < pArray->GetCount(); i++) { |
259 for (int32_t i = 0; i < iCount; i++) { | |
260 FX_BOOL bItem = TRUE; | 254 FX_BOOL bItem = TRUE; |
261 CPDF_Dictionary* pItemDict = pArray->GetDictAt(i); | 255 CPDF_Dictionary* pItemDict = pArray->GetDictAt(i); |
262 if (pItemDict) | 256 if (pItemDict) |
263 bItem = bFromConfig ? LoadOCGState(pItemDict) : GetOCGVisible(pItemDict); | 257 bItem = bFromConfig ? LoadOCGState(pItemDict) : GetOCGVisible(pItemDict); |
264 | 258 |
265 if ((csP == "AnyOn" && bItem) || (csP == "AnyOff" && !bItem)) | 259 if ((csP == "AnyOn" && bItem) || (csP == "AnyOff" && !bItem)) |
266 return TRUE; | 260 return TRUE; |
267 if ((csP == "AllOn" && !bItem) || (csP == "AllOff" && bItem)) | 261 if ((csP == "AllOn" && !bItem) || (csP == "AllOff" && bItem)) |
268 return FALSE; | 262 return FALSE; |
269 } | 263 } |
270 return bState; | 264 return bState; |
271 } | 265 } |
272 FX_BOOL CPDF_OCContext::CheckOCGVisible(const CPDF_Dictionary* pOCGDict) { | 266 FX_BOOL CPDF_OCContext::CheckOCGVisible(const CPDF_Dictionary* pOCGDict) { |
273 if (!pOCGDict) { | 267 if (!pOCGDict) { |
274 return TRUE; | 268 return TRUE; |
275 } | 269 } |
276 CFX_ByteString csType = pOCGDict->GetStringBy("Type", "OCG"); | 270 CFX_ByteString csType = pOCGDict->GetStringBy("Type", "OCG"); |
277 if (csType == "OCG") { | 271 if (csType == "OCG") { |
278 return GetOCGVisible(pOCGDict); | 272 return GetOCGVisible(pOCGDict); |
279 } | 273 } |
280 return LoadOCMDState(pOCGDict, FALSE); | 274 return LoadOCMDState(pOCGDict, FALSE); |
281 } | 275 } |
282 void CPDF_OCContext::ResetOCContext() { | 276 void CPDF_OCContext::ResetOCContext() { |
283 m_OCGStates.clear(); | 277 m_OCGStates.clear(); |
284 } | 278 } |
OLD | NEW |