diff options
author | Dan Sinclair <dsinclair@chromium.org> | 2016-03-14 13:35:12 -0400 |
---|---|---|
committer | Dan Sinclair <dsinclair@chromium.org> | 2016-03-14 13:35:12 -0400 |
commit | 764ec513eecbebd12781bcc96ce81ed5e736ee92 (patch) | |
tree | 12763fde4be1f10ea1183d92185917b2b587e00b /core/fpdfdoc/doc_ocg.cpp | |
parent | 97da97662417085774f75c26e535c6fbe70266ae (diff) | |
download | pdfium-764ec513eecbebd12781bcc96ce81ed5e736ee92.tar.xz |
Move core/src/ up to core/.
This CL moves the core/src/ files up to core/ and fixes up the include guards,
includes and build files.
R=tsepez@chromium.org
Review URL: https://codereview.chromium.org/1800523005 .
Diffstat (limited to 'core/fpdfdoc/doc_ocg.cpp')
-rw-r--r-- | core/fpdfdoc/doc_ocg.cpp | 284 |
1 files changed, 284 insertions, 0 deletions
diff --git a/core/fpdfdoc/doc_ocg.cpp b/core/fpdfdoc/doc_ocg.cpp new file mode 100644 index 0000000000..3af745580c --- /dev/null +++ b/core/fpdfdoc/doc_ocg.cpp @@ -0,0 +1,284 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/include/fpdfapi/cpdf_array.h" +#include "core/include/fpdfapi/cpdf_document.h" +#include "core/include/fpdfdoc/fpdf_doc.h" + +static int32_t FPDFDOC_OCG_FindGroup(const CPDF_Object* pObject, + const CPDF_Dictionary* pGroupDict) { + if (!pObject || !pGroupDict) + return -1; + + if (const CPDF_Array* pArray = pObject->AsArray()) { + FX_DWORD dwCount = pArray->GetCount(); + for (FX_DWORD i = 0; i < dwCount; i++) { + if (pArray->GetDictAt(i) == pGroupDict) + return i; + } + return -1; + } + return pObject->GetDict() == pGroupDict ? 0 : -1; +} +static FX_BOOL FPDFDOC_OCG_HasIntent(const CPDF_Dictionary* pDict, + const CFX_ByteStringC& csElement, + const CFX_ByteStringC& csDef = "") { + CPDF_Object* pIntent = pDict->GetElementValue("Intent"); + if (!pIntent) { + return csElement == csDef; + } + CFX_ByteString bsIntent; + if (CPDF_Array* pArray = pIntent->AsArray()) { + FX_DWORD dwCount = pArray->GetCount(); + for (FX_DWORD i = 0; i < dwCount; i++) { + bsIntent = pArray->GetStringAt(i); + if (bsIntent == "All" || bsIntent == csElement) + return TRUE; + } + return FALSE; + } + bsIntent = pIntent->GetString(); + return bsIntent == "All" || bsIntent == csElement; +} +static CPDF_Dictionary* FPDFDOC_OCG_GetConfig(CPDF_Document* pDoc, + const CPDF_Dictionary* pOCGDict, + const CFX_ByteStringC& bsState) { + FXSYS_assert(pDoc && pOCGDict); + CPDF_Dictionary* pOCProperties = pDoc->GetRoot()->GetDictBy("OCProperties"); + if (!pOCProperties) { + return NULL; + } + CPDF_Array* pOCGs = pOCProperties->GetArrayBy("OCGs"); + if (!pOCGs) { + return NULL; + } + if (FPDFDOC_OCG_FindGroup(pOCGs, pOCGDict) < 0) { + return NULL; + } + CPDF_Dictionary* pConfig = pOCProperties->GetDictBy("D"); + CPDF_Array* pConfigs = pOCProperties->GetArrayBy("Configs"); + if (pConfigs) { + CPDF_Dictionary* pFind; + int32_t iCount = pConfigs->GetCount(); + for (int32_t i = 0; i < iCount; i++) { + pFind = pConfigs->GetDictAt(i); + if (!pFind) { + continue; + } + if (!FPDFDOC_OCG_HasIntent(pFind, "View", "View")) { + continue; + } + pConfig = pFind; + break; + } + } + return pConfig; +} +static CFX_ByteString FPDFDOC_OCG_GetUsageTypeString( + CPDF_OCContext::UsageType eType) { + CFX_ByteString csState = "View"; + if (eType == CPDF_OCContext::Design) { + csState = "Design"; + } else if (eType == CPDF_OCContext::Print) { + csState = "Print"; + } else if (eType == CPDF_OCContext::Export) { + csState = "Export"; + } + return csState; +} +CPDF_OCContext::CPDF_OCContext(CPDF_Document* pDoc, UsageType eUsageType) { + FXSYS_assert(pDoc); + m_pDocument = pDoc; + m_eUsageType = eUsageType; +} +CPDF_OCContext::~CPDF_OCContext() { + m_OCGStates.clear(); +} +FX_BOOL CPDF_OCContext::LoadOCGStateFromConfig(const CFX_ByteStringC& csConfig, + const CPDF_Dictionary* pOCGDict, + FX_BOOL& bValidConfig) const { + CPDF_Dictionary* pConfig = + FPDFDOC_OCG_GetConfig(m_pDocument, pOCGDict, csConfig); + if (!pConfig) { + return TRUE; + } + bValidConfig = TRUE; + FX_BOOL bState = pConfig->GetStringBy("BaseState", "ON") != "OFF"; + CPDF_Array* pArray = pConfig->GetArrayBy("ON"); + if (pArray) { + if (FPDFDOC_OCG_FindGroup(pArray, pOCGDict) >= 0) { + bState = TRUE; + } + } + pArray = pConfig->GetArrayBy("OFF"); + if (pArray) { + if (FPDFDOC_OCG_FindGroup(pArray, pOCGDict) >= 0) { + bState = FALSE; + } + } + pArray = pConfig->GetArrayBy("AS"); + if (pArray) { + CFX_ByteString csFind = csConfig + "State"; + int32_t iCount = pArray->GetCount(); + for (int32_t i = 0; i < iCount; i++) { + CPDF_Dictionary* pUsage = pArray->GetDictAt(i); + if (!pUsage) { + continue; + } + if (pUsage->GetStringBy("Event", "View") != csConfig) { + continue; + } + CPDF_Array* pOCGs = pUsage->GetArrayBy("OCGs"); + if (!pOCGs) { + continue; + } + if (FPDFDOC_OCG_FindGroup(pOCGs, pOCGDict) < 0) { + continue; + } + CPDF_Dictionary* pState = pUsage->GetDictBy(csConfig); + if (!pState) { + continue; + } + bState = pState->GetStringBy(csFind) != "OFF"; + } + } + return bState; +} +FX_BOOL CPDF_OCContext::LoadOCGState(const CPDF_Dictionary* pOCGDict) const { + if (!FPDFDOC_OCG_HasIntent(pOCGDict, "View", "View")) { + return TRUE; + } + CFX_ByteString csState = FPDFDOC_OCG_GetUsageTypeString(m_eUsageType); + CPDF_Dictionary* pUsage = pOCGDict->GetDictBy("Usage"); + if (pUsage) { + CPDF_Dictionary* pState = pUsage->GetDictBy(csState); + if (pState) { + CFX_ByteString csFind = csState + "State"; + if (pState->KeyExist(csFind)) { + return pState->GetStringBy(csFind) != "OFF"; + } + } + if (csState != "View") { + pState = pUsage->GetDictBy("View"); + if (pState && pState->KeyExist("ViewState")) { + return pState->GetStringBy("ViewState") != "OFF"; + } + } + } + FX_BOOL bDefValid = FALSE; + return LoadOCGStateFromConfig(csState, pOCGDict, bDefValid); +} + +FX_BOOL CPDF_OCContext::GetOCGVisible(const CPDF_Dictionary* pOCGDict) { + if (!pOCGDict) + return FALSE; + + const auto it = m_OCGStates.find(pOCGDict); + if (it != m_OCGStates.end()) + return it->second; + + FX_BOOL bState = LoadOCGState(pOCGDict); + m_OCGStates[pOCGDict] = bState; + return bState; +} + +FX_BOOL CPDF_OCContext::GetOCGVE(CPDF_Array* pExpression, + FX_BOOL bFromConfig, + int nLevel) { + if (nLevel > 32) { + return FALSE; + } + if (!pExpression) { + return FALSE; + } + int32_t iCount = pExpression->GetCount(); + CPDF_Object* pOCGObj; + CFX_ByteString csOperator = pExpression->GetStringAt(0); + if (csOperator == "Not") { + pOCGObj = pExpression->GetElementValue(1); + if (!pOCGObj) + return FALSE; + if (CPDF_Dictionary* pDict = pOCGObj->AsDictionary()) + return !(bFromConfig ? LoadOCGState(pDict) : GetOCGVisible(pDict)); + if (CPDF_Array* pArray = pOCGObj->AsArray()) + return !GetOCGVE(pArray, bFromConfig, nLevel + 1); + return FALSE; + } + if (csOperator == "Or" || csOperator == "And") { + FX_BOOL bValue = FALSE; + for (int32_t i = 1; i < iCount; i++) { + pOCGObj = pExpression->GetElementValue(1); + if (!pOCGObj) { + continue; + } + FX_BOOL bItem = FALSE; + if (CPDF_Dictionary* pDict = pOCGObj->AsDictionary()) + bItem = bFromConfig ? LoadOCGState(pDict) : GetOCGVisible(pDict); + else if (CPDF_Array* pArray = pOCGObj->AsArray()) + bItem = GetOCGVE(pArray, bFromConfig, nLevel + 1); + + if (i == 1) { + bValue = bItem; + } else { + if (csOperator == "Or") { + bValue = bValue || bItem; + } else { + bValue = bValue && bItem; + } + } + } + return bValue; + } + return FALSE; +} +FX_BOOL CPDF_OCContext::LoadOCMDState(const CPDF_Dictionary* pOCMDDict, + FX_BOOL bFromConfig) { + CPDF_Array* pVE = pOCMDDict->GetArrayBy("VE"); + if (pVE) { + return GetOCGVE(pVE, bFromConfig); + } + CFX_ByteString csP = pOCMDDict->GetStringBy("P", "AnyOn"); + CPDF_Object* pOCGObj = pOCMDDict->GetElementValue("OCGs"); + if (!pOCGObj) + return TRUE; + if (const CPDF_Dictionary* pDict = pOCGObj->AsDictionary()) + return bFromConfig ? LoadOCGState(pDict) : GetOCGVisible(pDict); + + CPDF_Array* pArray = pOCGObj->AsArray(); + if (!pArray) + return TRUE; + + FX_BOOL bState = FALSE; + if (csP == "AllOn" || csP == "AllOff") { + bState = TRUE; + } + int32_t iCount = pArray->GetCount(); + for (int32_t i = 0; i < iCount; i++) { + FX_BOOL bItem = TRUE; + CPDF_Dictionary* pItemDict = pArray->GetDictAt(i); + if (pItemDict) + bItem = bFromConfig ? LoadOCGState(pItemDict) : GetOCGVisible(pItemDict); + + if ((csP == "AnyOn" && bItem) || (csP == "AnyOff" && !bItem)) + return TRUE; + if ((csP == "AllOn" && !bItem) || (csP == "AllOff" && bItem)) + return FALSE; + } + return bState; +} +FX_BOOL CPDF_OCContext::CheckOCGVisible(const CPDF_Dictionary* pOCGDict) { + if (!pOCGDict) { + return TRUE; + } + CFX_ByteString csType = pOCGDict->GetStringBy("Type", "OCG"); + if (csType == "OCG") { + return GetOCGVisible(pOCGDict); + } + return LoadOCMDState(pOCGDict, FALSE); +} +void CPDF_OCContext::ResetOCContext() { + m_OCGStates.clear(); +} |