summaryrefslogtreecommitdiff
path: root/core/fpdfapi/edit
diff options
context:
space:
mode:
authorwileyrya <wileyrr@gmail.com>2017-05-31 14:49:05 -0500
committerChromium commit bot <commit-bot@chromium.org>2017-06-01 15:03:14 +0000
commite858aa4b70db7408bda1aed71827d9eee1dd98c5 (patch)
treeb80ff68a8a32487bb2511fb8d83af917e6e6583b /core/fpdfapi/edit
parent5be0b291bce26e1a12c9a7becb7c9a9e7857a456 (diff)
downloadpdfium-e858aa4b70db7408bda1aed71827d9eee1dd98c5.tar.xz
Fix content generation to only generate dirty page objects.
BUG=pdfium:717 R=dsinclair@chromium.org,thestig@chromium.org Change-Id: I7e0e6fd301d40f9b5341d40cf11167b7748af243 Reviewed-on: https://pdfium-review.googlesource.com/6071 Reviewed-by: dsinclair <dsinclair@chromium.org> Reviewed-by: Lei Zhang <thestig@chromium.org> Commit-Queue: dsinclair <dsinclair@chromium.org>
Diffstat (limited to 'core/fpdfapi/edit')
-rw-r--r--core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp68
-rw-r--r--core/fpdfapi/edit/cpdf_pagecontentgenerator.h1
2 files changed, 57 insertions, 12 deletions
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
index 2cf10bd7cb..7abf7a4964 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
@@ -17,6 +17,7 @@
#include "core/fpdfapi/page/cpdf_path.h"
#include "core/fpdfapi/page/cpdf_pathobject.h"
#include "core/fpdfapi/page/cpdf_textobject.h"
+#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fpdfapi/parser/cpdf_name.h"
@@ -59,23 +60,49 @@ CPDF_PageContentGenerator::CPDF_PageContentGenerator(CPDF_Page* pPage)
CPDF_PageContentGenerator::~CPDF_PageContentGenerator() {}
void CPDF_PageContentGenerator::GenerateContent() {
+ CPDF_Document* pDoc = m_pDocument.Get();
CFX_ByteTextBuf buf;
- for (auto& pPageObj : m_pageObjects) {
- if (CPDF_ImageObject* pImageObject = pPageObj->AsImage())
- ProcessImage(&buf, pImageObject);
- else if (CPDF_PathObject* pPathObj = pPageObj->AsPath())
- ProcessPath(&buf, pPathObj);
- else if (CPDF_TextObject* pTextObj = pPageObj->AsText())
- ProcessText(&buf, pTextObj);
+ if (!m_pageObjects.empty()) {
+ if (!ProcessPageObjects(&buf))
+ return;
}
CPDF_Dictionary* pPageDict = m_pPage->m_pFormDict.Get();
CPDF_Object* pContent =
- pPageDict ? pPageDict->GetDirectObjectFor("Contents") : nullptr;
- if (pContent)
- pPageDict->RemoveFor("Contents");
-
- CPDF_Stream* pStream = m_pDocument->NewIndirect<CPDF_Stream>();
+ pPageDict ? pPageDict->GetObjectFor("Contents") : nullptr;
+ CPDF_Stream* pStream = pDoc->NewIndirect<CPDF_Stream>();
pStream->SetData(buf.GetBuffer(), buf.GetLength());
+ if (pContent) {
+ CPDF_Array* pArray = ToArray(pContent);
+ if (pArray) {
+ pArray->AddNew<CPDF_Reference>(pDoc, pStream->GetObjNum());
+ return;
+ }
+ CPDF_Reference* pReference = ToReference(pContent);
+ if (!pReference) {
+ pPageDict->SetNewFor<CPDF_Reference>("Contents", m_pDocument.Get(),
+ pStream->GetObjNum());
+ return;
+ }
+ CPDF_Object* pDirectObj = pReference->GetDirect();
+ if (!pDirectObj) {
+ pPageDict->SetNewFor<CPDF_Reference>("Contents", m_pDocument.Get(),
+ pStream->GetObjNum());
+ return;
+ }
+ CPDF_Array* pObjArray = pDirectObj->AsArray();
+ if (pObjArray) {
+ pObjArray->AddNew<CPDF_Reference>(pDoc, pStream->GetObjNum());
+ return;
+ }
+ if (pDirectObj->IsStream()) {
+ CPDF_Array* pContentArray = pDoc->NewIndirect<CPDF_Array>();
+ pContentArray->AddNew<CPDF_Reference>(pDoc, pDirectObj->GetObjNum());
+ pContentArray->AddNew<CPDF_Reference>(pDoc, pStream->GetObjNum());
+ pPageDict->SetNewFor<CPDF_Reference>("Contents", pDoc,
+ pContentArray->GetObjNum());
+ return;
+ }
+ }
pPageDict->SetNewFor<CPDF_Reference>("Contents", m_pDocument.Get(),
pStream->GetObjNum());
}
@@ -107,6 +134,23 @@ CFX_ByteString CPDF_PageContentGenerator::RealizeResource(
return name;
}
+bool CPDF_PageContentGenerator::ProcessPageObjects(CFX_ByteTextBuf* buf) {
+ bool bDirty = false;
+ for (auto& pPageObj : m_pageObjects) {
+ if (!pPageObj->IsDirty())
+ continue;
+ bDirty = true;
+ if (CPDF_ImageObject* pImageObject = pPageObj->AsImage())
+ ProcessImage(buf, pImageObject);
+ else if (CPDF_PathObject* pPathObj = pPageObj->AsPath())
+ ProcessPath(buf, pPathObj);
+ else if (CPDF_TextObject* pTextObj = pPageObj->AsText())
+ ProcessText(buf, pTextObj);
+ pPageObj->SetDirty(false);
+ }
+ return bDirty;
+}
+
void CPDF_PageContentGenerator::ProcessImage(CFX_ByteTextBuf* buf,
CPDF_ImageObject* pImageObj) {
if ((pImageObj->matrix().a == 0 && pImageObj->matrix().b == 0) ||
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.h b/core/fpdfapi/edit/cpdf_pagecontentgenerator.h
index 6c54d3130e..302375d536 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.h
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.h
@@ -30,6 +30,7 @@ class CPDF_PageContentGenerator {
private:
friend class CPDF_PageContentGeneratorTest;
+ bool ProcessPageObjects(CFX_ByteTextBuf* buf);
void ProcessPath(CFX_ByteTextBuf* buf, CPDF_PathObject* pPathObj);
void ProcessImage(CFX_ByteTextBuf* buf, CPDF_ImageObject* pImageObj);
void ProcessGraphics(CFX_ByteTextBuf* buf, CPDF_PageObject* pPageObj);