| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2016 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/fpdfdoc/include/cpdf_occontext.h" | 7 #include "core/fpdfdoc/include/cpdf_occontext.h" |
| 8 | 8 |
| 9 #include "core/fpdfapi/fpdf_page/cpdf_contentmarkdata.h" | 9 #include "core/fpdfapi/fpdf_page/cpdf_contentmarkdata.h" |
| 10 #include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h" | 10 #include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h" |
| 11 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" | 11 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" |
| 12 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" | 12 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" |
| 13 | 13 |
| 14 namespace { | 14 namespace { |
| 15 | 15 |
| 16 int32_t FPDFDOC_OCG_FindGroup(const CPDF_Array* pArray, | 16 int32_t FindGroup(const CPDF_Array* pArray, const CPDF_Dictionary* pGroupDict) { |
| 17 const CPDF_Dictionary* pGroupDict) { | |
| 18 if (!pArray || !pGroupDict) | 17 if (!pArray || !pGroupDict) |
| 19 return -1; | 18 return -1; |
| 20 | 19 |
| 21 for (size_t i = 0; i < pArray->GetCount(); i++) { | 20 for (size_t i = 0; i < pArray->GetCount(); i++) { |
| 22 if (pArray->GetDictAt(i) == pGroupDict) | 21 if (pArray->GetDictAt(i) == pGroupDict) |
| 23 return i; | 22 return i; |
| 24 } | 23 } |
| 25 return -1; | 24 return -1; |
| 26 } | 25 } |
| 27 | 26 |
| 28 bool FPDFDOC_OCG_HasIntent(const CPDF_Dictionary* pDict, | 27 bool HasIntent(const CPDF_Dictionary* pDict, |
| 29 const CFX_ByteStringC& csElement, | 28 const CFX_ByteStringC& csElement, |
| 30 const CFX_ByteStringC& csDef) { | 29 const CFX_ByteStringC& csDef) { |
| 31 CPDF_Object* pIntent = pDict->GetDirectObjectBy("Intent"); | 30 CPDF_Object* pIntent = pDict->GetDirectObjectBy("Intent"); |
| 32 if (!pIntent) | 31 if (!pIntent) |
| 33 return csElement == csDef; | 32 return csElement == csDef; |
| 34 | 33 |
| 35 CFX_ByteString bsIntent; | 34 CFX_ByteString bsIntent; |
| 36 if (CPDF_Array* pArray = pIntent->AsArray()) { | 35 if (CPDF_Array* pArray = pIntent->AsArray()) { |
| 37 for (size_t i = 0; i < pArray->GetCount(); i++) { | 36 for (size_t i = 0; i < pArray->GetCount(); i++) { |
| 38 bsIntent = pArray->GetStringAt(i); | 37 bsIntent = pArray->GetStringAt(i); |
| 39 if (bsIntent == "All" || bsIntent == csElement) | 38 if (bsIntent == "All" || bsIntent == csElement) |
| 40 return true; | 39 return true; |
| 41 } | 40 } |
| 42 return false; | 41 return false; |
| 43 } | 42 } |
| 44 bsIntent = pIntent->GetString(); | 43 bsIntent = pIntent->GetString(); |
| 45 return bsIntent == "All" || bsIntent == csElement; | 44 return bsIntent == "All" || bsIntent == csElement; |
| 46 } | 45 } |
| 47 | 46 |
| 48 CPDF_Dictionary* FPDFDOC_OCG_GetConfig(CPDF_Document* pDoc, | 47 CPDF_Dictionary* GetConfig(CPDF_Document* pDoc, |
| 49 const CPDF_Dictionary* pOCGDict) { | 48 const CPDF_Dictionary* pOCGDict) { |
| 50 ASSERT(pOCGDict); | 49 ASSERT(pOCGDict); |
| 51 CPDF_Dictionary* pOCProperties = pDoc->GetRoot()->GetDictBy("OCProperties"); | 50 CPDF_Dictionary* pOCProperties = pDoc->GetRoot()->GetDictBy("OCProperties"); |
| 52 if (!pOCProperties) | 51 if (!pOCProperties) |
| 53 return nullptr; | 52 return nullptr; |
| 54 | 53 |
| 55 CPDF_Array* pOCGs = pOCProperties->GetArrayBy("OCGs"); | 54 CPDF_Array* pOCGs = pOCProperties->GetArrayBy("OCGs"); |
| 56 if (!pOCGs) | 55 if (!pOCGs) |
| 57 return nullptr; | 56 return nullptr; |
| 58 | 57 |
| 59 if (FPDFDOC_OCG_FindGroup(pOCGs, pOCGDict) < 0) | 58 if (FindGroup(pOCGs, pOCGDict) < 0) |
| 60 return nullptr; | 59 return nullptr; |
| 61 | 60 |
| 62 CPDF_Dictionary* pConfig = pOCProperties->GetDictBy("D"); | 61 CPDF_Dictionary* pConfig = pOCProperties->GetDictBy("D"); |
| 63 CPDF_Array* pConfigs = pOCProperties->GetArrayBy("Configs"); | 62 CPDF_Array* pConfigs = pOCProperties->GetArrayBy("Configs"); |
| 64 if (!pConfigs) | 63 if (!pConfigs) |
| 65 return pConfig; | 64 return pConfig; |
| 66 | 65 |
| 67 for (size_t i = 0; i < pConfigs->GetCount(); i++) { | 66 for (size_t i = 0; i < pConfigs->GetCount(); i++) { |
| 68 CPDF_Dictionary* pFind = pConfigs->GetDictAt(i); | 67 CPDF_Dictionary* pFind = pConfigs->GetDictAt(i); |
| 69 if (pFind && FPDFDOC_OCG_HasIntent(pFind, "View", "View")) | 68 if (pFind && HasIntent(pFind, "View", "View")) |
| 70 return pFind; | 69 return pFind; |
| 71 } | 70 } |
| 72 return pConfig; | 71 return pConfig; |
| 73 } | 72 } |
| 74 | 73 |
| 75 CFX_ByteString FPDFDOC_OCG_GetUsageTypeString(CPDF_OCContext::UsageType eType) { | 74 CFX_ByteString GetUsageTypeString(CPDF_OCContext::UsageType eType) { |
| 76 CFX_ByteString csState; | 75 CFX_ByteString csState; |
| 77 switch (eType) { | 76 switch (eType) { |
| 78 case CPDF_OCContext::Design: | 77 case CPDF_OCContext::Design: |
| 79 csState = "Design"; | 78 csState = "Design"; |
| 80 break; | 79 break; |
| 81 case CPDF_OCContext::Print: | 80 case CPDF_OCContext::Print: |
| 82 csState = "Print"; | 81 csState = "Print"; |
| 83 break; | 82 break; |
| 84 case CPDF_OCContext::Export: | 83 case CPDF_OCContext::Export: |
| 85 csState = "Export"; | 84 csState = "Export"; |
| 86 break; | 85 break; |
| 87 default: | 86 default: |
| 88 csState = "View"; | 87 csState = "View"; |
| 89 break; | 88 break; |
| 90 } | 89 } |
| 91 return csState; | 90 return csState; |
| 92 } | 91 } |
| 93 | 92 |
| 94 } // namespace | 93 } // namespace |
| 95 | 94 |
| 96 CPDF_OCContext::CPDF_OCContext(CPDF_Document* pDoc, UsageType eUsageType) | 95 CPDF_OCContext::CPDF_OCContext(CPDF_Document* pDoc, UsageType eUsageType) |
| 97 : m_pDocument(pDoc), m_eUsageType(eUsageType) { | 96 : m_pDocument(pDoc), m_eUsageType(eUsageType) { |
| 98 ASSERT(pDoc); | 97 ASSERT(pDoc); |
| 99 } | 98 } |
| 100 | 99 |
| 101 CPDF_OCContext::~CPDF_OCContext() { | 100 CPDF_OCContext::~CPDF_OCContext() {} |
| 102 } | |
| 103 | 101 |
| 104 bool CPDF_OCContext::LoadOCGStateFromConfig( | 102 bool CPDF_OCContext::LoadOCGStateFromConfig( |
| 105 const CFX_ByteString& csConfig, | 103 const CFX_ByteString& csConfig, |
| 106 const CPDF_Dictionary* pOCGDict) const { | 104 const CPDF_Dictionary* pOCGDict) const { |
| 107 CPDF_Dictionary* pConfig = FPDFDOC_OCG_GetConfig(m_pDocument, pOCGDict); | 105 CPDF_Dictionary* pConfig = GetConfig(m_pDocument, pOCGDict); |
| 108 if (!pConfig) | 106 if (!pConfig) |
| 109 return true; | 107 return true; |
| 110 | 108 |
| 111 bool bState = pConfig->GetStringBy("BaseState", "ON") != "OFF"; | 109 bool bState = pConfig->GetStringBy("BaseState", "ON") != "OFF"; |
| 112 CPDF_Array* pArray = pConfig->GetArrayBy("ON"); | 110 CPDF_Array* pArray = pConfig->GetArrayBy("ON"); |
| 113 if (pArray) { | 111 if (pArray) { |
| 114 if (FPDFDOC_OCG_FindGroup(pArray, pOCGDict) >= 0) | 112 if (FindGroup(pArray, pOCGDict) >= 0) |
| 115 bState = true; | 113 bState = true; |
| 116 } | 114 } |
| 117 pArray = pConfig->GetArrayBy("OFF"); | 115 pArray = pConfig->GetArrayBy("OFF"); |
| 118 if (pArray) { | 116 if (pArray) { |
| 119 if (FPDFDOC_OCG_FindGroup(pArray, pOCGDict) >= 0) | 117 if (FindGroup(pArray, pOCGDict) >= 0) |
| 120 bState = false; | 118 bState = false; |
| 121 } | 119 } |
| 122 pArray = pConfig->GetArrayBy("AS"); | 120 pArray = pConfig->GetArrayBy("AS"); |
| 123 if (!pArray) | 121 if (!pArray) |
| 124 return bState; | 122 return bState; |
| 125 | 123 |
| 126 CFX_ByteString csFind = csConfig + "State"; | 124 CFX_ByteString csFind = csConfig + "State"; |
| 127 for (size_t i = 0; i < pArray->GetCount(); i++) { | 125 for (size_t i = 0; i < pArray->GetCount(); i++) { |
| 128 CPDF_Dictionary* pUsage = pArray->GetDictAt(i); | 126 CPDF_Dictionary* pUsage = pArray->GetDictAt(i); |
| 129 if (!pUsage) | 127 if (!pUsage) |
| 130 continue; | 128 continue; |
| 131 | 129 |
| 132 if (pUsage->GetStringBy("Event", "View") != csConfig) | 130 if (pUsage->GetStringBy("Event", "View") != csConfig) |
| 133 continue; | 131 continue; |
| 134 | 132 |
| 135 CPDF_Array* pOCGs = pUsage->GetArrayBy("OCGs"); | 133 CPDF_Array* pOCGs = pUsage->GetArrayBy("OCGs"); |
| 136 if (!pOCGs) | 134 if (!pOCGs) |
| 137 continue; | 135 continue; |
| 138 | 136 |
| 139 if (FPDFDOC_OCG_FindGroup(pOCGs, pOCGDict) < 0) | 137 if (FindGroup(pOCGs, pOCGDict) < 0) |
| 140 continue; | 138 continue; |
| 141 | 139 |
| 142 CPDF_Dictionary* pState = pUsage->GetDictBy(csConfig); | 140 CPDF_Dictionary* pState = pUsage->GetDictBy(csConfig); |
| 143 if (!pState) | 141 if (!pState) |
| 144 continue; | 142 continue; |
| 145 | 143 |
| 146 bState = pState->GetStringBy(csFind) != "OFF"; | 144 bState = pState->GetStringBy(csFind) != "OFF"; |
| 147 } | 145 } |
| 148 return bState; | 146 return bState; |
| 149 } | 147 } |
| 150 | 148 |
| 151 bool CPDF_OCContext::LoadOCGState(const CPDF_Dictionary* pOCGDict) const { | 149 bool CPDF_OCContext::LoadOCGState(const CPDF_Dictionary* pOCGDict) const { |
| 152 if (!FPDFDOC_OCG_HasIntent(pOCGDict, "View", "View")) | 150 if (!HasIntent(pOCGDict, "View", "View")) |
| 153 return true; | 151 return true; |
| 154 | 152 |
| 155 CFX_ByteString csState = FPDFDOC_OCG_GetUsageTypeString(m_eUsageType); | 153 CFX_ByteString csState = GetUsageTypeString(m_eUsageType); |
| 156 CPDF_Dictionary* pUsage = pOCGDict->GetDictBy("Usage"); | 154 CPDF_Dictionary* pUsage = pOCGDict->GetDictBy("Usage"); |
| 157 if (pUsage) { | 155 if (pUsage) { |
| 158 CPDF_Dictionary* pState = pUsage->GetDictBy(csState); | 156 CPDF_Dictionary* pState = pUsage->GetDictBy(csState); |
| 159 if (pState) { | 157 if (pState) { |
| 160 CFX_ByteString csFind = csState + "State"; | 158 CFX_ByteString csFind = csState + "State"; |
| 161 if (pState->KeyExist(csFind)) { | 159 if (pState->KeyExist(csFind)) |
| 162 return pState->GetStringBy(csFind) != "OFF"; | 160 return pState->GetStringBy(csFind) != "OFF"; |
| 163 } | |
| 164 } | 161 } |
| 165 if (csState != "View") { | 162 if (csState != "View") { |
| 166 pState = pUsage->GetDictBy("View"); | 163 pState = pUsage->GetDictBy("View"); |
| 167 if (pState && pState->KeyExist("ViewState")) { | 164 if (pState && pState->KeyExist("ViewState")) |
| 168 return pState->GetStringBy("ViewState") != "OFF"; | 165 return pState->GetStringBy("ViewState") != "OFF"; |
| 169 } | |
| 170 } | 166 } |
| 171 } | 167 } |
| 172 return LoadOCGStateFromConfig(csState, pOCGDict); | 168 return LoadOCGStateFromConfig(csState, pOCGDict); |
| 173 } | 169 } |
| 174 | 170 |
| 175 bool CPDF_OCContext::GetOCGVisible(const CPDF_Dictionary* pOCGDict) { | 171 bool CPDF_OCContext::GetOCGVisible(const CPDF_Dictionary* pOCGDict) { |
| 176 if (!pOCGDict) | 172 if (!pOCGDict) |
| 177 return false; | 173 return false; |
| 178 | 174 |
| 179 const auto it = m_OCGStates.find(pOCGDict); | 175 const auto it = m_OCGStates.find(pOCGDict); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 | 272 |
| 277 bool CPDF_OCContext::CheckOCGVisible(const CPDF_Dictionary* pOCGDict) { | 273 bool CPDF_OCContext::CheckOCGVisible(const CPDF_Dictionary* pOCGDict) { |
| 278 if (!pOCGDict) | 274 if (!pOCGDict) |
| 279 return true; | 275 return true; |
| 280 | 276 |
| 281 CFX_ByteString csType = pOCGDict->GetStringBy("Type", "OCG"); | 277 CFX_ByteString csType = pOCGDict->GetStringBy("Type", "OCG"); |
| 282 if (csType == "OCG") | 278 if (csType == "OCG") |
| 283 return GetOCGVisible(pOCGDict); | 279 return GetOCGVisible(pOCGDict); |
| 284 return LoadOCMDState(pOCGDict); | 280 return LoadOCMDState(pOCGDict); |
| 285 } | 281 } |
| OLD | NEW |