void CPDF_StructElementImpl::LoadKid(uint32_t PageObjNum, CPDF_Object* pKidObj, CPDF_StructKid* pKid) { pKid->m_Type = CPDF_StructKid::Invalid; if (!pKidObj) return; if (pKidObj->IsNumber()) { if (m_pTree->m_pPage && m_pTree->m_pPage->GetObjNum() != PageObjNum) { return; } pKid->m_Type = CPDF_StructKid::PageContent; pKid->m_PageContent.m_ContentId = pKidObj->GetInteger(); pKid->m_PageContent.m_PageObjNum = PageObjNum; return; } CPDF_Dictionary* pKidDict = pKidObj->AsDictionary(); if (!pKidDict) return; if (CPDF_Reference* pRef = ToReference(pKidDict->GetObjectBy("Pg"))) PageObjNum = pRef->GetRefObjNum(); CFX_ByteString type = pKidDict->GetStringBy("Type"); if (type == "MCR") { if (m_pTree->m_pPage && m_pTree->m_pPage->GetObjNum() != PageObjNum) { return; } pKid->m_Type = CPDF_StructKid::StreamContent; if (CPDF_Reference* pRef = ToReference(pKidDict->GetObjectBy("Stm"))) { pKid->m_StreamContent.m_RefObjNum = pRef->GetRefObjNum(); } else { pKid->m_StreamContent.m_RefObjNum = 0; } pKid->m_StreamContent.m_PageObjNum = PageObjNum; pKid->m_StreamContent.m_ContentId = pKidDict->GetIntegerBy("MCID"); } else if (type == "OBJR") { if (m_pTree->m_pPage && m_pTree->m_pPage->GetObjNum() != PageObjNum) { return; } pKid->m_Type = CPDF_StructKid::Object; if (CPDF_Reference* pObj = ToReference(pKidDict->GetObjectBy("Obj"))) { pKid->m_Object.m_RefObjNum = pObj->GetRefObjNum(); } else { pKid->m_Object.m_RefObjNum = 0; } pKid->m_Object.m_PageObjNum = PageObjNum; } else { pKid->m_Type = CPDF_StructKid::Element; pKid->m_Element.m_pDict = pKidDict; if (!m_pTree->m_pPage) { pKid->m_Element.m_pElement = new CPDF_StructElementImpl(m_pTree, this, pKidDict); } else { pKid->m_Element.m_pElement = nullptr; } } }
void CPDF_StructElement::LoadKid(uint32_t PageObjNum, const CPDF_Object* pKidObj, CPDF_StructKid* pKid) { pKid->m_Type = CPDF_StructKid::Invalid; if (!pKidObj) return; if (pKidObj->IsNumber()) { if (m_pTree->GetPage() && m_pTree->GetPage()->GetObjNum() != PageObjNum) return; pKid->m_Type = CPDF_StructKid::PageContent; pKid->m_ContentId = pKidObj->GetInteger(); pKid->m_PageObjNum = PageObjNum; return; } const CPDF_Dictionary* pKidDict = pKidObj->AsDictionary(); if (!pKidDict) return; if (const CPDF_Reference* pRef = ToReference(pKidDict->GetObjectFor("Pg"))) PageObjNum = pRef->GetRefObjNum(); ByteString type = pKidDict->GetStringFor("Type"); if ((type == "MCR" || type == "OBJR") && m_pTree->GetPage() && m_pTree->GetPage()->GetObjNum() != PageObjNum) { return; } if (type == "MCR") { pKid->m_Type = CPDF_StructKid::StreamContent; const CPDF_Reference* pRef = ToReference(pKidDict->GetObjectFor("Stm")); pKid->m_RefObjNum = pRef ? pRef->GetRefObjNum() : 0; pKid->m_PageObjNum = PageObjNum; pKid->m_ContentId = pKidDict->GetIntegerFor("MCID"); return; } if (type == "OBJR") { pKid->m_Type = CPDF_StructKid::Object; const CPDF_Reference* pObj = ToReference(pKidDict->GetObjectFor("Obj")); pKid->m_RefObjNum = pObj ? pObj->GetRefObjNum() : 0; pKid->m_PageObjNum = PageObjNum; return; } pKid->m_Type = CPDF_StructKid::Element; pKid->m_pDict = pKidDict; if (m_pTree->GetPage()) { pKid->m_pElement = nullptr; return; } pKid->m_pElement = pdfium::MakeRetain<CPDF_StructElement>(m_pTree.Get(), this, pKidDict); }
CFX_WideString CPDF_Dictionary::GetUnicodeText(const CFX_ByteStringC& key, CFX_CharMap* pCharMap) const { CPDF_Object* p = GetElement(key); if (CPDF_Reference* pRef = ToReference(p)) p = pRef->GetDirect(); return p ? p->GetUnicodeText(pCharMap) : CFX_WideString(); }
bool CPDF_DataAvail::GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages) { if (!pParser) { m_docStatus = PDF_DATAAVAIL_ERROR; return false; } CPDF_Dictionary* pDict = pPages->GetDict(); CPDF_Object* pKids = pDict ? pDict->GetObjectFor("Kids") : nullptr; if (!pKids) return true; switch (pKids->GetType()) { case CPDF_Object::REFERENCE: m_PageObjList.Add(pKids->AsReference()->GetRefObjNum()); break; case CPDF_Object::ARRAY: { CPDF_Array* pKidsArray = pKids->AsArray(); for (size_t i = 0; i < pKidsArray->GetCount(); ++i) { if (CPDF_Reference* pRef = ToReference(pKidsArray->GetObjectAt(i))) m_PageObjList.Add(pRef->GetRefObjNum()); } } break; default: m_docStatus = PDF_DATAAVAIL_ERROR; 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; }
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; }
bool CPDF_DataAvail::CheckTrailer(DownloadHints* pHints) { int32_t iTrailerSize = (int32_t)(m_Pos + 512 > m_dwFileLen ? m_dwFileLen - m_Pos : 512); if (m_pFileAvail->IsDataAvail(m_Pos, iTrailerSize)) { int32_t iSize = (int32_t)(m_Pos + iTrailerSize - m_dwTrailerOffset); CFX_BinaryBuf buf(iSize); uint8_t* pBuf = buf.GetBuffer(); if (!pBuf) { m_docStatus = PDF_DATAAVAIL_ERROR; return false; } if (!m_pFileRead->ReadBlock(pBuf, m_dwTrailerOffset, iSize)) return false; ScopedFileStream file(FX_CreateMemoryStream(pBuf, (size_t)iSize, false)); m_syntaxParser.InitParser(file.get(), 0); std::unique_ptr<CPDF_Object> pTrailer( m_syntaxParser.GetObject(nullptr, 0, 0, true)); if (!pTrailer) { m_Pos += m_syntaxParser.SavePos(); pHints->AddSegment(m_Pos, iTrailerSize); return false; } if (!pTrailer->IsDictionary()) return false; CPDF_Dictionary* pTrailerDict = pTrailer->GetDict(); CPDF_Object* pEncrypt = pTrailerDict->GetObjectFor("Encrypt"); if (ToReference(pEncrypt)) { m_docStatus = PDF_DATAAVAIL_LOADALLFILE; return true; } uint32_t xrefpos = GetDirectInteger(pTrailerDict, "Prev"); if (xrefpos) { m_dwPrevXRefOffset = GetDirectInteger(pTrailerDict, "XRefStm"); if (m_dwPrevXRefOffset) { m_docStatus = PDF_DATAAVAIL_LOADALLFILE; } else { m_dwPrevXRefOffset = xrefpos; if (m_dwPrevXRefOffset >= m_dwFileLen) { m_docStatus = PDF_DATAAVAIL_LOADALLFILE; } else { SetStartOffset(m_dwPrevXRefOffset); m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND; } } return true; } m_dwPrevXRefOffset = 0; m_docStatus = PDF_DATAAVAIL_TRAILER_APPEND; return true; } pHints->AddSegment(m_Pos, iTrailerSize); return false; }
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; }
int CPDF_Document::_FindPageIndex(CPDF_Dictionary* pNode, FX_DWORD& skip_count, FX_DWORD objnum, int& index, int level) { if (pNode->KeyExist("Kids")) { CPDF_Array* pKidList = pNode->GetArray("Kids"); if (!pKidList) { return -1; } if (level >= FX_MAX_PAGE_LEVEL) { return -1; } FX_DWORD count = pNode->GetInteger("Count"); if (count <= skip_count) { skip_count -= count; index += count; return -1; } if (count && count == pKidList->GetCount()) { for (FX_DWORD i = 0; i < count; i++) { if (CPDF_Reference* pKid = ToReference(pKidList->GetElement(i))) { if (pKid->GetRefObjNum() == objnum) { m_PageList.SetAt(index + i, objnum); return index + i; } } } } for (FX_DWORD i = 0; i < pKidList->GetCount(); i++) { CPDF_Dictionary* pKid = pKidList->GetDict(i); if (!pKid) { continue; } if (pKid == pNode) { continue; } int found_index = _FindPageIndex(pKid, skip_count, objnum, index, level + 1); if (found_index >= 0) { return found_index; } } } else { if (objnum == pNode->GetObjNum()) { return index; } if (skip_count) { skip_count--; } index++; } return -1; }
bool CPDF_DataAvail::CheckPage(DownloadHints* pHints) { uint32_t iPageObjs = m_PageObjList.GetSize(); CFX_ArrayTemplate<uint32_t> UnavailObjList; for (uint32_t i = 0; i < iPageObjs; ++i) { uint32_t dwPageObjNum = m_PageObjList.GetAt(i); bool bExist = false; std::unique_ptr<CPDF_Object> pObj = GetObject(dwPageObjNum, pHints, &bExist); if (!pObj) { if (bExist) UnavailObjList.Add(dwPageObjNum); continue; } CPDF_Array* pArray = ToArray(pObj.get()); if (pArray) { for (const auto& pArrayObj : *pArray) { if (CPDF_Reference* pRef = ToReference(pArrayObj.get())) UnavailObjList.Add(pRef->GetRefObjNum()); } } if (!pObj->IsDictionary()) continue; CFX_ByteString type = pObj->GetDict()->GetStringFor("Type"); if (type == "Pages") { m_PagesArray.push_back(std::move(pObj)); continue; } } m_PageObjList.RemoveAll(); if (UnavailObjList.GetSize()) { m_PageObjList.Append(UnavailObjList); return false; } uint32_t iPages = m_PagesArray.size(); for (uint32_t i = 0; i < iPages; i++) { std::unique_ptr<CPDF_Object> pPages = std::move(m_PagesArray[i]); if (pPages && !GetPageKids(m_pCurrentParser, pPages.get())) { m_PagesArray.clear(); m_docStatus = PDF_DATAAVAIL_ERROR; return false; } } m_PagesArray.clear(); if (!m_PageObjList.GetSize()) m_docStatus = PDF_DATAAVAIL_DONE; return true; }
int CPDF_Document::FindPageIndex(CPDF_Dictionary* pNode, uint32_t& skip_count, uint32_t objnum, int& index, int level) { if (!pNode->KeyExist("Kids")) { if (objnum == pNode->GetObjNum()) return index; if (skip_count) skip_count--; index++; return -1; } CPDF_Array* pKidList = pNode->GetArrayFor("Kids"); if (!pKidList) return -1; if (level >= FX_MAX_PAGE_LEVEL) return -1; size_t count = pNode->GetIntegerFor("Count"); if (count <= skip_count) { skip_count -= count; index += count; return -1; } if (count && count == pKidList->GetCount()) { for (size_t i = 0; i < count; i++) { if (CPDF_Reference* pKid = ToReference(pKidList->GetObjectAt(i))) { if (pKid->GetRefObjNum() == objnum) { m_PageList.SetAt(index + i, objnum); return static_cast<int>(index + i); } } } } for (size_t i = 0; i < pKidList->GetCount(); i++) { CPDF_Dictionary* pKid = pKidList->GetDictAt(i); if (!pKid || pKid == pNode) continue; int found_index = FindPageIndex(pKid, skip_count, objnum, index, level + 1); if (found_index >= 0) return found_index; } return -1; }
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; } }
void CPDF_StructElementImpl::LoadKids(CPDF_Dictionary* pDict) { CPDF_Object* pObj = pDict->GetObjectBy("Pg"); uint32_t PageObjNum = 0; if (CPDF_Reference* pRef = ToReference(pObj)) PageObjNum = pRef->GetRefObjNum(); CPDF_Object* pKids = pDict->GetDirectObjectBy("K"); if (!pKids) return; m_Kids.clear(); if (CPDF_Array* pArray = pKids->AsArray()) { m_Kids.resize(pArray->GetCount()); for (uint32_t i = 0; i < pArray->GetCount(); i++) { CPDF_Object* pKid = pArray->GetDirectObjectAt(i); LoadKid(PageObjNum, pKid, &m_Kids[i]); } } else { m_Kids.resize(1); LoadKid(PageObjNum, pKids, &m_Kids[0]); } }
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; }
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; }
CPDF_FormField* CPDF_InterForm::AddTerminalField(CPDF_Dictionary* pFieldDict) { if (!pFieldDict->KeyExist("FT")) { // Key "FT" is required for terminal fields, it is also inheritable. CPDF_Dictionary* pParentDict = pFieldDict->GetDictFor("Parent"); if (!pParentDict || !pParentDict->KeyExist("FT")) return nullptr; } CPDF_Dictionary* pDict = pFieldDict; CFX_WideString csWName = FPDF_GetFullName(pFieldDict); if (csWName.IsEmpty()) return nullptr; CPDF_FormField* pField = nullptr; pField = m_pFieldTree->GetField(csWName); if (!pField) { CPDF_Dictionary* pParent = pFieldDict; if (!pFieldDict->KeyExist("T") && pFieldDict->GetStringFor("Subtype") == "Widget") { pParent = pFieldDict->GetDictFor("Parent"); if (!pParent) pParent = pFieldDict; } if (pParent && pParent != pFieldDict && !pParent->KeyExist("FT")) { if (pFieldDict->KeyExist("FT")) { CPDF_Object* pFTValue = pFieldDict->GetDirectObjectFor("FT"); if (pFTValue) pParent->SetFor("FT", pFTValue->Clone()); } if (pFieldDict->KeyExist("Ff")) { CPDF_Object* pFfValue = pFieldDict->GetDirectObjectFor("Ff"); if (pFfValue) pParent->SetFor("Ff", pFfValue->Clone()); } } pField = new CPDF_FormField(this, pParent); CPDF_Object* pTObj = pDict->GetObjectFor("T"); if (ToReference(pTObj)) { std::unique_ptr<CPDF_Object> pClone = pTObj->CloneDirectObject(); if (pClone) pDict->SetFor("T", std::move(pClone)); else pDict->SetNewFor<CPDF_Name>("T", ""); } m_pFieldTree->SetField(csWName, pField); } CPDF_Array* pKids = pFieldDict->GetArrayFor("Kids"); if (pKids) { for (size_t i = 0; i < pKids->GetCount(); i++) { CPDF_Dictionary* pKid = pKids->GetDictAt(i); if (!pKid) continue; if (pKid->GetStringFor("Subtype") != "Widget") continue; AddControl(pField, pKid); } } else { if (pFieldDict->GetStringFor("Subtype") == "Widget") AddControl(pField, pFieldDict); } return pField; }
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->GetElement("Contents") : nullptr; if (!pContentObj) pContentObj = pPageDic ? pPageDic->GetArrayBy("Contents") : nullptr; 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 = new CPDF_Dictionary; CPDF_Stream* pStream = new CPDF_Stream(nullptr, 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 = nullptr; if (CPDF_Array* pArray = ToArray(pContentObj)) { pContentArray = pArray; CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum()); pContentArray->InsertAt(0, pRef); } else if (CPDF_Reference* pReference = ToReference(pContentObj)) { CPDF_Object* pDirectObj = pReference->GetDirect(); if (pDirectObj) { if (CPDF_Array* pArray = pDirectObj->AsArray()) { pContentArray = pArray; CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum()); pContentArray->InsertAt(0, pRef); } else if (pDirectObj->IsStream()) { pContentArray = new CPDF_Array(); pContentArray->AddReference(pDoc, pStream->GetObjNum()); pContentArray->AddReference(pDoc, pDirectObj->GetObjNum()); pPageDic->SetAtReference("Contents", pDoc, pDoc->AddIndirectObject(pContentArray)); } } } }
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()); } }
CPDF_FormField* CPDF_InterForm::AddTerminalField(CPDF_Dictionary* pFieldDict) { if (!pFieldDict->KeyExist(FX_BSTRC("T"))) { return NULL; } CPDF_Dictionary* pDict = pFieldDict; CFX_WideString csWName = GetFullName(pFieldDict); if (csWName.IsEmpty()) { return NULL; } CPDF_FormField* pField = NULL; pField = m_pFieldTree->GetField(csWName); if (pField == NULL) { CPDF_Dictionary* pParent = pFieldDict; if (!pFieldDict->KeyExist(FX_BSTRC("T")) && pFieldDict->GetString(FX_BSTRC("Subtype")) == FX_BSTRC("Widget")) { pParent = pFieldDict->GetDict(FX_BSTRC("Parent")); if (!pParent) { pParent = pFieldDict; } } if (pParent && pParent != pFieldDict && !pParent->KeyExist(FX_BSTRC("FT"))) { if (pFieldDict->KeyExist(FX_BSTRC("FT"))) { CPDF_Object* pFTValue = pFieldDict->GetElementValue(FX_BSTRC("FT")); if (pFTValue) { pParent->SetAt(FX_BSTRC("FT"), pFTValue->Clone()); } } if (pFieldDict->KeyExist(FX_BSTRC("Ff"))) { CPDF_Object* pFfValue = pFieldDict->GetElementValue(FX_BSTRC("Ff")); if (pFfValue) { pParent->SetAt(FX_BSTRC("Ff"), pFfValue->Clone()); } } } pField = new CPDF_FormField(this, pParent); CPDF_Object* pTObj = pDict->GetElement("T"); if (ToReference(pTObj)) { CPDF_Object* pClone = pTObj->Clone(TRUE); if (pClone) pDict->SetAt("T", pClone); else pDict->SetAtName("T", ""); } m_pFieldTree->SetField(csWName, pField); } CPDF_Array* pKids = pFieldDict->GetArray("Kids"); if (pKids == NULL) { if (pFieldDict->GetString("Subtype") == "Widget") { AddControl(pField, pFieldDict); } } else { for (FX_DWORD i = 0; i < pKids->GetCount(); i++) { CPDF_Dictionary* pKid = pKids->GetDict(i); if (pKid == NULL) { continue; } if (pKid->GetString("Subtype") != "Widget") { continue; } AddControl(pField, pKid); } } return pField; }
DLLEXPORT FPDF_BOOL STDCALL FPDFPage_TransFormWithClip(FPDF_PAGE page, FS_MATRIX* matrix, FS_RECTF* clipRect) { CPDF_Page* pPage = CPDFPageFromFPDFPage(page); if (!pPage) 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_Dictionary* pPageDic = pPage->m_pFormDict; CPDF_Object* pContentObj = pPageDic ? pPageDic->GetElement("Contents") : nullptr; if (!pContentObj) pContentObj = pPageDic ? pPageDic->GetArrayBy("Contents") : nullptr; if (!pContentObj) return FALSE; CPDF_Dictionary* pDic = new CPDF_Dictionary; CPDF_Stream* pStream = new CPDF_Stream(nullptr, 0, pDic); pStream->SetData(textBuf.GetBuffer(), textBuf.GetSize(), FALSE, FALSE); CPDF_Document* pDoc = pPage->m_pDocument; if (!pDoc) return FALSE; pDoc->AddIndirectObject(pStream); pDic = new CPDF_Dictionary; CPDF_Stream* pEndStream = new CPDF_Stream(nullptr, 0, pDic); pEndStream->SetData((const uint8_t*)" Q", 2, FALSE, FALSE); pDoc->AddIndirectObject(pEndStream); CPDF_Array* pContentArray = nullptr; if (CPDF_Array* pArray = ToArray(pContentObj)) { pContentArray = pArray; CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum()); pContentArray->InsertAt(0, pRef); pContentArray->AddReference(pDoc, pEndStream); } else if (CPDF_Reference* pReference = ToReference(pContentObj)) { CPDF_Object* pDirectObj = pReference->GetDirect(); if (pDirectObj) { if (CPDF_Array* pArray = pDirectObj->AsArray()) { pContentArray = pArray; CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum()); pContentArray->InsertAt(0, pRef); pContentArray->AddReference(pDoc, pEndStream); } else if (pDirectObj->IsStream()) { pContentArray = 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->GetDictBy("Resources"); if (pRes) { CPDF_Dictionary* pPattenDict = pRes->GetDictBy("Pattern"); if (pPattenDict) { for (const auto& it : *pPattenDict) { CPDF_Object* pObj = it.second; if (pObj->IsReference()) pObj = pObj->GetDirect(); CPDF_Dictionary* pDict = nullptr; if (pObj->IsDictionary()) pDict = pObj->AsDictionary(); else if (CPDF_Stream* pStream = pObj->AsStream()) pDict = pStream->GetDict(); else continue; CFX_Matrix m = pDict->GetMatrixBy("Matrix"); CFX_Matrix t = *(CFX_Matrix*)matrix; m.Concat(t); pDict->SetAtMatrix("Matrix", m); } } } return TRUE; }
CPDF_FormField* CPDF_InterForm::AddTerminalField(CPDF_Dictionary* pFieldDict) { if (!pFieldDict->KeyExist("T")) return nullptr; CPDF_Dictionary* pDict = pFieldDict; CFX_WideString csWName = FPDF_GetFullName(pFieldDict); if (csWName.IsEmpty()) return nullptr; CPDF_FormField* pField = nullptr; pField = m_pFieldTree->GetField(csWName); if (!pField) { CPDF_Dictionary* pParent = pFieldDict; if (!pFieldDict->KeyExist("T") && pFieldDict->GetStringBy("Subtype") == "Widget") { pParent = pFieldDict->GetDictBy("Parent"); if (!pParent) pParent = pFieldDict; } if (pParent && pParent != pFieldDict && !pParent->KeyExist("FT")) { if (pFieldDict->KeyExist("FT")) { CPDF_Object* pFTValue = pFieldDict->GetDirectObjectBy("FT"); if (pFTValue) pParent->SetAt("FT", pFTValue->Clone()); } if (pFieldDict->KeyExist("Ff")) { CPDF_Object* pFfValue = pFieldDict->GetDirectObjectBy("Ff"); if (pFfValue) pParent->SetAt("Ff", pFfValue->Clone()); } } pField = new CPDF_FormField(this, pParent); CPDF_Object* pTObj = pDict->GetObjectBy("T"); if (ToReference(pTObj)) { CPDF_Object* pClone = pTObj->CloneDirectObject(); if (pClone) pDict->SetAt("T", pClone); else pDict->SetAtName("T", ""); } m_pFieldTree->SetField(csWName, pField); } CPDF_Array* pKids = pFieldDict->GetArrayBy("Kids"); if (!pKids) { if (pFieldDict->GetStringBy("Subtype") == "Widget") AddControl(pField, pFieldDict); } else { for (size_t i = 0; i < pKids->GetCount(); i++) { CPDF_Dictionary* pKid = pKids->GetDictAt(i); if (!pKid) continue; if (pKid->GetStringBy("Subtype") != "Widget") continue; AddControl(pField, pKid); } } return pField; }