FX_BOOL CPDF_PageOrganizer::PDFDocInit(CPDF_Document* pDestPDFDoc, CPDF_Document* pSrcPDFDoc) { if (!pDestPDFDoc || !pSrcPDFDoc) return FALSE; CPDF_Dictionary* pNewRoot = pDestPDFDoc->GetRoot(); if (!pNewRoot) return FALSE; CPDF_Dictionary* DInfoDict = pDestPDFDoc->GetInfo(); if (!DInfoDict) return FALSE; CFX_ByteString producerstr; producerstr.Format("PDFium"); DInfoDict->SetFor("Producer", new CPDF_String(producerstr, FALSE)); CFX_ByteString cbRootType = pNewRoot->GetStringFor("Type", ""); if (cbRootType.IsEmpty()) pNewRoot->SetFor("Type", new CPDF_Name("Catalog")); CPDF_Object* pElement = pNewRoot->GetObjectFor("Pages"); CPDF_Dictionary* pNewPages = pElement ? ToDictionary(pElement->GetDirect()) : nullptr; if (!pNewPages) { pNewPages = new CPDF_Dictionary(pDestPDFDoc->GetByteStringPool()); pNewRoot->SetReferenceFor("Pages", pDestPDFDoc, pDestPDFDoc->AddIndirectObject(pNewPages)); } CFX_ByteString cbPageType = pNewPages->GetStringFor("Type", ""); if (cbPageType == "") { pNewPages->SetFor("Type", new CPDF_Name("Pages")); } if (!pNewPages->GetArrayFor("Kids")) { pNewPages->SetIntegerFor("Count", 0); pNewPages->SetReferenceFor("Kids", pDestPDFDoc, pDestPDFDoc->AddIndirectObject(new CPDF_Array)); } return TRUE; }
void CPDF_Document::CreateNewDoc() { ASSERT(!m_pRootDict && !m_pInfoDict); m_pRootDict = new CPDF_Dictionary(m_pByteStringPool); m_pRootDict->SetNameFor("Type", "Catalog"); AddIndirectObject(m_pRootDict); CPDF_Dictionary* pPages = new CPDF_Dictionary(m_pByteStringPool); pPages->SetNameFor("Type", "Pages"); pPages->SetNumberFor("Count", 0); pPages->SetFor("Kids", new CPDF_Array); m_pRootDict->SetReferenceFor("Pages", this, AddIndirectObject(pPages)); m_pInfoDict = new CPDF_Dictionary(m_pByteStringPool); AddIndirectObject(m_pInfoDict); }
FPDF_EXPORT void FPDF_CALLCONV FPDFPage_InsertClipPath(FPDF_PAGE page, FPDF_CLIPPATH clipPath) { CPDF_Page* pPage = CPDFPageFromFPDFPage(page); if (!pPage) return; CPDF_Dictionary* pPageDict = pPage->GetDict(); CPDF_Object* pContentObj = GetPageContent(pPageDict); if (!pContentObj) return; std::ostringstream strClip; CPDF_ClipPath* pClipPath = CPDFClipPathFromFPDFClipPath(clipPath); for (size_t i = 0; i < pClipPath->GetPathCount(); ++i) { CPDF_Path path = pClipPath->GetPath(i); if (path.GetPoints().empty()) { // Empty clipping (totally clipped out) strClip << "0 0 m W n "; } else { OutputPath(strClip, path); if (pClipPath->GetClipType(i) == FXFILL_WINDING) strClip << "W n\n"; else strClip << "W* n\n"; } } CPDF_Document* pDoc = pPage->GetDocument(); if (!pDoc) return; CPDF_Stream* pStream = pDoc->NewIndirect<CPDF_Stream>(nullptr, 0, pDoc->New<CPDF_Dictionary>()); pStream->SetDataFromStringstream(&strClip); if (CPDF_Array* pArray = ToArray(pContentObj)) { pArray->InsertAt(0, pStream->MakeReference(pDoc)); } else if (pContentObj->IsStream() && !pContentObj->IsInline()) { CPDF_Array* pContentArray = pDoc->NewIndirect<CPDF_Array>(); pContentArray->Add(pStream->MakeReference(pDoc)); pContentArray->Add(pContentObj->MakeReference(pDoc)); pPageDict->SetFor(pdfium::page_object::kContents, pContentArray->MakeReference(pDoc)); } }
DLLEXPORT FPDF_BOOL STDCALL FPDF_CopyViewerPreferences(FPDF_DOCUMENT dest_doc, FPDF_DOCUMENT src_doc) { CPDF_Document* pDstDoc = CPDFDocumentFromFPDFDocument(dest_doc); if (!pDstDoc) return FALSE; CPDF_Document* pSrcDoc = CPDFDocumentFromFPDFDocument(src_doc); if (!pSrcDoc) return FALSE; CPDF_Dictionary* pSrcDict = pSrcDoc->GetRoot(); pSrcDict = pSrcDict->GetDictFor("ViewerPreferences"); if (!pSrcDict) return FALSE; CPDF_Dictionary* pDstDict = pDstDoc->GetRoot(); if (!pDstDict) return FALSE; pDstDict->SetFor("ViewerPreferences", pSrcDict->CloneDirectObject()); return TRUE; }
size_t CPDF_Document::CalculateEncodingDict(int charset, CPDF_Dictionary* pBaseDict) { size_t i; for (i = 0; i < FX_ArraySize(g_FX_CharsetUnicodes); ++i) { if (g_FX_CharsetUnicodes[i].m_Charset == charset) break; } if (i == FX_ArraySize(g_FX_CharsetUnicodes)) return i; CPDF_Dictionary* pEncodingDict = new CPDF_Dictionary(m_pByteStringPool); pEncodingDict->SetNameFor("BaseEncoding", "WinAnsiEncoding"); CPDF_Array* pArray = new CPDF_Array; pArray->AddInteger(128); const uint16_t* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes; for (int j = 0; j < 128; j++) { CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]); pArray->AddName(name.IsEmpty() ? ".notdef" : name); } pEncodingDict->SetFor("Differences", pArray); pBaseDict->SetReferenceFor("Encoding", this, AddIndirectObject(pEncodingDict)); return i; }
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPage_TransFormWithClip(FPDF_PAGE page, const FS_MATRIX* matrix, const FS_RECTF* clipRect) { if (!matrix && !clipRect) return false; CPDF_Page* pPage = CPDFPageFromFPDFPage(page); if (!pPage) return false; std::ostringstream textBuf; textBuf << "q "; if (clipRect) { CFX_FloatRect rect = CFXFloatRectFromFSRECTF(*clipRect); rect.Normalize(); textBuf << ByteString::Format("%f %f %f %f re W* n ", rect.left, rect.bottom, rect.Width(), rect.Height()); } if (matrix) { textBuf << ByteString::Format("%f %f %f %f %f %f cm ", matrix->a, matrix->b, matrix->c, matrix->d, matrix->e, matrix->f); } CPDF_Dictionary* pPageDict = pPage->GetDict(); CPDF_Object* pContentObj = GetPageContent(pPageDict); if (!pContentObj) return false; CPDF_Document* pDoc = pPage->GetDocument(); if (!pDoc) return false; CPDF_Stream* pStream = pDoc->NewIndirect<CPDF_Stream>(nullptr, 0, pDoc->New<CPDF_Dictionary>()); pStream->SetDataFromStringstream(&textBuf); CPDF_Stream* pEndStream = pDoc->NewIndirect<CPDF_Stream>(nullptr, 0, pDoc->New<CPDF_Dictionary>()); pEndStream->SetData(ByteStringView(" Q").span()); if (CPDF_Array* pContentArray = ToArray(pContentObj)) { pContentArray->InsertAt(0, pStream->MakeReference(pDoc)); pContentArray->Add(pEndStream->MakeReference(pDoc)); } else if (pContentObj->IsStream() && !pContentObj->IsInline()) { pContentArray = pDoc->NewIndirect<CPDF_Array>(); pContentArray->Add(pStream->MakeReference(pDoc)); pContentArray->Add(pContentObj->MakeReference(pDoc)); pContentArray->Add(pEndStream->MakeReference(pDoc)); pPageDict->SetFor(pdfium::page_object::kContents, pContentArray->MakeReference(pDoc)); } // Need to transform the patterns as well. CPDF_Dictionary* pRes = pPageDict->GetDictFor(pdfium::page_object::kResources); if (!pRes) return true; CPDF_Dictionary* pPatternDict = pRes->GetDictFor("Pattern"); if (!pPatternDict) return true; CPDF_DictionaryLocker locker(pPatternDict); for (const auto& it : locker) { CPDF_Object* pObj = it.second.get(); if (pObj->IsReference()) pObj = pObj->GetDirect(); CPDF_Dictionary* pDict = nullptr; if (pObj->IsDictionary()) pDict = pObj->AsDictionary(); else if (CPDF_Stream* pObjStream = pObj->AsStream()) pDict = pObjStream->GetDict(); else continue; if (matrix) { CFX_Matrix m = CFXMatrixFromFSMatrix(*matrix); pDict->SetMatrixFor("Matrix", pDict->GetMatrixFor("Matrix") * m); } } return true; }
std::unique_ptr<CFDF_Document> CPDF_InterForm::ExportToFDF( const CFX_WideStringC& pdf_path, const std::vector<CPDF_FormField*>& fields, bool bIncludeOrExclude, bool bSimpleFileSpec) const { std::unique_ptr<CFDF_Document> pDoc = CFDF_Document::CreateNewDoc(); if (!pDoc) return nullptr; CPDF_Dictionary* pMainDict = pDoc->GetRoot()->GetDictFor("FDF"); if (!pdf_path.IsEmpty()) { if (bSimpleFileSpec) { CFX_WideString wsFilePath = CPDF_FileSpec::EncodeFileName(pdf_path); pMainDict->SetNewFor<CPDF_String>( "F", CFX_ByteString::FromUnicode(wsFilePath), false); pMainDict->SetNewFor<CPDF_String>("UF", PDF_EncodeText(wsFilePath), false); } else { CPDF_FileSpec filespec(pDoc->GetByteStringPool()); filespec.SetFileName(pdf_path); pMainDict->SetFor("F", pdfium::WrapUnique(filespec.GetObj())); } } CPDF_Array* pFields = pMainDict->SetNewFor<CPDF_Array>("Fields"); size_t nCount = m_pFieldTree->m_Root.CountFields(); for (size_t i = 0; i < nCount; ++i) { CPDF_FormField* pField = m_pFieldTree->m_Root.GetFieldAtIndex(i); if (!pField || pField->GetType() == CPDF_FormField::PushButton) continue; uint32_t dwFlags = pField->GetFieldFlags(); if (dwFlags & 0x04) continue; if (bIncludeOrExclude == pdfium::ContainsValue(fields, pField)) { if ((dwFlags & 0x02) != 0 && pField->m_pDict->GetStringFor("V").IsEmpty()) continue; CFX_WideString fullname = FPDF_GetFullName(pField->GetFieldDict()); auto pFieldDict = pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool()); pFieldDict->SetNewFor<CPDF_String>("T", fullname); if (pField->GetType() == CPDF_FormField::CheckBox || pField->GetType() == CPDF_FormField::RadioButton) { CFX_WideString csExport = pField->GetCheckValue(false); CFX_ByteString csBExport = PDF_EncodeText(csExport); CPDF_Object* pOpt = FPDF_GetFieldAttr(pField->m_pDict, "Opt"); if (pOpt) pFieldDict->SetNewFor<CPDF_String>("V", csBExport, false); else pFieldDict->SetNewFor<CPDF_Name>("V", csBExport); } else { CPDF_Object* pV = FPDF_GetFieldAttr(pField->m_pDict, "V"); if (pV) pFieldDict->SetFor("V", pV->CloneDirectObject()); } pFields->Add(std::move(pFieldDict)); } } return pDoc; }
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; }
CPDF_Dictionary* CPDF_Document::ProcessbCJK( CPDF_Dictionary* pBaseDict, int charset, FX_BOOL bVert, CFX_ByteString basefont, std::function<void(FX_WCHAR, FX_WCHAR, CPDF_Array*)> Insert) { CPDF_Dictionary* pFontDict = new CPDF_Dictionary(m_pByteStringPool); CFX_ByteString cmap; CFX_ByteString ordering; int supplement = 0; CPDF_Array* pWidthArray = new CPDF_Array; switch (charset) { case FXFONT_CHINESEBIG5_CHARSET: cmap = bVert ? "ETenms-B5-V" : "ETenms-B5-H"; ordering = "CNS1"; supplement = 4; pWidthArray->AddInteger(1); Insert(0x20, 0x7e, pWidthArray); break; case FXFONT_GB2312_CHARSET: cmap = bVert ? "GBK-EUC-V" : "GBK-EUC-H"; ordering = "GB1"; supplement = 2; pWidthArray->AddInteger(7716); Insert(0x20, 0x20, pWidthArray); pWidthArray->AddInteger(814); Insert(0x21, 0x7e, pWidthArray); break; case FXFONT_HANGUL_CHARSET: cmap = bVert ? "KSCms-UHC-V" : "KSCms-UHC-H"; ordering = "Korea1"; supplement = 2; pWidthArray->AddInteger(1); Insert(0x20, 0x7e, pWidthArray); break; case FXFONT_SHIFTJIS_CHARSET: cmap = bVert ? "90ms-RKSJ-V" : "90ms-RKSJ-H"; ordering = "Japan1"; supplement = 5; pWidthArray->AddInteger(231); Insert(0x20, 0x7d, pWidthArray); pWidthArray->AddInteger(326); Insert(0xa0, 0xa0, pWidthArray); pWidthArray->AddInteger(327); Insert(0xa1, 0xdf, pWidthArray); pWidthArray->AddInteger(631); Insert(0x7e, 0x7e, pWidthArray); break; } pBaseDict->SetNameFor("Subtype", "Type0"); pBaseDict->SetNameFor("BaseFont", basefont); pBaseDict->SetNameFor("Encoding", cmap); pFontDict->SetFor("W", pWidthArray); pFontDict->SetNameFor("Type", "Font"); pFontDict->SetNameFor("Subtype", "CIDFontType2"); pFontDict->SetNameFor("BaseFont", basefont); CPDF_Dictionary* pCIDSysInfo = new CPDF_Dictionary(m_pByteStringPool); pCIDSysInfo->SetStringFor("Registry", "Adobe"); pCIDSysInfo->SetStringFor("Ordering", ordering); pCIDSysInfo->SetIntegerFor("Supplement", supplement); pFontDict->SetFor("CIDSystemInfo", pCIDSysInfo); CPDF_Array* pArray = new CPDF_Array; pBaseDict->SetFor("DescendantFonts", pArray); pArray->AddReference(this, AddIndirectObject(pFontDict)); return pFontDict; }
DLLEXPORT int STDCALL FPDFPage_Flatten(FPDF_PAGE page, int nFlag) { CPDF_Page* pPage = CPDFPageFromFPDFPage(page); if (!page) { return FLATTEN_FAIL; } CPDF_Document* pDocument = pPage->m_pDocument; CPDF_Dictionary* pPageDict = pPage->m_pFormDict; if (!pDocument || !pPageDict) { return FLATTEN_FAIL; } CPDF_ObjectArray ObjectArray; CPDF_RectArray RectArray; int iRet = FLATTEN_FAIL; iRet = ParserAnnots(pDocument, pPageDict, &RectArray, &ObjectArray, nFlag); if (iRet == FLATTEN_NOTHINGTODO || iRet == FLATTEN_FAIL) return iRet; CFX_FloatRect rcOriginalCB; CFX_FloatRect rcMerger = CalculateRect(&RectArray); CFX_FloatRect rcOriginalMB = pPageDict->GetRectFor("MediaBox"); if (pPageDict->KeyExist("CropBox")) rcOriginalMB = pPageDict->GetRectFor("CropBox"); if (rcOriginalMB.IsEmpty()) { rcOriginalMB = CFX_FloatRect(0.0f, 0.0f, 612.0f, 792.0f); } rcMerger.left = rcMerger.left < rcOriginalMB.left ? rcOriginalMB.left : rcMerger.left; rcMerger.right = rcMerger.right > rcOriginalMB.right ? rcOriginalMB.right : rcMerger.right; rcMerger.top = rcMerger.top > rcOriginalMB.top ? rcOriginalMB.top : rcMerger.top; rcMerger.bottom = rcMerger.bottom < rcOriginalMB.bottom ? rcOriginalMB.bottom : rcMerger.bottom; if (pPageDict->KeyExist("ArtBox")) rcOriginalCB = pPageDict->GetRectFor("ArtBox"); else rcOriginalCB = rcOriginalMB; if (!rcOriginalMB.IsEmpty()) { CPDF_Array* pMediaBox = new CPDF_Array(); pMediaBox->Add(new CPDF_Number(rcOriginalMB.left)); pMediaBox->Add(new CPDF_Number(rcOriginalMB.bottom)); pMediaBox->Add(new CPDF_Number(rcOriginalMB.right)); pMediaBox->Add(new CPDF_Number(rcOriginalMB.top)); pPageDict->SetFor("MediaBox", pMediaBox); } if (!rcOriginalCB.IsEmpty()) { CPDF_Array* pCropBox = new CPDF_Array(); pCropBox->Add(new CPDF_Number(rcOriginalCB.left)); pCropBox->Add(new CPDF_Number(rcOriginalCB.bottom)); pCropBox->Add(new CPDF_Number(rcOriginalCB.right)); pCropBox->Add(new CPDF_Number(rcOriginalCB.top)); pPageDict->SetFor("ArtBox", pCropBox); } CPDF_Dictionary* pRes = pPageDict->GetDictFor("Resources"); if (!pRes) { pRes = new CPDF_Dictionary(pDocument->GetByteStringPool()); pPageDict->SetFor("Resources", pRes); } CPDF_Stream* pNewXObject = new CPDF_Stream( nullptr, 0, new CPDF_Dictionary(pDocument->GetByteStringPool())); uint32_t dwObjNum = pDocument->AddIndirectObject(pNewXObject); CPDF_Dictionary* pPageXObject = pRes->GetDictFor("XObject"); if (!pPageXObject) { pPageXObject = new CPDF_Dictionary(pDocument->GetByteStringPool()); pRes->SetFor("XObject", pPageXObject); } CFX_ByteString key = ""; int nStreams = ObjectArray.GetSize(); if (nStreams > 0) { for (int iKey = 0; /*iKey < 100*/; iKey++) { char sExtend[5] = {}; FXSYS_itoa(iKey, sExtend, 10); key = CFX_ByteString("FFT") + CFX_ByteString(sExtend); if (!pPageXObject->KeyExist(key)) break; } } SetPageContents(key, pPageDict, pDocument); CPDF_Dictionary* pNewXORes = nullptr; if (!key.IsEmpty()) { pPageXObject->SetReferenceFor(key, pDocument, dwObjNum); CPDF_Dictionary* pNewOXbjectDic = pNewXObject->GetDict(); pNewXORes = new CPDF_Dictionary(pDocument->GetByteStringPool()); pNewOXbjectDic->SetFor("Resources", pNewXORes); pNewOXbjectDic->SetNameFor("Type", "XObject"); pNewOXbjectDic->SetNameFor("Subtype", "Form"); pNewOXbjectDic->SetIntegerFor("FormType", 1); pNewOXbjectDic->SetNameFor("Name", "FRM"); CFX_FloatRect rcBBox = pPageDict->GetRectFor("ArtBox"); pNewOXbjectDic->SetRectFor("BBox", rcBBox); } for (int i = 0; i < nStreams; i++) { CPDF_Dictionary* pAnnotDic = ObjectArray.GetAt(i); if (!pAnnotDic) continue; CFX_FloatRect rcAnnot = pAnnotDic->GetRectFor("Rect"); rcAnnot.Normalize(); CFX_ByteString sAnnotState = pAnnotDic->GetStringFor("AS"); CPDF_Dictionary* pAnnotAP = pAnnotDic->GetDictFor("AP"); if (!pAnnotAP) continue; CPDF_Stream* pAPStream = pAnnotAP->GetStreamFor("N"); if (!pAPStream) { CPDF_Dictionary* pAPDic = pAnnotAP->GetDictFor("N"); if (!pAPDic) continue; if (!sAnnotState.IsEmpty()) { pAPStream = pAPDic->GetStreamFor(sAnnotState); } else { auto it = pAPDic->begin(); if (it != pAPDic->end()) { CPDF_Object* pFirstObj = it->second; if (pFirstObj) { if (pFirstObj->IsReference()) pFirstObj = pFirstObj->GetDirect(); if (!pFirstObj->IsStream()) continue; pAPStream = pFirstObj->AsStream(); } } } } if (!pAPStream) continue; CPDF_Dictionary* pAPDic = pAPStream->GetDict(); CFX_Matrix matrix = pAPDic->GetMatrixFor("Matrix"); CFX_FloatRect rcStream; if (pAPDic->KeyExist("Rect")) rcStream = pAPDic->GetRectFor("Rect"); else if (pAPDic->KeyExist("BBox")) rcStream = pAPDic->GetRectFor("BBox"); if (rcStream.IsEmpty()) continue; CPDF_Object* pObj = pAPStream; if (pObj) { CPDF_Dictionary* pObjDic = pObj->GetDict(); if (pObjDic) { pObjDic->SetNameFor("Type", "XObject"); pObjDic->SetNameFor("Subtype", "Form"); } } CPDF_Dictionary* pXObject = pNewXORes->GetDictFor("XObject"); if (!pXObject) { pXObject = new CPDF_Dictionary(pDocument->GetByteStringPool()); pNewXORes->SetFor("XObject", pXObject); } CFX_ByteString sFormName; sFormName.Format("F%d", i); pXObject->SetReferenceFor(sFormName, pDocument, pDocument->AddIndirectObject(pObj)); CPDF_StreamAcc acc; acc.LoadAllData(pNewXObject); const uint8_t* pData = acc.GetData(); CFX_ByteString sStream(pData, acc.GetSize()); if (matrix.IsIdentity()) { matrix.a = 1.0f; matrix.b = 0.0f; matrix.c = 0.0f; matrix.d = 1.0f; matrix.e = 0.0f; matrix.f = 0.0f; } CFX_ByteString sTemp; CFX_Matrix m = GetMatrix(rcAnnot, rcStream, matrix); sTemp.Format("q %f 0 0 %f %f %f cm /%s Do Q\n", m.a, m.d, m.e, m.f, sFormName.c_str()); sStream += sTemp; pNewXObject->SetData(sStream.raw_str(), sStream.GetLength()); } pPageDict->RemoveFor("Annots"); ObjectArray.RemoveAll(); RectArray.RemoveAll(); return FLATTEN_SUCCESS; }
FX_BOOL CPDF_PageOrganizer::ExportPage(CPDF_Document* pSrcPDFDoc, std::vector<uint16_t>* pPageNums, CPDF_Document* pDestPDFDoc, int nIndex) { int curpage = nIndex; std::unique_ptr<ObjectNumberMap> pObjNumberMap(new ObjectNumberMap); int nSize = pdfium::CollectionSize<int>(*pPageNums); for (int i = 0; i < nSize; ++i) { CPDF_Dictionary* pCurPageDict = pDestPDFDoc->CreateNewPage(curpage); CPDF_Dictionary* pSrcPageDict = pSrcPDFDoc->GetPage(pPageNums->at(i) - 1); if (!pSrcPageDict || !pCurPageDict) return FALSE; // Clone the page dictionary for (const auto& it : *pSrcPageDict) { const CFX_ByteString& cbSrcKeyStr = it.first; CPDF_Object* pObj = it.second; if (cbSrcKeyStr.Compare(("Type")) && cbSrcKeyStr.Compare(("Parent"))) { if (pCurPageDict->KeyExist(cbSrcKeyStr)) pCurPageDict->RemoveFor(cbSrcKeyStr); pCurPageDict->SetFor(cbSrcKeyStr, pObj->Clone()); } } // inheritable item CPDF_Object* pInheritable = nullptr; // 1 MediaBox //required if (!pCurPageDict->KeyExist("MediaBox")) { pInheritable = PageDictGetInheritableTag(pSrcPageDict, "MediaBox"); if (!pInheritable) { // Search the "CropBox" from source page dictionary, // if not exists,we take the letter size. pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox"); if (pInheritable) { pCurPageDict->SetFor("MediaBox", pInheritable->Clone()); } else { // Make the default size to be letter size (8.5'x11') CPDF_Array* pArray = new CPDF_Array; pArray->AddNumber(0); pArray->AddNumber(0); pArray->AddNumber(612); pArray->AddNumber(792); pCurPageDict->SetFor("MediaBox", pArray); } } else { pCurPageDict->SetFor("MediaBox", pInheritable->Clone()); } } // 2 Resources //required if (!pCurPageDict->KeyExist("Resources")) { pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Resources"); if (!pInheritable) return FALSE; pCurPageDict->SetFor("Resources", pInheritable->Clone()); } // 3 CropBox //Optional if (!pCurPageDict->KeyExist("CropBox")) { pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox"); if (pInheritable) pCurPageDict->SetFor("CropBox", pInheritable->Clone()); } // 4 Rotate //Optional if (!pCurPageDict->KeyExist("Rotate")) { pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Rotate"); if (pInheritable) pCurPageDict->SetFor("Rotate", pInheritable->Clone()); } // Update the reference uint32_t dwOldPageObj = pSrcPageDict->GetObjNum(); uint32_t dwNewPageObj = pCurPageDict->GetObjNum(); (*pObjNumberMap)[dwOldPageObj] = dwNewPageObj; UpdateReference(pCurPageDict, pDestPDFDoc, pObjNumberMap.get()); ++curpage; } return TRUE; }