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/fpdfdoc/fpdf_doc.h" | 7 #include "../../include/fpdfdoc/fpdf_doc.h" |
8 static int32_t FPDFDOC_OCG_FindGroup(const CPDF_Object *pObject, const CPDF_Dict
ionary *pGroupDict) | 8 static int32_t FPDFDOC_OCG_FindGroup(const CPDF_Object *pObject, const CPDF_Dict
ionary *pGroupDict) |
9 { | 9 { |
10 if (pObject == NULL || pGroupDict == NULL) { | 10 if (pObject == NULL || pGroupDict == NULL) { |
11 return -1; | 11 return -1; |
12 } | 12 } |
13 int32_t iType = pObject->GetType(); | 13 int32_t iType = pObject->GetType(); |
14 if (iType == PDFOBJ_ARRAY) { | 14 if (iType == PDFOBJ_ARRAY) { |
15 FX_DWORD dwCount = ((CPDF_Array*)pObject)->GetCount(); | 15 FX_DWORD dwCount = ((CPDF_Array*)pObject)->GetCount(); |
16 for (FX_DWORD i = 0; i < dwCount; i++) { | 16 for (FX_DWORD i = 0; i < dwCount; i++) { |
17 if (((CPDF_Array*)pObject)->GetDict(i) == pGroupDict) { | 17 if (((CPDF_Array*)pObject)->GetDict(i) == pGroupDict) { |
18 return i; | 18 return i; |
19 } | 19 } |
20 } | 20 } |
21 return -1; | 21 return -1; |
22 } | 22 } |
23 if (pObject->GetDict() == pGroupDict) { | 23 if (pObject->GetDict() == pGroupDict) { |
24 return 0; | 24 return 0; |
25 } | 25 } |
26 return -1; | 26 return -1; |
27 } | 27 } |
28 static bool FPDFDOC_OCG_HasIntent(const CPDF_Dictionary *pDict, const CFX_ByteSt
ringC& csElement, const CFX_ByteStringC& csDef = FX_BSTRC("")) | 28 static FX_BOOL FPDFDOC_OCG_HasIntent(const CPDF_Dictionary *pDict, const CFX_Byt
eStringC& csElement, const CFX_ByteStringC& csDef = FX_BSTRC("")) |
29 { | 29 { |
30 FXSYS_assert(pDict != NULL); | 30 FXSYS_assert(pDict != NULL); |
31 CPDF_Object *pIntent = pDict->GetElementValue(FX_BSTRC("Intent")); | 31 CPDF_Object *pIntent = pDict->GetElementValue(FX_BSTRC("Intent")); |
32 if (pIntent == NULL) { | 32 if (pIntent == NULL) { |
33 return csElement == csDef; | 33 return csElement == csDef; |
34 } | 34 } |
35 CFX_ByteString bsIntent; | 35 CFX_ByteString bsIntent; |
36 if (pIntent->GetType() == PDFOBJ_ARRAY) { | 36 if (pIntent->GetType() == PDFOBJ_ARRAY) { |
37 FX_DWORD dwCount = ((CPDF_Array*)pIntent)->GetCount(); | 37 FX_DWORD dwCount = ((CPDF_Array*)pIntent)->GetCount(); |
38 for (FX_DWORD i = 0; i < dwCount; i++) { | 38 for (FX_DWORD i = 0; i < dwCount; i++) { |
39 bsIntent = ((CPDF_Array*)pIntent)->GetString(i); | 39 bsIntent = ((CPDF_Array*)pIntent)->GetString(i); |
40 if (bsIntent == FX_BSTRC("All") || bsIntent == csElement) { | 40 if (bsIntent == FX_BSTRC("All") || bsIntent == csElement) { |
41 return true; | 41 return TRUE; |
42 } | 42 } |
43 } | 43 } |
44 return false; | 44 return FALSE; |
45 } | 45 } |
46 bsIntent = pIntent->GetString(); | 46 bsIntent = pIntent->GetString(); |
47 return bsIntent == FX_BSTRC("All") || bsIntent == csElement; | 47 return bsIntent == FX_BSTRC("All") || bsIntent == csElement; |
48 } | 48 } |
49 static CPDF_Dictionary* FPDFDOC_OCG_GetConfig(CPDF_Document *pDoc, const CPDF_Di
ctionary *pOCGDict, const CFX_ByteStringC& bsState) | 49 static CPDF_Dictionary* FPDFDOC_OCG_GetConfig(CPDF_Document *pDoc, const CPDF_Di
ctionary *pOCGDict, const CFX_ByteStringC& bsState) |
50 { | 50 { |
51 FXSYS_assert(pDoc && pOCGDict); | 51 FXSYS_assert(pDoc && pOCGDict); |
52 CPDF_Dictionary *pOCProperties = pDoc->GetRoot()->GetDict(FX_BSTRC("OCProper
ties")); | 52 CPDF_Dictionary *pOCProperties = pDoc->GetRoot()->GetDict(FX_BSTRC("OCProper
ties")); |
53 if (!pOCProperties) { | 53 if (!pOCProperties) { |
54 return NULL; | 54 return NULL; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 CPDF_OCContext::CPDF_OCContext(CPDF_Document *pDoc, UsageType eUsageType) | 94 CPDF_OCContext::CPDF_OCContext(CPDF_Document *pDoc, UsageType eUsageType) |
95 { | 95 { |
96 FXSYS_assert(pDoc != NULL); | 96 FXSYS_assert(pDoc != NULL); |
97 m_pDocument = pDoc; | 97 m_pDocument = pDoc; |
98 m_eUsageType = eUsageType; | 98 m_eUsageType = eUsageType; |
99 } | 99 } |
100 CPDF_OCContext::~CPDF_OCContext() | 100 CPDF_OCContext::~CPDF_OCContext() |
101 { | 101 { |
102 m_OCGStates.clear(); | 102 m_OCGStates.clear(); |
103 } | 103 } |
104 bool CPDF_OCContext::LoadOCGStateFromConfig(const CFX_ByteStringC& csConfig, con
st CPDF_Dictionary *pOCGDict, bool &bValidConfig) const | 104 FX_BOOL CPDF_OCContext::LoadOCGStateFromConfig(const CFX_ByteStringC& csConfig,
const CPDF_Dictionary *pOCGDict, FX_BOOL &bValidConfig) const |
105 { | 105 { |
106 CPDF_Dictionary *pConfig = FPDFDOC_OCG_GetConfig(m_pDocument, pOCGDict, csCo
nfig); | 106 CPDF_Dictionary *pConfig = FPDFDOC_OCG_GetConfig(m_pDocument, pOCGDict, csCo
nfig); |
107 if (!pConfig) { | 107 if (!pConfig) { |
108 return true; | 108 return TRUE; |
109 } | 109 } |
110 bValidConfig = true; | 110 bValidConfig = TRUE; |
111 bool bState = pConfig->GetString(FX_BSTRC("BaseState"), FX_BSTRC("ON")) != F
X_BSTRC("OFF"); | 111 FX_BOOL bState = pConfig->GetString(FX_BSTRC("BaseState"), FX_BSTRC("ON")) !
= FX_BSTRC("OFF"); |
112 CPDF_Array *pArray = pConfig->GetArray(FX_BSTRC("ON")); | 112 CPDF_Array *pArray = pConfig->GetArray(FX_BSTRC("ON")); |
113 if (pArray) { | 113 if (pArray) { |
114 if (FPDFDOC_OCG_FindGroup(pArray, pOCGDict) >= 0) { | 114 if (FPDFDOC_OCG_FindGroup(pArray, pOCGDict) >= 0) { |
115 bState = true; | 115 bState = TRUE; |
116 } | 116 } |
117 } | 117 } |
118 pArray = pConfig->GetArray(FX_BSTRC("OFF")); | 118 pArray = pConfig->GetArray(FX_BSTRC("OFF")); |
119 if (pArray) { | 119 if (pArray) { |
120 if (FPDFDOC_OCG_FindGroup(pArray, pOCGDict) >= 0) { | 120 if (FPDFDOC_OCG_FindGroup(pArray, pOCGDict) >= 0) { |
121 bState = false; | 121 bState = FALSE; |
122 } | 122 } |
123 } | 123 } |
124 pArray = pConfig->GetArray(FX_BSTRC("AS")); | 124 pArray = pConfig->GetArray(FX_BSTRC("AS")); |
125 if (pArray) { | 125 if (pArray) { |
126 CFX_ByteString csFind = csConfig + FX_BSTRC("State"); | 126 CFX_ByteString csFind = csConfig + FX_BSTRC("State"); |
127 int32_t iCount = pArray->GetCount(); | 127 int32_t iCount = pArray->GetCount(); |
128 for (int32_t i = 0; i < iCount; i ++) { | 128 for (int32_t i = 0; i < iCount; i ++) { |
129 CPDF_Dictionary *pUsage = pArray->GetDict(i); | 129 CPDF_Dictionary *pUsage = pArray->GetDict(i); |
130 if (!pUsage) { | 130 if (!pUsage) { |
131 continue; | 131 continue; |
(...skipping 10 matching lines...) Expand all Loading... |
142 } | 142 } |
143 CPDF_Dictionary *pState = pUsage->GetDict(csConfig); | 143 CPDF_Dictionary *pState = pUsage->GetDict(csConfig); |
144 if (!pState) { | 144 if (!pState) { |
145 continue; | 145 continue; |
146 } | 146 } |
147 bState = pState->GetString(csFind) != FX_BSTRC("OFF"); | 147 bState = pState->GetString(csFind) != FX_BSTRC("OFF"); |
148 } | 148 } |
149 } | 149 } |
150 return bState; | 150 return bState; |
151 } | 151 } |
152 bool CPDF_OCContext::LoadOCGState(const CPDF_Dictionary *pOCGDict) const | 152 FX_BOOL CPDF_OCContext::LoadOCGState(const CPDF_Dictionary *pOCGDict) const |
153 { | 153 { |
154 if (!FPDFDOC_OCG_HasIntent(pOCGDict, FX_BSTRC("View"), FX_BSTRC("View"))) { | 154 if (!FPDFDOC_OCG_HasIntent(pOCGDict, FX_BSTRC("View"), FX_BSTRC("View"))) { |
155 return true; | 155 return TRUE; |
156 } | 156 } |
157 CFX_ByteString csState = FPDFDOC_OCG_GetUsageTypeString(m_eUsageType); | 157 CFX_ByteString csState = FPDFDOC_OCG_GetUsageTypeString(m_eUsageType); |
158 CPDF_Dictionary *pUsage = pOCGDict->GetDict(FX_BSTRC("Usage")); | 158 CPDF_Dictionary *pUsage = pOCGDict->GetDict(FX_BSTRC("Usage")); |
159 if (pUsage) { | 159 if (pUsage) { |
160 CPDF_Dictionary *pState = pUsage->GetDict(csState); | 160 CPDF_Dictionary *pState = pUsage->GetDict(csState); |
161 if (pState) { | 161 if (pState) { |
162 CFX_ByteString csFind = csState + FX_BSTRC("State"); | 162 CFX_ByteString csFind = csState + FX_BSTRC("State"); |
163 if (pState->KeyExist(csFind)) { | 163 if (pState->KeyExist(csFind)) { |
164 return pState->GetString(csFind) != FX_BSTRC("OFF"); | 164 return pState->GetString(csFind) != FX_BSTRC("OFF"); |
165 } | 165 } |
166 } | 166 } |
167 if (csState != FX_BSTRC("View")) { | 167 if (csState != FX_BSTRC("View")) { |
168 pState = pUsage->GetDict(FX_BSTRC("View")); | 168 pState = pUsage->GetDict(FX_BSTRC("View")); |
169 if (pState && pState->KeyExist(FX_BSTRC("ViewState"))) { | 169 if (pState && pState->KeyExist(FX_BSTRC("ViewState"))) { |
170 return pState->GetString(FX_BSTRC("ViewState")) != FX_BSTRC("OFF
"); | 170 return pState->GetString(FX_BSTRC("ViewState")) != FX_BSTRC("OFF
"); |
171 } | 171 } |
172 } | 172 } |
173 } | 173 } |
174 bool bDefValid = false; | 174 FX_BOOL bDefValid = FALSE; |
175 return LoadOCGStateFromConfig(csState, pOCGDict, bDefValid); | 175 return LoadOCGStateFromConfig(csState, pOCGDict, bDefValid); |
176 } | 176 } |
177 | 177 |
178 bool CPDF_OCContext::GetOCGVisible(const CPDF_Dictionary* pOCGDict) | 178 FX_BOOL CPDF_OCContext::GetOCGVisible(const CPDF_Dictionary* pOCGDict) |
179 { | 179 { |
180 if (!pOCGDict) | 180 if (!pOCGDict) |
181 return false; | 181 return FALSE; |
182 | 182 |
183 const auto it = m_OCGStates.find(pOCGDict); | 183 const auto it = m_OCGStates.find(pOCGDict); |
184 if (it != m_OCGStates.end()) | 184 if (it != m_OCGStates.end()) |
185 return it->second; | 185 return it->second; |
186 | 186 |
187 bool bState = LoadOCGState(pOCGDict); | 187 FX_BOOL bState = LoadOCGState(pOCGDict); |
188 m_OCGStates[pOCGDict] = bState; | 188 m_OCGStates[pOCGDict] = bState; |
189 return bState; | 189 return bState; |
190 } | 190 } |
191 | 191 |
192 bool CPDF_OCContext::GetOCGVE(CPDF_Array *pExpression, bool bFromConfig, int nLe
vel) | 192 FX_BOOL CPDF_OCContext::GetOCGVE(CPDF_Array *pExpression, FX_BOOL bFromConfig, i
nt nLevel) |
193 { | 193 { |
194 if (nLevel > 32) { | 194 if (nLevel > 32) { |
195 return false; | 195 return FALSE; |
196 } | 196 } |
197 if (pExpression == NULL) { | 197 if (pExpression == NULL) { |
198 return false; | 198 return FALSE; |
199 } | 199 } |
200 int32_t iCount = pExpression->GetCount(); | 200 int32_t iCount = pExpression->GetCount(); |
201 CPDF_Object *pOCGObj; | 201 CPDF_Object *pOCGObj; |
202 CFX_ByteString csOperator = pExpression->GetString(0); | 202 CFX_ByteString csOperator = pExpression->GetString(0); |
203 if (csOperator == FX_BSTRC("Not")) { | 203 if (csOperator == FX_BSTRC("Not")) { |
204 pOCGObj = pExpression->GetElementValue(1); | 204 pOCGObj = pExpression->GetElementValue(1); |
205 if (pOCGObj == NULL) { | 205 if (pOCGObj == NULL) { |
206 return false; | 206 return FALSE; |
207 } | 207 } |
208 if (pOCGObj->GetType() == PDFOBJ_DICTIONARY) { | 208 if (pOCGObj->GetType() == PDFOBJ_DICTIONARY) { |
209 return !(bFromConfig ? LoadOCGState((CPDF_Dictionary*)pOCGObj) : Get
OCGVisible((CPDF_Dictionary*)pOCGObj)); | 209 return !(bFromConfig ? LoadOCGState((CPDF_Dictionary*)pOCGObj) : Get
OCGVisible((CPDF_Dictionary*)pOCGObj)); |
210 } | 210 } |
211 if (pOCGObj->GetType() == PDFOBJ_ARRAY) { | 211 if (pOCGObj->GetType() == PDFOBJ_ARRAY) { |
212 return !GetOCGVE((CPDF_Array*)pOCGObj, bFromConfig, nLevel + 1); | 212 return !GetOCGVE((CPDF_Array*)pOCGObj, bFromConfig, nLevel + 1); |
213 } | 213 } |
214 return false; | 214 return FALSE; |
215 } | 215 } |
216 if (csOperator == FX_BSTRC("Or") || csOperator == FX_BSTRC("And")) { | 216 if (csOperator == FX_BSTRC("Or") || csOperator == FX_BSTRC("And")) { |
217 bool bValue = false; | 217 FX_BOOL bValue = FALSE; |
218 for (int32_t i = 1; i < iCount; i ++) { | 218 for (int32_t i = 1; i < iCount; i ++) { |
219 pOCGObj = pExpression->GetElementValue(1); | 219 pOCGObj = pExpression->GetElementValue(1); |
220 if (pOCGObj == NULL) { | 220 if (pOCGObj == NULL) { |
221 continue; | 221 continue; |
222 } | 222 } |
223 bool bItem = false; | 223 FX_BOOL bItem = FALSE; |
224 if (pOCGObj->GetType() == PDFOBJ_DICTIONARY) { | 224 if (pOCGObj->GetType() == PDFOBJ_DICTIONARY) { |
225 bItem = bFromConfig ? LoadOCGState((CPDF_Dictionary*)pOCGObj) :
GetOCGVisible((CPDF_Dictionary*)pOCGObj); | 225 bItem = bFromConfig ? LoadOCGState((CPDF_Dictionary*)pOCGObj) :
GetOCGVisible((CPDF_Dictionary*)pOCGObj); |
226 } else if (pOCGObj->GetType() == PDFOBJ_ARRAY) { | 226 } else if (pOCGObj->GetType() == PDFOBJ_ARRAY) { |
227 bItem = GetOCGVE((CPDF_Array*)pOCGObj, bFromConfig, nLevel + 1); | 227 bItem = GetOCGVE((CPDF_Array*)pOCGObj, bFromConfig, nLevel + 1); |
228 } | 228 } |
229 if (i == 1) { | 229 if (i == 1) { |
230 bValue = bItem; | 230 bValue = bItem; |
231 } else { | 231 } else { |
232 if (csOperator == FX_BSTRC("Or")) { | 232 if (csOperator == FX_BSTRC("Or")) { |
233 bValue = bValue || bItem; | 233 bValue = bValue || bItem; |
234 } else { | 234 } else { |
235 bValue = bValue && bItem; | 235 bValue = bValue && bItem; |
236 } | 236 } |
237 } | 237 } |
238 } | 238 } |
239 return bValue; | 239 return bValue; |
240 } | 240 } |
241 return false; | 241 return FALSE; |
242 } | 242 } |
243 bool CPDF_OCContext::LoadOCMDState(const CPDF_Dictionary *pOCMDDict, bool bFromC
onfig) | 243 FX_BOOL CPDF_OCContext::LoadOCMDState(const CPDF_Dictionary *pOCMDDict, FX_BOOL
bFromConfig) |
244 { | 244 { |
245 FXSYS_assert(pOCMDDict != NULL); | 245 FXSYS_assert(pOCMDDict != NULL); |
246 CPDF_Array *pVE = pOCMDDict->GetArray(FX_BSTRC("VE")); | 246 CPDF_Array *pVE = pOCMDDict->GetArray(FX_BSTRC("VE")); |
247 if (pVE != NULL) { | 247 if (pVE != NULL) { |
248 return GetOCGVE(pVE, bFromConfig); | 248 return GetOCGVE(pVE, bFromConfig); |
249 } | 249 } |
250 CFX_ByteString csP = pOCMDDict->GetString(FX_BSTRC("P"), FX_BSTRC("AnyOn")); | 250 CFX_ByteString csP = pOCMDDict->GetString(FX_BSTRC("P"), FX_BSTRC("AnyOn")); |
251 CPDF_Object *pOCGObj = pOCMDDict->GetElementValue(FX_BSTRC("OCGs")); | 251 CPDF_Object *pOCGObj = pOCMDDict->GetElementValue(FX_BSTRC("OCGs")); |
252 if (pOCGObj == NULL) { | 252 if (pOCGObj == NULL) { |
253 return true; | 253 return TRUE; |
254 } | 254 } |
255 if (pOCGObj->GetType() == PDFOBJ_DICTIONARY) { | 255 if (pOCGObj->GetType() == PDFOBJ_DICTIONARY) { |
256 return bFromConfig ? LoadOCGState((CPDF_Dictionary*)pOCGObj) : GetOCGVis
ible((CPDF_Dictionary*)pOCGObj); | 256 return bFromConfig ? LoadOCGState((CPDF_Dictionary*)pOCGObj) : GetOCGVis
ible((CPDF_Dictionary*)pOCGObj); |
257 } | 257 } |
258 if (pOCGObj->GetType() != PDFOBJ_ARRAY) { | 258 if (pOCGObj->GetType() != PDFOBJ_ARRAY) { |
259 return true; | 259 return TRUE; |
260 } | 260 } |
261 bool bState = false; | 261 FX_BOOL bState = FALSE; |
262 if (csP == FX_BSTRC("AllOn") || csP == FX_BSTRC("AllOff")) { | 262 if (csP == FX_BSTRC("AllOn") || csP == FX_BSTRC("AllOff")) { |
263 bState = true; | 263 bState = TRUE; |
264 } | 264 } |
265 int32_t iCount = ((CPDF_Array*)pOCGObj)->GetCount(); | 265 int32_t iCount = ((CPDF_Array*)pOCGObj)->GetCount(); |
266 for (int32_t i = 0; i < iCount; i ++) { | 266 for (int32_t i = 0; i < iCount; i ++) { |
267 bool bItem = true; | 267 FX_BOOL bItem = TRUE; |
268 CPDF_Dictionary* pItemDict = ((CPDF_Array*)pOCGObj)->GetDict(i); | 268 CPDF_Dictionary* pItemDict = ((CPDF_Array*)pOCGObj)->GetDict(i); |
269 if (pItemDict) { | 269 if (pItemDict) { |
270 bItem = bFromConfig ? LoadOCGState(pItemDict) : GetOCGVisible(pItemD
ict); | 270 bItem = bFromConfig ? LoadOCGState(pItemDict) : GetOCGVisible(pItemD
ict); |
271 } | 271 } |
272 if (csP == FX_BSTRC("AnyOn") && bItem) { | 272 if (csP == FX_BSTRC("AnyOn") && bItem) { |
273 return true; | 273 return TRUE; |
274 } | 274 } |
275 if (csP == FX_BSTRC("AnyOff") && !bItem) { | 275 if (csP == FX_BSTRC("AnyOff") && !bItem) { |
276 return true; | 276 return TRUE; |
277 } | 277 } |
278 if (csP == FX_BSTRC("AllOn") && !bItem) { | 278 if (csP == FX_BSTRC("AllOn") && !bItem) { |
279 return false; | 279 return FALSE; |
280 } | 280 } |
281 if (csP == FX_BSTRC("AllOff") && bItem) { | 281 if (csP == FX_BSTRC("AllOff") && bItem) { |
282 return false; | 282 return FALSE; |
283 } | 283 } |
284 } | 284 } |
285 return bState; | 285 return bState; |
286 } | 286 } |
287 bool CPDF_OCContext::CheckOCGVisible(const CPDF_Dictionary *pOCGDict) | 287 FX_BOOL CPDF_OCContext::CheckOCGVisible(const CPDF_Dictionary *pOCGDict) |
288 { | 288 { |
289 if (!pOCGDict) { | 289 if (!pOCGDict) { |
290 return true; | 290 return TRUE; |
291 } | 291 } |
292 CFX_ByteString csType = pOCGDict->GetString(FX_BSTRC("Type"), FX_BSTRC("OCG"
)); | 292 CFX_ByteString csType = pOCGDict->GetString(FX_BSTRC("Type"), FX_BSTRC("OCG"
)); |
293 if (csType == FX_BSTRC("OCG")) { | 293 if (csType == FX_BSTRC("OCG")) { |
294 return GetOCGVisible(pOCGDict); | 294 return GetOCGVisible(pOCGDict); |
295 } | 295 } |
296 return LoadOCMDState(pOCGDict, false); | 296 return LoadOCMDState(pOCGDict, FALSE); |
297 } | 297 } |
298 void CPDF_OCContext::ResetOCContext() | 298 void CPDF_OCContext::ResetOCContext() |
299 { | 299 { |
300 m_OCGStates.clear(); | 300 m_OCGStates.clear(); |
301 } | 301 } |
OLD | NEW |