DLLEXPORT FPDF_PAGE STDCALL FPDFPage_New(FPDF_DOCUMENT document, int page_index, double width, double height) { CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc) return nullptr; if (page_index < 0) page_index = 0; if (pDoc->GetPageCount() < page_index) page_index = pDoc->GetPageCount(); CPDF_Dictionary* pPageDict = pDoc->CreateNewPage(page_index); if (!pPageDict) return NULL; CPDF_Array* pMediaBoxArray = new CPDF_Array; pMediaBoxArray->Add(new CPDF_Number(0)); pMediaBoxArray->Add(new CPDF_Number(0)); pMediaBoxArray->Add(new CPDF_Number(FX_FLOAT(width))); pMediaBoxArray->Add(new CPDF_Number(FX_FLOAT(height))); pPageDict->SetAt("MediaBox", pMediaBoxArray); pPageDict->SetAt("Rotate", new CPDF_Number(0)); pPageDict->SetAt("Resources", new CPDF_Dictionary); CPDF_Page* pPage = new CPDF_Page; pPage->Load(pDoc, pPageDict); pPage->ParseContent(); return pPage; }
DLLEXPORT FPDF_PAGE STDCALL FPDFPage_New(FPDF_DOCUMENT document, int page_index, double width, double height) { CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc) return nullptr; page_index = std::min(std::max(page_index, 0), pDoc->GetPageCount()); CPDF_Dictionary* pPageDict = pDoc->CreateNewPage(page_index); if (!pPageDict) return nullptr; CPDF_Array* pMediaBoxArray = new CPDF_Array; pMediaBoxArray->Add(new CPDF_Number(0)); pMediaBoxArray->Add(new CPDF_Number(0)); pMediaBoxArray->Add(new CPDF_Number(FX_FLOAT(width))); pMediaBoxArray->Add(new CPDF_Number(FX_FLOAT(height))); pPageDict->SetAt("MediaBox", pMediaBoxArray); pPageDict->SetAt("Rotate", new CPDF_Number(0)); pPageDict->SetAt("Resources", new CPDF_Dictionary); #ifdef PDF_ENABLE_XFA CPDFXFA_Page* pPage = new CPDFXFA_Page((CPDFXFA_Document*)document, page_index); pPage->LoadPDFPage(pPageDict); #else // PDF_ENABLE_XFA CPDF_Page* pPage = new CPDF_Page(pDoc, pPageDict, true); pPage->ParseContent(); #endif // PDF_ENABLE_XFA return pPage; }
DLLEXPORT FPDF_PAGE STDCALL FPDFPage_New(FPDF_DOCUMENT document, int page_index, double width, double height) { if (!document) return NULL; // CPDF_Parser* pParser = (CPDF_Parser*)document; CPDF_Document* pDoc = (CPDF_Document*)document; if(page_index < 0) page_index = 0; if(pDoc->GetPageCount()<page_index) page_index = pDoc->GetPageCount(); // if (page_index < 0 || page_index >= pDoc->GetPageCount()) // return NULL; CPDF_Dictionary* pPageDict = pDoc->CreateNewPage(page_index); if(!pPageDict) return NULL; CPDF_Array* pMediaBoxArray = FX_NEW CPDF_Array; pMediaBoxArray->Add(FX_NEW CPDF_Number(0)); pMediaBoxArray->Add(FX_NEW CPDF_Number(0)); pMediaBoxArray->Add(FX_NEW CPDF_Number(FX_FLOAT(width))); pMediaBoxArray->Add(FX_NEW CPDF_Number(FX_FLOAT(height))); pPageDict->SetAt("MediaBox", pMediaBoxArray); pPageDict->SetAt("Rotate", FX_NEW CPDF_Number(0)); pPageDict->SetAt("Resources", FX_NEW CPDF_Dictionary); CPDF_Page* pPage = FX_NEW CPDF_Page; pPage->Load(pDoc,pPageDict); pPage->ParseContent(); return pPage; }
DLLEXPORT void STDCALL FPDFPage_SetMediaBox(FPDF_PAGE page, float left, float bottom, float right, float top) { if(!page) return; CPDF_Page* pPage = (CPDF_Page*)page; CPDF_Dictionary* pPageDict = pPage->m_pFormDict; CPDF_Array* pMediaBoxArray = FX_NEW CPDF_Array; pMediaBoxArray->Add(FX_NEW CPDF_Number(left)); pMediaBoxArray->Add(FX_NEW CPDF_Number(bottom)); pMediaBoxArray->Add(FX_NEW CPDF_Number(FX_FLOAT(right))); pMediaBoxArray->Add(FX_NEW CPDF_Number(FX_FLOAT(top))); pPageDict->SetAt("MediaBox", pMediaBoxArray); }
CFDF_Document* CPDF_InterForm::ExportToFDF( const CFX_WideStringC& pdf_path, const std::vector<CPDF_FormField*>& fields, bool bIncludeOrExclude, bool bSimpleFileSpec) const { CFDF_Document* pDoc = CFDF_Document::CreateNewDoc(); if (!pDoc) return nullptr; CPDF_Dictionary* pMainDict = pDoc->GetRoot()->GetDictBy("FDF"); if (!pdf_path.IsEmpty()) { if (bSimpleFileSpec) { CFX_WideString wsFilePath = CPDF_FileSpec::EncodeFileName(pdf_path); pMainDict->SetAtString("F", CFX_ByteString::FromUnicode(wsFilePath)); pMainDict->SetAtString("UF", PDF_EncodeText(wsFilePath)); } else { CPDF_FileSpec filespec; filespec.SetFileName(pdf_path); pMainDict->SetAt("F", filespec.GetObj()); } } CPDF_Array* pFields = new CPDF_Array; pMainDict->SetAt("Fields", pFields); int nCount = m_pFieldTree->m_Root.CountFields(); for (int i = 0; i < nCount; i++) { CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(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->GetStringBy("V").IsEmpty()) continue; CFX_WideString fullname = FPDF_GetFullName(pField->GetFieldDict()); CPDF_Dictionary* pFieldDict = new CPDF_Dictionary; pFieldDict->SetAt("T", new CPDF_String(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->SetAtString("V", csBExport); else pFieldDict->SetAtName("V", csBExport); } else { CPDF_Object* pV = FPDF_GetFieldAttr(pField->m_pDict, "V"); if (pV) pFieldDict->SetAt("V", pV->CloneDirectObject()); } pFields->Add(pFieldDict); } } return pDoc; }
static int InsertNewPage(CPDF_Document* pDoc, int iPage, CPDF_Dictionary* pPageDict, CFX_DWordArray &pageList) { CPDF_Dictionary* pRoot = pDoc->GetRoot(); if (!pRoot) { return -1; } CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages")); if (!pPages) { return -1; } int nPages = pDoc->GetPageCount(); if (iPage < 0 || iPage > nPages) { return -1; } if (iPage == nPages) { CPDF_Array* pPagesList = pPages->GetArray(FX_BSTRC("Kids")); if (!pPagesList) { pPagesList = FX_NEW CPDF_Array; pPages->SetAt(FX_BSTRC("Kids"), pPagesList); } pPagesList->Add(pPageDict, pDoc); pPages->SetAtInteger(FX_BSTRC("Count"), nPages + 1); pPageDict->SetAtReference(FX_BSTRC("Parent"), pDoc, pPages->GetObjNum()); } else { CFX_PtrArray stack; stack.Add(pPages); if (InsertDeletePDFPage(pDoc, pPages, iPage, pPageDict, TRUE, stack) < 0) { return -1; } } pageList.InsertAt(iPage, pPageDict->GetObjNum()); return iPage; }
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)); } }
void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, int32_t iCompress, IFX_FileWrite* pFileWrite, IFX_FileRead* pFileRead, const CFX_DIBitmap* pMask, const CPDF_ImageSetParam* pParam) { int32_t BitmapWidth = pBitmap->GetWidth(); int32_t BitmapHeight = pBitmap->GetHeight(); if (BitmapWidth < 1 || BitmapHeight < 1) { return; } uint8_t* src_buf = pBitmap->GetBuffer(); int32_t src_pitch = pBitmap->GetPitch(); int32_t bpp = pBitmap->GetBPP(); FX_BOOL bUseMatte = pParam && pParam->pMatteColor && (pBitmap->GetFormat() == FXDIB_Argb); CPDF_Dictionary* pDict = new CPDF_Dictionary; pDict->SetAtName("Type", "XObject"); pDict->SetAtName("Subtype", "Image"); pDict->SetAtInteger("Width", BitmapWidth); pDict->SetAtInteger("Height", BitmapHeight); uint8_t* dest_buf = NULL; FX_STRSIZE dest_pitch = 0, dest_size = 0, opType = -1; if (bpp == 1) { int32_t reset_a = 0, reset_r = 0, reset_g = 0, reset_b = 0; int32_t set_a = 0, set_r = 0, set_g = 0, set_b = 0; if (!pBitmap->IsAlphaMask()) { ArgbDecode(pBitmap->GetPaletteArgb(0), reset_a, reset_r, reset_g, reset_b); ArgbDecode(pBitmap->GetPaletteArgb(1), set_a, set_r, set_g, set_b); } if (set_a == 0 || reset_a == 0) { pDict->SetAt("ImageMask", new CPDF_Boolean(TRUE)); if (reset_a == 0) { CPDF_Array* pArray = new CPDF_Array; pArray->AddInteger(1); pArray->AddInteger(0); pDict->SetAt("Decode", pArray); } } else { CPDF_Array* pCS = new CPDF_Array; pCS->AddName("Indexed"); pCS->AddName("DeviceRGB"); pCS->AddInteger(1); CFX_ByteString ct; FX_CHAR* pBuf = ct.GetBuffer(6); pBuf[0] = (FX_CHAR)reset_r; pBuf[1] = (FX_CHAR)reset_g; pBuf[2] = (FX_CHAR)reset_b; pBuf[3] = (FX_CHAR)set_r; pBuf[4] = (FX_CHAR)set_g; pBuf[5] = (FX_CHAR)set_b; ct.ReleaseBuffer(6); pCS->Add(new CPDF_String(ct, TRUE)); pDict->SetAt("ColorSpace", pCS); } pDict->SetAtInteger("BitsPerComponent", 1); dest_pitch = (BitmapWidth + 7) / 8; if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) { opType = 1; } else { opType = 0; } } else if (bpp == 8) { int32_t iPalette = pBitmap->GetPaletteSize(); if (iPalette > 0) { CPDF_Array* pCS = new CPDF_Array; m_pDocument->AddIndirectObject(pCS); pCS->AddName("Indexed"); pCS->AddName("DeviceRGB"); pCS->AddInteger(iPalette - 1); uint8_t* pColorTable = FX_Alloc2D(uint8_t, iPalette, 3); uint8_t* ptr = pColorTable; for (int32_t i = 0; i < iPalette; i++) { FX_DWORD argb = pBitmap->GetPaletteArgb(i); ptr[0] = (uint8_t)(argb >> 16); ptr[1] = (uint8_t)(argb >> 8); ptr[2] = (uint8_t)argb; ptr += 3; } CPDF_Stream* pCTS = new CPDF_Stream(pColorTable, iPalette * 3, new CPDF_Dictionary); m_pDocument->AddIndirectObject(pCTS); pCS->AddReference(m_pDocument, pCTS); pDict->SetAtReference("ColorSpace", m_pDocument, pCS); } else {
CPDF_Object* CPDF_StreamParser::ReadNextObject(FX_BOOL bAllowNestedArray, FX_BOOL bInArray) { FX_BOOL bIsNumber; GetNextWord(bIsNumber); if (m_WordSize == 0) { return NULL; } if (bIsNumber) { m_WordBuffer[m_WordSize] = 0; return CPDF_Number::Create(CFX_ByteStringC(m_WordBuffer, m_WordSize)); } int first_char = m_WordBuffer[0]; if (first_char == '/') { return CPDF_Name::Create(PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))); } if (first_char == '(') { return CPDF_String::Create(ReadString()); } if (first_char == '<') { if (m_WordSize == 1) { return CPDF_String::Create(ReadHexString(), TRUE); } CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); while (1) { GetNextWord(bIsNumber); if (m_WordSize == 0) { pDict->Release(); return NULL; } if (m_WordSize == 2 && m_WordBuffer[0] == '>') { break; } if (m_WordBuffer[0] != '/') { pDict->Release(); return NULL; } CFX_ByteString key = PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)); CPDF_Object* pObj = ReadNextObject(TRUE); if (pObj == NULL) { if (pDict) { pDict->Release(); } return NULL; } if (!key.IsEmpty()) { pDict->SetAt(key, pObj); } else { pObj->Release(); } } return pDict; } if (first_char == '[') { if (!bAllowNestedArray && bInArray) { return NULL; } CPDF_Array* pArray = CPDF_Array::Create(); while (1) { CPDF_Object* pObj = ReadNextObject(bAllowNestedArray, TRUE); if (pObj == NULL) { if (m_WordSize == 0 || m_WordBuffer[0] == ']') { return pArray; } if (m_WordBuffer[0] == '[') { continue; } } else { pArray->Add(pObj); } } } if (m_WordSize == 4) { if (*(FX_DWORD*)m_WordBuffer == FXDWORD_TRUE) { return CPDF_Boolean::Create(TRUE); } if (*(FX_DWORD*)m_WordBuffer == FXDWORD_NULL) { return CPDF_Null::Create(); } } else if (m_WordSize == 5) { if (*(FX_DWORD*)m_WordBuffer == FXDWORD_FALS && m_WordBuffer[4] == 'e') { return CPDF_Boolean::Create(FALSE); } } return NULL; }
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; }
CFDF_Document* CPDF_InterForm::ExportToFDF( const CFX_WideStringC& pdf_path, const std::vector<CPDF_FormField*>& fields, bool bIncludeOrExclude, bool bSimpleFileSpec) const { CFDF_Document* pDoc = CFDF_Document::CreateNewDoc(); if (pDoc == NULL) { return NULL; } CPDF_Dictionary* pMainDict = pDoc->GetRoot()->GetDict("FDF"); if (!pdf_path.IsEmpty()) { if (bSimpleFileSpec) { CFX_WideString wsFilePath = FILESPEC_EncodeFileName(pdf_path); pMainDict->SetAtString(FX_BSTRC("F"), CFX_ByteString::FromUnicode(wsFilePath)); pMainDict->SetAtString(FX_BSTRC("UF"), PDF_EncodeText(wsFilePath)); } else { CPDF_FileSpec filespec; filespec.SetFileName(pdf_path); pMainDict->SetAt("F", static_cast<CPDF_Object*>(filespec)); } } CPDF_Array* pFields = CPDF_Array::Create(); if (pFields == NULL) { return NULL; } pMainDict->SetAt("Fields", pFields); int nCount = m_pFieldTree->m_Root.CountFields(); for (int i = 0; i < nCount; i++) { CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i); if (pField == NULL || pField->GetType() == CPDF_FormField::PushButton) { continue; } FX_DWORD dwFlags = pField->GetFieldFlags(); if (dwFlags & 0x04) continue; auto it = std::find(fields.begin(), fields.end(), pField); if (bIncludeOrExclude == (it != fields.end())) { if ((dwFlags & 0x02) != 0 && pField->m_pDict->GetString("V").IsEmpty()) continue; CFX_WideString fullname = GetFullName(pField->GetFieldDict()); CPDF_Dictionary* pFieldDict = CPDF_Dictionary::Create(); if (!pFieldDict) return nullptr; CPDF_String* pString = CPDF_String::Create(fullname); if (!pString) { pFieldDict->Release(); return nullptr; } pFieldDict->SetAt("T", pString); 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->SetAtString("V", csBExport); else pFieldDict->SetAtName("V", csBExport); } else { CPDF_Object* pV = FPDF_GetFieldAttr(pField->m_pDict, "V"); if (pV) pFieldDict->SetAt("V", pV->Clone(TRUE)); } pFields->Add(pFieldDict); } } return pDoc; }
DLLEXPORT int STDCALL FPDFPage_Flatten( FPDF_PAGE page, int nFlag) { if (!page) { return FLATTEN_FAIL; } CPDF_Page * pPage = (CPDF_Page*)( page ); 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_NOTINGTODO) { return FLATTEN_NOTINGTODO; }else if (iRet == FLATTEN_FAIL) { return FLATTEN_FAIL; } CPDF_Rect rcOriginalCB; CPDF_Rect rcMerger = CalculateRect( &RectArray ); CPDF_Rect rcOriginalMB = pPageDict->GetRect("MediaBox"); if (pPageDict->KeyExist("CropBox")) rcOriginalMB = pPageDict->GetRect("CropBox"); if (rcOriginalMB.IsEmpty()) { rcOriginalMB = CPDF_Rect(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->GetRect("ArtBox"); else rcOriginalCB = rcOriginalMB; if (!rcOriginalMB.IsEmpty()) { CPDF_Array* pMediaBox = FX_NEW CPDF_Array(); pMediaBox->Add(FX_NEW CPDF_Number(rcOriginalMB.left)); pMediaBox->Add(FX_NEW CPDF_Number(rcOriginalMB.bottom)); pMediaBox->Add(FX_NEW CPDF_Number(rcOriginalMB.right)); pMediaBox->Add(FX_NEW CPDF_Number(rcOriginalMB.top)); pPageDict->SetAt("MediaBox",pMediaBox); } if (!rcOriginalCB.IsEmpty()) { CPDF_Array* pCropBox = FX_NEW CPDF_Array(); pCropBox->Add(FX_NEW CPDF_Number(rcOriginalCB.left)); pCropBox->Add(FX_NEW CPDF_Number(rcOriginalCB.bottom)); pCropBox->Add(FX_NEW CPDF_Number(rcOriginalCB.right)); pCropBox->Add(FX_NEW CPDF_Number(rcOriginalCB.top)); pPageDict->SetAt("ArtBox", pCropBox); } CPDF_Dictionary* pRes = NULL; pRes = pPageDict->GetDict("Resources"); if (!pRes) { pRes = FX_NEW CPDF_Dictionary; pPageDict->SetAt( "Resources", pRes ); } CPDF_Stream* pNewXObject = FX_NEW CPDF_Stream(NULL, 0, FX_NEW CPDF_Dictionary); FX_DWORD dwObjNum = pDocument->AddIndirectObject(pNewXObject); CPDF_Dictionary* pPageXObject = pRes->GetDict("XObject"); if (!pPageXObject) { pPageXObject = FX_NEW CPDF_Dictionary; pRes->SetAt("XObject", pPageXObject); } CFX_ByteString key = ""; int nStreams = ObjectArray.GetSize(); if (nStreams > 0) { for (int iKey = 0; /*iKey < 100*/; iKey++) { char sExtend[5] = {0}; FXSYS_itoa(iKey, sExtend, 10); key = CFX_ByteString("FFT") + CFX_ByteString(sExtend); if (!pPageXObject->KeyExist(key)) break; } } SetPageContents(key, pPageDict, pDocument); CPDF_Dictionary* pNewXORes = NULL; if (!key.IsEmpty()) { pPageXObject->SetAtReference(key, pDocument, dwObjNum); CPDF_Dictionary* pNewOXbjectDic = pNewXObject->GetDict(); pNewXORes = FX_NEW CPDF_Dictionary; pNewOXbjectDic->SetAt("Resources", pNewXORes); pNewOXbjectDic->SetAtName("Type", "XObject"); pNewOXbjectDic->SetAtName("Subtype", "Form"); pNewOXbjectDic->SetAtInteger("FormType", 1); pNewOXbjectDic->SetAtName("Name", "FRM"); CPDF_Rect rcBBox = pPageDict->GetRect("ArtBox"); pNewOXbjectDic->SetAtRect("BBox", rcBBox); } for (int i = 0; i < nStreams; i++) { CPDF_Dictionary* pAnnotDic = ObjectArray.GetAt(i); if (!pAnnotDic)continue; CPDF_Rect rcAnnot = pAnnotDic->GetRect("Rect"); rcAnnot.Normalize(); CFX_ByteString sAnnotState = pAnnotDic->GetString("AS"); CPDF_Dictionary* pAnnotAP = pAnnotDic->GetDict("AP"); if (!pAnnotAP)continue; CPDF_Stream* pAPStream = pAnnotAP->GetStream("N"); if (!pAPStream) { CPDF_Dictionary* pAPDic = pAnnotAP->GetDict("N"); if (!pAPDic)continue; if (!sAnnotState.IsEmpty()) { pAPStream = pAPDic->GetStream(sAnnotState); } else { FX_POSITION pos = pAPDic->GetStartPos(); if (pos) { CFX_ByteString sKey; CPDF_Object* pFirstObj = pAPDic->GetNextElement(pos, sKey); if (pFirstObj) { if (pFirstObj->GetType() == PDFOBJ_REFERENCE) pFirstObj = pFirstObj->GetDirect(); if (pFirstObj->GetType() != PDFOBJ_STREAM) continue; pAPStream = (CPDF_Stream*)pFirstObj; } } } } if (!pAPStream)continue; CPDF_Dictionary* pAPDic = pAPStream->GetDict(); CFX_AffineMatrix matrix = pAPDic->GetMatrix("Matrix"); CPDF_Rect rcStream; if (pAPDic->KeyExist("Rect")) rcStream = pAPDic->GetRect("Rect"); else if (pAPDic->KeyExist("BBox")) rcStream = pAPDic->GetRect("BBox"); if (rcStream.IsEmpty())continue; CPDF_Object* pObj = pAPStream; if (pObj) { CPDF_Dictionary* pObjDic = pObj->GetDict(); if (pObjDic) { pObjDic->SetAtName("Type", "XObject"); pObjDic->SetAtName("Subtype", "Form"); } } CPDF_Dictionary* pXObject = pNewXORes->GetDict("XObject"); if (!pXObject) { pXObject = FX_NEW CPDF_Dictionary; pNewXORes->SetAt("XObject", pXObject); } CFX_ByteString sFormName; sFormName.Format("F%d", i); FX_DWORD dwObjNum = pDocument->AddIndirectObject(pObj); pXObject->SetAtReference(sFormName, pDocument, dwObjNum); CPDF_StreamAcc acc; acc.LoadAllData(pNewXObject); FX_LPCBYTE pData = acc.GetData(); CFX_ByteString sStream(pData, acc.GetSize()); CFX_ByteString sTemp; 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_AffineMatrix 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((FX_LPCBYTE)sStream, sStream.GetLength(), FALSE, FALSE); } pPageDict->RemoveAt( "Annots" ); ObjectArray.RemoveAll(); RectArray.RemoveAll(); return FLATTEN_SUCCESS; }
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; }