Beispiel #1
0
FX_BOOL CPDF_StructTreeImpl::AddTopLevelNode(CPDF_Dictionary* pDict,
                                             CPDF_StructElementImpl* pElement) {
  CPDF_Object* pObj = m_pTreeRoot->GetDirectObjectBy("K");
  if (!pObj)
    return FALSE;

  if (pObj->IsDictionary()) {
    if (pObj->GetObjNum() != pDict->GetObjNum())
      return FALSE;
    m_Kids[0].Reset(pElement);
  }
  if (CPDF_Array* pTopKids = pObj->AsArray()) {
    bool bSave = false;
    for (size_t i = 0; i < pTopKids->GetCount(); i++) {
      CPDF_Reference* pKidRef = ToReference(pTopKids->GetObjectAt(i));
      if (pKidRef && pKidRef->GetRefObjNum() == pDict->GetObjNum()) {
        m_Kids[i].Reset(pElement);
        bSave = true;
      }
    }
    if (!bSave)
      return FALSE;
  }
  return TRUE;
}
FX_BOOL CPDF_Document::IsContentUsedElsewhere(FX_DWORD objnum,
        CPDF_Dictionary* pThisPageDict) {
    for (int i = 0; i < m_PageList.GetSize(); i++) {
        CPDF_Dictionary* pPageDict = GetPage(i);
        if (pPageDict == pThisPageDict) {
            continue;
        }
        CPDF_Object* pContents =
            pPageDict ? pPageDict->GetElement("Contents") : NULL;
        if (!pContents) {
            continue;
        }
        if (pContents->GetDirectType() == PDFOBJ_ARRAY) {
            CPDF_Array* pArray = pContents->GetDirect()->AsArray();
            for (FX_DWORD j = 0; j < pArray->GetCount(); j++) {
                CPDF_Reference* pRef = ToReference(pArray->GetElement(j));
                if (pRef && pRef->GetRefObjNum() == objnum)
                    return TRUE;
            }
        } else if (pContents->GetObjNum() == objnum) {
            return TRUE;
        }
    }
    return FALSE;
}
Beispiel #3
0
FX_BOOL CPDF_PageOrganizer::UpdateReference(CPDF_Object* pObj,
                                            CPDF_Document* pDoc,
                                            ObjectNumberMap* pObjNumberMap) {
  switch (pObj->GetType()) {
    case CPDF_Object::REFERENCE: {
      CPDF_Reference* pReference = pObj->AsReference();
      uint32_t newobjnum = GetNewObjId(pDoc, pObjNumberMap, pReference);
      if (newobjnum == 0)
        return FALSE;
      pReference->SetRef(pDoc, newobjnum);
      break;
    }
    case CPDF_Object::DICTIONARY: {
      CPDF_Dictionary* pDict = pObj->AsDictionary();
      auto it = pDict->begin();
      while (it != pDict->end()) {
        const CFX_ByteString& key = it->first;
        CPDF_Object* pNextObj = it->second;
        ++it;
        if (key == "Parent" || key == "Prev" || key == "First")
          continue;
        if (!pNextObj)
          return FALSE;
        if (!UpdateReference(pNextObj, pDoc, pObjNumberMap))
          pDict->RemoveFor(key);
      }
      break;
    }
    case CPDF_Object::ARRAY: {
      CPDF_Array* pArray = pObj->AsArray();
      for (size_t i = 0; i < pArray->GetCount(); ++i) {
        CPDF_Object* pNextObj = pArray->GetObjectAt(i);
        if (!pNextObj)
          return FALSE;
        if (!UpdateReference(pNextObj, pDoc, pObjNumberMap))
          return FALSE;
      }
      break;
    }
    case CPDF_Object::STREAM: {
      CPDF_Stream* pStream = pObj->AsStream();
      CPDF_Dictionary* pDict = pStream->GetDict();
      if (pDict) {
        if (!UpdateReference(pDict, pDoc, pObjNumberMap))
          return FALSE;
      } else {
        return FALSE;
      }
      break;
    }
    default:
      break;
  }

  return TRUE;
}
bool CPDF_DataAvail::PreparePageItem() {
  CPDF_Dictionary* pRoot = m_pDocument->GetRoot();
  CPDF_Reference* pRef =
      ToReference(pRoot ? pRoot->GetObjectFor("Pages") : nullptr);
  if (!pRef) {
    m_docStatus = PDF_DATAAVAIL_ERROR;
    return false;
  }

  m_PagesObjNum = pRef->GetRefObjNum();
  m_pCurrentParser = m_pDocument->GetParser();
  m_docStatus = PDF_DATAAVAIL_PAGETREE;
  return true;
}
void CPDF_StreamContentParser::Handle_ExecuteXObject() {
  CFX_ByteString name = GetString(0);
  if (name == m_LastImageName && m_pLastImage && m_pLastImage->GetStream() &&
      m_pLastImage->GetStream()->GetObjNum()) {
    AddImage(nullptr, m_pLastImage, FALSE);
    return;
  }

  if (m_Options.m_bTextOnly) {
    if (!m_pResources)
      return;

    CPDF_Dictionary* pList = m_pResources->GetDict("XObject");
    if (!pList && m_pPageResources && m_pResources != m_pPageResources)
      pList = m_pPageResources->GetDict("XObject");
    if (!pList)
      return;
    CPDF_Reference* pRes = ToReference(pList->GetElement(name));
    if (!pRes)
      return;

    FX_BOOL bForm;
    if (m_pDocument->IsFormStream(pRes->GetRefObjNum(), bForm) && !bForm)
      return;
  }

  CPDF_Stream* pXObject = ToStream(FindResourceObj("XObject", name));
  if (!pXObject) {
    m_bResourceMissing = TRUE;
    return;
  }

  CFX_ByteStringC type = pXObject->GetDict()
                             ? pXObject->GetDict()->GetConstString("Subtype")
                             : CFX_ByteStringC();
  if (type == "Image") {
    if (m_Options.m_bTextOnly) {
      return;
    }
    CPDF_ImageObject* pObj = AddImage(pXObject, NULL, FALSE);
    m_LastImageName = name;
    m_pLastImage = pObj->m_pImage;
    if (!m_pObjectList->m_bHasImageMask)
      m_pObjectList->m_bHasImageMask = m_pLastImage->IsMask();
  } else if (type == "Form") {
    AddForm(pXObject);
  } else {
    return;
  }
}
bool CPDF_DataAvail::CheckRoot(DownloadHints* pHints) {
  bool bExist = false;
  m_pRoot = GetObject(m_dwRootObjNum, pHints, &bExist);
  if (!bExist) {
    m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
    return true;
  }

  if (!m_pRoot) {
    if (m_docStatus == PDF_DATAAVAIL_ERROR) {
      m_docStatus = PDF_DATAAVAIL_LOADALLFILE;
      return true;
    }
    return false;
  }

  CPDF_Dictionary* pDict = m_pRoot->GetDict();
  if (!pDict) {
    m_docStatus = PDF_DATAAVAIL_ERROR;
    return false;
  }

  CPDF_Reference* pRef = ToReference(pDict->GetObjectFor("Pages"));
  if (!pRef) {
    m_docStatus = PDF_DATAAVAIL_ERROR;
    return false;
  }

  m_PagesObjNum = pRef->GetRefObjNum();
  CPDF_Reference* pAcroFormRef =
      ToReference(m_pRoot->GetDict()->GetObjectFor("AcroForm"));
  if (pAcroFormRef) {
    m_bHaveAcroForm = true;
    m_dwAcroFormObjNum = pAcroFormRef->GetRefObjNum();
  }

  if (m_dwInfoObjNum) {
    m_docStatus = PDF_DATAAVAIL_INFO;
  } else {
    m_docStatus =
        m_bHaveAcroForm ? PDF_DATAAVAIL_ACROFORM : PDF_DATAAVAIL_PAGETREE;
  }
  return true;
}
static CPDF_Stream* GetFormStream(CPDF_Document* pDoc, CPDF_Object* pResObj)
{
    if (pResObj->GetType() != PDFOBJ_REFERENCE) {
        return NULL;
    }
    CPDF_Reference* pRef = (CPDF_Reference*)pResObj;
    FX_BOOL bForm;
    if (pDoc->IsFormStream(pRef->GetRefObjNum(), bForm) && !bForm) {
        return NULL;
    }
    pResObj = pRef->GetDirect();
    if (pResObj->GetType() != PDFOBJ_STREAM) {
        return NULL;
    }
    CPDF_Stream* pXObject = (CPDF_Stream*)pResObj;
    if (pXObject->GetDict()->GetString(FX_BSTRC("Subtype")) != FX_BSTRC("Form")) {
        return NULL;
    }
    return pXObject;
}
bool CPDF_DataAvail::CheckArrayPageNode(uint32_t dwPageNo,
                                        PageNode* pPageNode,
                                        DownloadHints* pHints) {
  bool bExist = false;
  std::unique_ptr<CPDF_Object> pPages = GetObject(dwPageNo, pHints, &bExist);
  if (!bExist) {
    m_docStatus = PDF_DATAAVAIL_ERROR;
    return false;
  }

  if (!pPages) {
    if (m_docStatus == PDF_DATAAVAIL_ERROR) {
      m_docStatus = PDF_DATAAVAIL_ERROR;
      return false;
    }
    return false;
  }

  CPDF_Array* pArray = pPages->AsArray();
  if (!pArray) {
    m_docStatus = PDF_DATAAVAIL_ERROR;
    return false;
  }

  pPageNode->m_type = PDF_PAGENODE_PAGES;
  for (size_t i = 0; i < pArray->GetCount(); ++i) {
    CPDF_Reference* pKid = ToReference(pArray->GetObjectAt(i));
    if (!pKid)
      continue;

    PageNode* pNode = new PageNode();
    pPageNode->m_childNode.Add(pNode);
    pNode->m_dwPageNo = pKid->GetRefObjNum();
  }
  return true;
}
CPDF_Object* CPDF_Object::CloneInternal(FX_BOOL bDirect, CFX_MapPtrToPtr* visited) const
{
    switch (m_Type) {
        case PDFOBJ_BOOLEAN:
            return new CPDF_Boolean(((CPDF_Boolean*)this)->m_bValue);
        case PDFOBJ_NUMBER:
            return new CPDF_Number(((CPDF_Number*)this)->m_bInteger, &((CPDF_Number*)this)->m_Integer);
        case PDFOBJ_STRING:
            return new CPDF_String(((CPDF_String*)this)->m_String, ((CPDF_String*)this)->IsHex());
        case PDFOBJ_NAME:
            return new CPDF_Name(((CPDF_Name*)this)->m_Name);
        case PDFOBJ_ARRAY: {
                CPDF_Array* pCopy = new CPDF_Array();
                CPDF_Array* pThis = (CPDF_Array*)this;
                int n = pThis->GetCount();
                for (int i = 0; i < n; i ++) {
                    CPDF_Object* value = (CPDF_Object*)pThis->m_Objects.GetAt(i);
                    pCopy->m_Objects.Add(value->CloneInternal(bDirect, visited));
                }
                return pCopy;
            }
        case PDFOBJ_DICTIONARY: {
                CPDF_Dictionary* pCopy = new CPDF_Dictionary();
                CPDF_Dictionary* pThis = (CPDF_Dictionary*)this;
                FX_POSITION pos = pThis->m_Map.GetStartPosition();
                while (pos) {
                    CFX_ByteString key;
                    CPDF_Object* value;
                    pThis->m_Map.GetNextAssoc(pos, key, (void*&)value);
                    pCopy->m_Map.SetAt(key, value->CloneInternal(bDirect, visited));
                }
                return pCopy;
            }
        case PDFOBJ_NULL: {
                return new CPDF_Null;
            }
        case PDFOBJ_STREAM: {
                CPDF_Stream* pThis = (CPDF_Stream*)this;
                CPDF_StreamAcc acc;
                acc.LoadAllData(pThis, TRUE);
                FX_DWORD streamSize = acc.GetSize();
                CPDF_Stream* pObj;
                if (pThis->GetDict())
                    pObj = new CPDF_Stream(acc.DetachData(), streamSize, (CPDF_Dictionary*)((CPDF_Object*)pThis->GetDict())->CloneInternal(bDirect, visited));
                else
                    pObj = new CPDF_Stream(acc.DetachData(), streamSize, NULL);
                return pObj;
            }
        case PDFOBJ_REFERENCE: {
                CPDF_Reference* pRef = (CPDF_Reference*)this;
                FX_DWORD obj_num = pRef->m_RefObjNum;
                if (bDirect && !visited->GetValueAt((void*)(FX_UINTPTR)obj_num)) {
                    visited->SetAt((void*)(FX_UINTPTR)obj_num, (void*)1);
                    CPDF_Object* ret;
                    if (pRef->GetDirect())
                        ret = pRef->GetDirect()->CloneInternal(TRUE, visited);
                    else
                        ret = NULL;
                    return ret;
                } else {
                    return new CPDF_Reference(pRef->m_pObjList, obj_num);
                }
            }
    }
    return NULL;
}
bool CPDF_DataAvail::AreObjectsAvailable(std::vector<CPDF_Object*>& obj_array,
                                         bool bParsePage,
                                         DownloadHints* pHints,
                                         std::vector<CPDF_Object*>& ret_array) {
  if (obj_array.empty())
    return true;

  uint32_t count = 0;
  std::vector<CPDF_Object*> new_obj_array;
  for (CPDF_Object* pObj : obj_array) {
    if (!pObj)
      continue;

    int32_t type = pObj->GetType();
    switch (type) {
      case CPDF_Object::ARRAY: {
        CPDF_Array* pArray = pObj->AsArray();
        for (size_t k = 0; k < pArray->GetCount(); ++k)
          new_obj_array.push_back(pArray->GetObjectAt(k));
      } break;
      case CPDF_Object::STREAM:
        pObj = pObj->GetDict();
      case CPDF_Object::DICTIONARY: {
        CPDF_Dictionary* pDict = pObj->GetDict();
        if (pDict && pDict->GetStringFor("Type") == "Page" && !bParsePage)
          continue;

        for (const auto& it : *pDict) {
          if (it.first != "Parent")
            new_obj_array.push_back(it.second.get());
        }
      } break;
      case CPDF_Object::REFERENCE: {
        CPDF_Reference* pRef = pObj->AsReference();
        uint32_t dwNum = pRef->GetRefObjNum();

        FX_FILESIZE offset;
        uint32_t size = GetObjectSize(dwNum, offset);
        if (size == 0 || offset < 0 || offset >= m_dwFileLen)
          break;

        if (!IsDataAvail(offset, size, pHints)) {
          ret_array.push_back(pObj);
          count++;
        } else if (!pdfium::ContainsKey(m_ObjectSet, dwNum)) {
          m_ObjectSet.insert(dwNum);
          CPDF_Object* pReferred =
              m_pDocument->GetOrParseIndirectObject(pRef->GetRefObjNum());
          if (pReferred)
            new_obj_array.push_back(pReferred);
        }
      } break;
    }
  }

  if (count > 0) {
    for (CPDF_Object* pObj : new_obj_array) {
      CPDF_Reference* pRef = pObj->AsReference();
      if (pRef && pdfium::ContainsKey(m_ObjectSet, pRef->GetRefObjNum()))
        continue;
      ret_array.push_back(pObj);
    }
    return false;
  }

  obj_array = new_obj_array;
  return AreObjectsAvailable(obj_array, false, pHints, ret_array);
}
bool CPDF_DataAvail::CheckUnkownPageNode(uint32_t dwPageNo,
                                         PageNode* pPageNode,
                                         DownloadHints* pHints) {
  bool bExist = false;
  std::unique_ptr<CPDF_Object> pPage = GetObject(dwPageNo, pHints, &bExist);
  if (!bExist) {
    m_docStatus = PDF_DATAAVAIL_ERROR;
    return false;
  }

  if (!pPage) {
    if (m_docStatus == PDF_DATAAVAIL_ERROR)
      m_docStatus = PDF_DATAAVAIL_ERROR;
    return false;
  }

  if (pPage->IsArray()) {
    pPageNode->m_dwPageNo = dwPageNo;
    pPageNode->m_type = PDF_PAGENODE_ARRAY;
    return true;
  }

  if (!pPage->IsDictionary()) {
    m_docStatus = PDF_DATAAVAIL_ERROR;
    return false;
  }

  pPageNode->m_dwPageNo = dwPageNo;
  CPDF_Dictionary* pDict = pPage->GetDict();
  CFX_ByteString type = pDict->GetStringFor("Type");
  if (type == "Pages") {
    pPageNode->m_type = PDF_PAGENODE_PAGES;
    CPDF_Object* pKids = pDict->GetObjectFor("Kids");
    if (!pKids) {
      m_docStatus = PDF_DATAAVAIL_PAGE;
      return true;
    }

    switch (pKids->GetType()) {
      case CPDF_Object::REFERENCE: {
        CPDF_Reference* pKid = pKids->AsReference();
        PageNode* pNode = new PageNode();
        pPageNode->m_childNode.Add(pNode);
        pNode->m_dwPageNo = pKid->GetRefObjNum();
      } break;
      case CPDF_Object::ARRAY: {
        CPDF_Array* pKidsArray = pKids->AsArray();
        for (size_t i = 0; i < pKidsArray->GetCount(); ++i) {
          CPDF_Reference* pKid = ToReference(pKidsArray->GetObjectAt(i));
          if (!pKid)
            continue;

          PageNode* pNode = new PageNode();
          pPageNode->m_childNode.Add(pNode);
          pNode->m_dwPageNo = pKid->GetRefObjNum();
        }
      } break;
      default:
        break;
    }
  } else if (type == "Page") {
    pPageNode->m_type = PDF_PAGENODE_PAGE;
  } else {
    m_docStatus = PDF_DATAAVAIL_ERROR;
    return false;
  }
  return true;
}
DLLEXPORT FPDF_BOOL STDCALL FPDFPage_TransFormWithClip(FPDF_PAGE page, FS_MATRIX* matrix, FS_RECTF* clipRect)
{
	if(!page)
		return FALSE;

	CFX_ByteTextBuf textBuf;
	textBuf<<"q ";
	CFX_FloatRect rect(clipRect->left, clipRect->bottom, clipRect->right, clipRect->top);
	rect.Normalize();
	CFX_ByteString bsClipping;
	bsClipping.Format("%f %f %f %f re W* n ", rect.left, rect.bottom, rect.Width(), rect.Height());
	textBuf<<bsClipping;

	CFX_ByteString bsMatix;
	bsMatix.Format("%f %f %f %f %f %f cm ", matrix->a, matrix->b,matrix->c,matrix->d,matrix->e,matrix->f);
	textBuf<<bsMatix;
	

	CPDF_Page* pPage = (CPDF_Page*)page;
	CPDF_Dictionary* pPageDic = pPage->m_pFormDict;
	CPDF_Object* pContentObj = pPageDic->GetElement("Contents");
	if(!pContentObj)
		pContentObj = pPageDic->GetArray("Contents");
	if(!pContentObj)
		return FALSE;
	
	CPDF_Dictionary* pDic = FX_NEW CPDF_Dictionary;
	CPDF_Stream* pStream = FX_NEW CPDF_Stream(NULL,0, pDic);
	pStream->SetData(textBuf.GetBuffer(), textBuf.GetSize(), FALSE, FALSE);
	CPDF_Document* pDoc = pPage->m_pDocument;
	if(!pDoc)
		return FALSE;
	pDoc->AddIndirectObject(pStream);

	pDic = FX_NEW CPDF_Dictionary;
	CPDF_Stream* pEndStream = FX_NEW CPDF_Stream(NULL,0, pDic);
	pEndStream->SetData((FX_LPCBYTE)" Q", 2, FALSE, FALSE);
	pDoc->AddIndirectObject(pEndStream);
	
	CPDF_Array* pContentArray = NULL;
	if (pContentObj && pContentObj->GetType() == PDFOBJ_ARRAY)
	{
		pContentArray = (CPDF_Array*)pContentObj;
		CPDF_Reference* pRef = FX_NEW CPDF_Reference(pDoc, pStream->GetObjNum());
		pContentArray->InsertAt(0, pRef);
		pContentArray->AddReference(pDoc,pEndStream);
		
	}
	else if(pContentObj && pContentObj->GetType() == PDFOBJ_REFERENCE)
	{
		CPDF_Reference* pReference = (CPDF_Reference*)pContentObj;
		CPDF_Object* pDirectObj = pReference->GetDirect();
		if(pDirectObj != NULL)
		{
			if(pDirectObj->GetType() == PDFOBJ_ARRAY)
			{
				pContentArray = (CPDF_Array*)pDirectObj;
				CPDF_Reference* pRef = FX_NEW CPDF_Reference(pDoc, pStream->GetObjNum());
				pContentArray->InsertAt(0, pRef);
				pContentArray->AddReference(pDoc,pEndStream);
				
			}
			else if(pDirectObj->GetType() == PDFOBJ_STREAM)
			{
				pContentArray = FX_NEW CPDF_Array();
				pContentArray->AddReference(pDoc,pStream->GetObjNum());
				pContentArray->AddReference(pDoc,pDirectObj->GetObjNum());
				pContentArray->AddReference(pDoc, pEndStream);
				pPageDic->SetAtReference("Contents", pDoc, pDoc->AddIndirectObject(pContentArray));
			}
		}
	}	

	//Need to transform the patterns as well.
	CPDF_Dictionary* pRes = pPageDic->GetDict(FX_BSTRC("Resources"));
	if(pRes)
	{
		CPDF_Dictionary* pPattenDict = pRes->GetDict(FX_BSTRC("Pattern"));
		if(pPattenDict)
		{
			FX_POSITION pos = pPattenDict->GetStartPos();
			while(pos)
			{
				CPDF_Dictionary* pDict = NULL;
				CFX_ByteString key;
				CPDF_Object* pObj = pPattenDict->GetNextElement(pos, key);
				if(pObj->GetType() == PDFOBJ_REFERENCE)
					pObj = pObj->GetDirect();
				if(pObj->GetType() == PDFOBJ_DICTIONARY)
				{
					pDict = (CPDF_Dictionary*)pObj;
				}
				else if(pObj->GetType() == PDFOBJ_STREAM)
				{
					pDict = ((CPDF_Stream*)pObj)->GetDict();
				}
				else
					continue;
				
				CFX_AffineMatrix m = pDict->GetMatrix(FX_BSTRC("Matrix"));
				CFX_AffineMatrix t = *(CFX_AffineMatrix*)matrix;
				m.Concat(t);
				pDict->SetAtMatrix(FX_BSTRC("Matrix"), m);
			}
		}
	}

	return TRUE;
}
DLLEXPORT void STDCALL FPDFPage_InsertClipPath(FPDF_PAGE page,FPDF_CLIPPATH clipPath)
{
	if(!page)
		return;
	CPDF_Page* pPage = (CPDF_Page*)page;
	CPDF_Dictionary* pPageDic = pPage->m_pFormDict;
	CPDF_Object* pContentObj = pPageDic->GetElement("Contents");
	if(!pContentObj)
		pContentObj = pPageDic->GetArray("Contents");
	if(!pContentObj)
		return;

	CFX_ByteTextBuf strClip;
	CPDF_ClipPath* pClipPath = (CPDF_ClipPath*)clipPath;
	FX_DWORD i;
	for (i = 0; i < pClipPath->GetPathCount(); i ++) {
		CPDF_Path path = pClipPath->GetPath(i);
		int iClipType = pClipPath->GetClipType(i);
		if (path.GetPointCount() == 0) {
			// Empty clipping (totally clipped out)
			strClip << "0 0 m W n ";
		} else {
			OutputPath(strClip, path);
			if (iClipType == FXFILL_WINDING)
				strClip << "W n\n";
			else
				strClip << "W* n\n";
		}
	}
	CPDF_Dictionary* pDic = FX_NEW CPDF_Dictionary;
	CPDF_Stream* pStream = FX_NEW CPDF_Stream(NULL,0, pDic);
	pStream->SetData(strClip.GetBuffer(), strClip.GetSize(), FALSE, FALSE);
	CPDF_Document* pDoc = pPage->m_pDocument;
	if(!pDoc)
		return;
	pDoc->AddIndirectObject(pStream);
	
	CPDF_Array* pContentArray = NULL;
	if (pContentObj && pContentObj->GetType() == PDFOBJ_ARRAY)
	{
		pContentArray = (CPDF_Array*)pContentObj;
		CPDF_Reference* pRef = FX_NEW CPDF_Reference(pDoc, pStream->GetObjNum());
		pContentArray->InsertAt(0, pRef);
		
	}
	else if(pContentObj && pContentObj->GetType() == PDFOBJ_REFERENCE)
	{
		CPDF_Reference* pReference = (CPDF_Reference*)pContentObj;
		CPDF_Object* pDirectObj = pReference->GetDirect();
		if(pDirectObj != NULL)
		{
			if(pDirectObj->GetType() == PDFOBJ_ARRAY)
			{
				pContentArray = (CPDF_Array*)pDirectObj;
				CPDF_Reference* pRef = FX_NEW CPDF_Reference(pDoc, pStream->GetObjNum());
				pContentArray->InsertAt(0, pRef);
				
			}
			else if(pDirectObj->GetType() == PDFOBJ_STREAM)
			{
				pContentArray = FX_NEW CPDF_Array();
				pContentArray->AddReference(pDoc,pStream->GetObjNum());
				pContentArray->AddReference(pDoc,pDirectObj->GetObjNum());
				pPageDic->SetAtReference("Contents", pDoc, pDoc->AddIndirectObject(pContentArray));
			}
		}
	}	
}
Beispiel #14
0
FX_BOOL CPDF_PageOrganizer::UpdateReference(CPDF_Object* pObj,
                                            CPDF_Document* pDoc,
                                            ObjectNumberMap* pObjNumberMap) {
  switch (pObj->GetType()) {
    case PDFOBJ_REFERENCE: {
      CPDF_Reference* pReference = pObj->AsReference();
      FX_DWORD newobjnum = GetNewObjId(pDoc, pObjNumberMap, pReference);
      if (newobjnum == 0)
        return FALSE;
      pReference->SetRef(pDoc, newobjnum);
      break;
    }
    case PDFOBJ_DICTIONARY: {
      CPDF_Dictionary* pDict = pObj->AsDictionary();

      FX_POSITION pos = pDict->GetStartPos();
      while (pos) {
        CFX_ByteString key("");
        CPDF_Object* pNextObj = pDict->GetNextElement(pos, key);
        if (!FXSYS_strcmp(key, "Parent") || !FXSYS_strcmp(key, "Prev") ||
            !FXSYS_strcmp(key, "First")) {
          continue;
        }
        if (pNextObj) {
          if (!UpdateReference(pNextObj, pDoc, pObjNumberMap))
            pDict->RemoveAt(key);
        } else {
          return FALSE;
        }
      }
      break;
    }
    case PDFOBJ_ARRAY: {
      CPDF_Array* pArray = pObj->AsArray();
      FX_DWORD count = pArray->GetCount();
      for (FX_DWORD i = 0; i < count; ++i) {
        CPDF_Object* pNextObj = pArray->GetElement(i);
        if (!pNextObj)
          return FALSE;
        if (!UpdateReference(pNextObj, pDoc, pObjNumberMap))
          return FALSE;
      }
      break;
    }
    case PDFOBJ_STREAM: {
      CPDF_Stream* pStream = pObj->AsStream();
      CPDF_Dictionary* pDict = pStream->GetDict();
      if (pDict) {
        if (!UpdateReference(pDict, pDoc, pObjNumberMap))
          return FALSE;
      } else {
        return FALSE;
      }
      break;
    }
    default:
      break;
  }

  return TRUE;
}
DLLEXPORT void STDCALL FPDFPage_InsertClipPath(FPDF_PAGE page,
                                               FPDF_CLIPPATH clipPath) {
  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
  if (!pPage)
    return;

  CPDF_Dictionary* pPageDic = pPage->m_pFormDict;
  CPDF_Object* pContentObj =
      pPageDic ? pPageDic->GetObjectFor("Contents") : nullptr;
  if (!pContentObj)
    pContentObj = pPageDic ? pPageDic->GetArrayFor("Contents") : nullptr;
  if (!pContentObj)
    return;

  CFX_ByteTextBuf strClip;
  CPDF_ClipPath* pClipPath = (CPDF_ClipPath*)clipPath;
  uint32_t i;
  for (i = 0; i < pClipPath->GetPathCount(); i++) {
    CPDF_Path path = pClipPath->GetPath(i);
    int iClipType = pClipPath->GetClipType(i);
    if (path.GetPoints().empty()) {
      // Empty clipping (totally clipped out)
      strClip << "0 0 m W n ";
    } else {
      OutputPath(strClip, path);
      if (iClipType == FXFILL_WINDING)
        strClip << "W n\n";
      else
        strClip << "W* n\n";
    }
  }
  CPDF_Document* pDoc = pPage->m_pDocument;
  if (!pDoc)
    return;

  CPDF_Stream* pStream = pDoc->NewIndirect<CPDF_Stream>(
      nullptr, 0,
      pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool()));
  pStream->SetData(strClip.GetBuffer(), strClip.GetSize());

  CPDF_Array* pArray = ToArray(pContentObj);
  if (pArray) {
    pArray->InsertNewAt<CPDF_Reference>(0, pDoc, pStream->GetObjNum());
    return;
  }
  CPDF_Reference* pReference = ToReference(pContentObj);
  if (!pReference)
    return;

  CPDF_Object* pDirectObj = pReference->GetDirect();
  if (!pDirectObj)
    return;

  CPDF_Array* pObjArray = pDirectObj->AsArray();
  if (pObjArray) {
    pObjArray->InsertNewAt<CPDF_Reference>(0, pDoc, pStream->GetObjNum());
    return;
  }
  if (pDirectObj->IsStream()) {
    CPDF_Array* pContentArray = pDoc->NewIndirect<CPDF_Array>();
    pContentArray->AddNew<CPDF_Reference>(pDoc, pStream->GetObjNum());
    pContentArray->AddNew<CPDF_Reference>(pDoc, pDirectObj->GetObjNum());
    pPageDic->SetNewFor<CPDF_Reference>("Contents", pDoc,
                                        pContentArray->GetObjNum());
  }
}
Beispiel #16
0
FX_BOOL _SaveXFADocumentData(CPDFXFA_Document* pDocument,
                             CFX_PtrArray& fileList) {
  if (!pDocument)
    return FALSE;
  if (pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
      pDocument->GetDocType() != DOCTYPE_STATIC_XFA)
    return TRUE;
  if (!CPDFXFA_App::GetInstance()->GetXFAApp())
    return TRUE;

  IXFA_DocView* pXFADocView = pDocument->GetXFADocView();
  if (NULL == pXFADocView)
    return TRUE;

  IXFA_DocHandler* pXFADocHandler =
      CPDFXFA_App::GetInstance()->GetXFAApp()->GetDocHandler();
  CPDF_Document* pPDFDocument = pDocument->GetPDFDoc();
  if (pDocument == NULL)
    return FALSE;

  CPDF_Dictionary* pRoot = pPDFDocument->GetRoot();
  if (pRoot == NULL)
    return FALSE;
  CPDF_Dictionary* pAcroForm = pRoot->GetDict("AcroForm");
  if (NULL == pAcroForm)
    return FALSE;
  CPDF_Object* pXFA = pAcroForm->GetElement("XFA");
  if (pXFA == NULL)
    return TRUE;
  if (pXFA->GetType() != PDFOBJ_ARRAY)
    return FALSE;
  CPDF_Array* pArray = pXFA->GetArray();
  if (NULL == pArray)
    return FALSE;
  int size = pArray->GetCount();
  int iFormIndex = -1;
  int iDataSetsIndex = -1;
  int iTemplate = -1;
  int iLast = size - 2;
  for (int i = 0; i < size - 1; i++) {
    CPDF_Object* pPDFObj = pArray->GetElement(i);
    if (pPDFObj->GetType() != PDFOBJ_STRING)
      continue;
    if (pPDFObj->GetString() == "form")
      iFormIndex = i + 1;
    else if (pPDFObj->GetString() == "datasets")
      iDataSetsIndex = i + 1;
    else if (pPDFObj->GetString() == "template")
      iTemplate = i + 1;
  }
  IXFA_ChecksumContext* pContext = NULL;
  // Checksum
  pContext = XFA_Checksum_Create();
  FXSYS_assert(pContext);
  pContext->StartChecksum();

  // template
  if (iTemplate > -1) {
    CPDF_Stream* pTemplateStream = pArray->GetStream(iTemplate);
    CPDF_StreamAcc streamAcc;
    streamAcc.LoadAllData(pTemplateStream);
    uint8_t* pData = (uint8_t*)streamAcc.GetData();
    FX_DWORD dwSize2 = streamAcc.GetSize();
    IFX_FileStream* pTemplate = FX_CreateMemoryStream(pData, dwSize2);
    pContext->UpdateChecksum((IFX_FileRead*)pTemplate);
    pTemplate->Release();
  }
  CPDF_Stream* pFormStream = NULL;
  CPDF_Stream* pDataSetsStream = NULL;
  if (iFormIndex != -1) {
    // Get form CPDF_Stream
    CPDF_Object* pFormPDFObj = pArray->GetElement(iFormIndex);
    if (pFormPDFObj->GetType() == PDFOBJ_REFERENCE) {
      CPDF_Object* pFormDircetObj = pFormPDFObj->GetDirect();
      if (NULL != pFormDircetObj &&
          pFormDircetObj->GetType() == PDFOBJ_STREAM) {
        pFormStream = (CPDF_Stream*)pFormDircetObj;
      }
    } else if (pFormPDFObj->GetType() == PDFOBJ_STREAM) {
      pFormStream = (CPDF_Stream*)pFormPDFObj;
    }
  }

  if (iDataSetsIndex != -1) {
    // Get datasets CPDF_Stream
    CPDF_Object* pDataSetsPDFObj = pArray->GetElement(iDataSetsIndex);
    if (pDataSetsPDFObj->GetType() == PDFOBJ_REFERENCE) {
      CPDF_Reference* pDataSetsRefObj = (CPDF_Reference*)pDataSetsPDFObj;
      CPDF_Object* pDataSetsDircetObj = pDataSetsRefObj->GetDirect();
      if (NULL != pDataSetsDircetObj &&
          pDataSetsDircetObj->GetType() == PDFOBJ_STREAM) {
        pDataSetsStream = (CPDF_Stream*)pDataSetsDircetObj;
      }
    } else if (pDataSetsPDFObj->GetType() == PDFOBJ_STREAM) {
      pDataSetsStream = (CPDF_Stream*)pDataSetsPDFObj;
    }
  }
  // end
  // L"datasets"
  {
    IFX_FileStream* pDsfileWrite = FX_CreateMemoryStream();
    if (NULL == pDsfileWrite) {
      pContext->Release();
      pDsfileWrite->Release();
      return FALSE;
    }
    if (pXFADocHandler->SavePackage(pXFADocView->GetDoc(),
                                    CFX_WideStringC(L"datasets"),
                                    pDsfileWrite) &&
        pDsfileWrite->GetSize() > 0) {
      // Datasets
      pContext->UpdateChecksum((IFX_FileRead*)pDsfileWrite);
      pContext->FinishChecksum();
      CPDF_Dictionary* pDataDict = new CPDF_Dictionary;
      if (iDataSetsIndex != -1) {
        if (pDataSetsStream)
          pDataSetsStream->InitStreamFromFile(pDsfileWrite, pDataDict);
      } else {
        CPDF_Stream* pData = new CPDF_Stream(NULL, 0, NULL);
        pData->InitStreamFromFile(pDsfileWrite, pDataDict);
        pPDFDocument->AddIndirectObject(pData);
        iLast = pArray->GetCount() - 2;
        pArray->InsertAt(iLast, new CPDF_String("datasets", FALSE));
        pArray->InsertAt(iLast + 1, pData, pPDFDocument);
      }
      fileList.Add(pDsfileWrite);
    }
  }

  // L"form"
  {
    IFX_FileStream* pfileWrite = FX_CreateMemoryStream();
    if (NULL == pfileWrite) {
      pContext->Release();
      return FALSE;
    }
    if (pXFADocHandler->SavePackage(pXFADocView->GetDoc(),
                                    CFX_WideStringC(L"form"), pfileWrite,
                                    pContext) &&
        pfileWrite > 0) {
      CPDF_Dictionary* pDataDict = new CPDF_Dictionary;
      if (iFormIndex != -1) {
        if (pFormStream)
          pFormStream->InitStreamFromFile(pfileWrite, pDataDict);
      } else {
        CPDF_Stream* pData = new CPDF_Stream(NULL, 0, NULL);
        pData->InitStreamFromFile(pfileWrite, pDataDict);
        pPDFDocument->AddIndirectObject(pData);
        iLast = pArray->GetCount() - 2;
        pArray->InsertAt(iLast, new CPDF_String("form", FALSE));
        pArray->InsertAt(iLast + 1, pData, pPDFDocument);
      }
      fileList.Add(pfileWrite);
    }
  }
  pContext->Release();
  return TRUE;
}