summaryrefslogtreecommitdiff
path: root/core/src/fpdfapi/fpdf_edit/fpdf_edit_content.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/fpdfapi/fpdf_edit/fpdf_edit_content.cpp')
-rw-r--r--core/src/fpdfapi/fpdf_edit/fpdf_edit_content.cpp164
1 files changed, 164 insertions, 0 deletions
diff --git a/core/src/fpdfapi/fpdf_edit/fpdf_edit_content.cpp b/core/src/fpdfapi/fpdf_edit/fpdf_edit_content.cpp
new file mode 100644
index 0000000000..798c77261b
--- /dev/null
+++ b/core/src/fpdfapi/fpdf_edit/fpdf_edit_content.cpp
@@ -0,0 +1,164 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../include/fpdfapi/fpdf_page.h"
+#include "../../../include/fpdfapi/fpdf_serial.h"
+#include "../../../include/fpdfapi/fpdf_module.h"
+#include "../../../include/fxcodec/fx_codec.h"
+#include "../fpdf_page/pageint.h"
+CFX_ByteTextBuf& operator << (CFX_ByteTextBuf& ar, CFX_AffineMatrix& matrix)
+{
+ ar << matrix.a << " " << matrix.b << " " << matrix.c << " " << matrix.d << " " << matrix.e << " " << matrix.f;
+ return ar;
+}
+CPDF_PageContentGenerate::CPDF_PageContentGenerate(CPDF_Page* pPage) : m_pPage(pPage)
+{
+ m_pDocument = NULL;
+ if (m_pPage) {
+ m_pDocument = m_pPage->m_pDocument;
+ }
+}
+CPDF_PageContentGenerate::~CPDF_PageContentGenerate()
+{
+ for (int i = 0; i < m_pageObjects.GetSize(); ++i) {
+ CPDF_PageObject* pPageObj = (CPDF_PageObject*)m_pageObjects[i];
+ if (pPageObj) {
+ pPageObj->Release();
+ }
+ }
+}
+FX_BOOL CPDF_PageContentGenerate::InsertPageObject(CPDF_PageObject* pPageObject)
+{
+ if (!pPageObject) {
+ return FALSE;
+ }
+ return m_pageObjects.Add(pPageObject);
+}
+void CPDF_PageContentGenerate::GenerateContent()
+{
+ CFX_ByteTextBuf buf;
+ CPDF_Dictionary* pPageDict = m_pPage->m_pFormDict;
+ for (int i = 0; i < m_pageObjects.GetSize(); ++i) {
+ CPDF_PageObject* pPageObj = (CPDF_PageObject*)m_pageObjects[i];
+ if (!pPageObj || pPageObj->m_Type != PDFPAGE_IMAGE) {
+ continue;
+ }
+ ProcessImage(buf, (CPDF_ImageObject*)pPageObj);
+ }
+ CPDF_Object* pContent = pPageDict->GetElementValue("Contents");
+ if (pContent != NULL) {
+ pPageDict->RemoveAt("Contents");
+ }
+ CPDF_Stream* pStream = FX_NEW CPDF_Stream(NULL, 0, NULL);
+ pStream->SetData(buf.GetBuffer(), buf.GetLength(), FALSE, FALSE);
+ m_pDocument->AddIndirectObject(pStream);
+ pPageDict->SetAtReference("Contents", m_pDocument, pStream->GetObjNum());
+}
+CFX_ByteString CPDF_PageContentGenerate::RealizeResource(CPDF_Object* pResourceObj, const FX_CHAR* szType)
+{
+ if (m_pPage->m_pResources == NULL) {
+ m_pPage->m_pResources = FX_NEW CPDF_Dictionary;
+ int objnum = m_pDocument->AddIndirectObject(m_pPage->m_pResources);
+ m_pPage->m_pFormDict->SetAtReference("Resources", m_pDocument, objnum);
+ }
+ CPDF_Dictionary* pResList = m_pPage->m_pResources->GetDict(szType);
+ if (pResList == NULL) {
+ pResList = FX_NEW CPDF_Dictionary;
+ m_pPage->m_pResources->SetAt(szType, pResList);
+ }
+ m_pDocument->AddIndirectObject(pResourceObj);
+ CFX_ByteString name;
+ int idnum = 1;
+ while (1) {
+ name.Format("FX%c%d", szType[0], idnum);
+ if (!pResList->KeyExist(name)) {
+ break;
+ }
+ idnum ++;
+ }
+ pResList->AddReference(name, m_pDocument, pResourceObj->GetObjNum());
+ return name;
+}
+void CPDF_PageContentGenerate::ProcessImage(CFX_ByteTextBuf& buf, CPDF_ImageObject* pImageObj)
+{
+ if ((pImageObj->m_Matrix.a == 0 && pImageObj->m_Matrix.b == 0) ||
+ (pImageObj->m_Matrix.c == 0 && pImageObj->m_Matrix.d == 0)) {
+ return;
+ }
+ buf << "q " << pImageObj->m_Matrix << " cm ";
+ if (!pImageObj->m_pImage->IsInline()) {
+ CPDF_Stream* pStream = pImageObj->m_pImage->GetStream();
+ FX_DWORD dwSavedObjNum = pStream->GetObjNum();
+ CFX_ByteString name = RealizeResource(pStream, "XObject");
+ if (dwSavedObjNum == 0) {
+ pImageObj->m_pImage->Release();
+ pImageObj->m_pImage = m_pDocument->GetPageData()->GetImage(pStream);
+ }
+ buf << "/" << PDF_NameEncode(name) << " Do Q\n";
+ }
+}
+void CPDF_PageContentGenerate::ProcessForm(CFX_ByteTextBuf& buf, FX_LPCBYTE data, FX_DWORD size, CFX_Matrix& matrix)
+{
+ if (!data || !size) {
+ return;
+ }
+ CPDF_Stream* pStream = FX_NEW CPDF_Stream(NULL, 0, NULL);
+ CPDF_Dictionary* pFormDict = CPDF_Dictionary::Create();
+ pFormDict->SetAtName(FX_BSTR("Type"), FX_BSTR("XObject"));
+ pFormDict->SetAtName(FX_BSTR("Subtype"), FX_BSTR("Form"));
+ CFX_FloatRect bbox = m_pPage->GetPageBBox();
+ matrix.TransformRect(bbox);
+ pFormDict->SetAtRect(FX_BSTR("BBox"), bbox);
+ pStream->InitStream((FX_LPBYTE)data, size, pFormDict);
+ buf << "q " << matrix << " cm ";
+ CFX_ByteString name = RealizeResource(pStream, "XObject");
+ buf << "/" << PDF_NameEncode(name) << " Do Q\n";
+}
+void CPDF_PageContentGenerate::TransformContent(CFX_Matrix& matrix)
+{
+ CPDF_Object* pContent = m_pPage->m_pFormDict->GetElementValue("Contents");
+ if (!pContent) {
+ return;
+ }
+ CFX_ByteTextBuf buf;
+ int type = pContent->GetType();
+ if (type == PDFOBJ_ARRAY) {
+ CPDF_Array* pArray = (CPDF_Array*)pContent;
+ int iCount = pArray->GetCount();
+ CPDF_StreamAcc** pContentArray = (CPDF_StreamAcc**)FX_Alloc(CPDF_StreamAcc*, iCount);
+ int size = 0;
+ int i = 0;
+ for (i = 0; i < iCount; ++i) {
+ pContent = pArray->GetElement(i);
+ if (!pContent || pContent->GetType() != PDFOBJ_STREAM) {
+ continue;
+ }
+ CPDF_StreamAcc* pStream = FX_NEW CPDF_StreamAcc();
+ pStream->LoadAllData((CPDF_Stream*)pContent);
+ pContentArray[i] = pStream;
+ size += pContentArray[i]->GetSize() + 1;
+ }
+ int pos = 0;
+ FX_LPBYTE pBuf = FX_Alloc(FX_BYTE, size);
+ for (i = 0; i < iCount; ++i) {
+ FXSYS_memcpy32(pBuf + pos, pContentArray[i]->GetData(), pContentArray[i]->GetSize());
+ pos += pContentArray[i]->GetSize() + 1;
+ pBuf[pos - 1] = ' ';
+ delete pContentArray[i];
+ }
+ ProcessForm(buf, pBuf, size, matrix);
+ FX_Free(pBuf);
+ FX_Free(pContentArray);
+ } else if (type == PDFOBJ_STREAM) {
+ CPDF_StreamAcc contentStream;
+ contentStream.LoadAllData((CPDF_Stream*)pContent);
+ ProcessForm(buf, contentStream.GetData(), contentStream.GetSize(), matrix);
+ }
+ CPDF_Stream* pStream = FX_NEW CPDF_Stream(NULL, 0, NULL);
+ pStream->SetData(buf.GetBuffer(), buf.GetLength(), FALSE, FALSE);
+ m_pDocument->AddIndirectObject(pStream);
+ m_pPage->m_pFormDict->SetAtReference("Contents", m_pDocument, pStream->GetObjNum());
+}