From 81a3085b250deafd18a2183a311cc57e2ec1c6f0 Mon Sep 17 00:00:00 2001 From: Henrique Nakashima Date: Tue, 12 Jun 2018 22:00:25 +0000 Subject: Refactor modification of Contents in CPDF_PageContentGenerator. This is a pure refactor, there should be no change in behavior. It prepares for the next CL, which will allow modification of content streams. Bug: pdfium:1051 Change-Id: I01ca3e897efe423e89df75e1f31cd67539cc3d08 Reviewed-on: https://pdfium-review.googlesource.com/34470 Commit-Queue: Henrique Nakashima Reviewed-by: dsinclair --- core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp | 98 ++++++++++++++----------- 1 file changed, 56 insertions(+), 42 deletions(-) (limited to 'core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp') diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp index 3365b5f986..e3a8674afe 100644 --- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp +++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp @@ -9,6 +9,7 @@ #include #include +#include "core/fpdfapi/edit/cpdf_pagecontentmanager.h" #include "core/fpdfapi/font/cpdf_font.h" #include "core/fpdfapi/page/cpdf_docpagedata.h" #include "core/fpdfapi/page/cpdf_image.h" @@ -64,60 +65,67 @@ CPDF_PageContentGenerator::~CPDF_PageContentGenerator() {} void CPDF_PageContentGenerator::GenerateContent() { ASSERT(m_pObjHolder->IsPage()); - CPDF_Document* pDoc = m_pDocument.Get(); - std::ostringstream buf; + std::map> stream = + GenerateModifiedStreams(); + UpdateContentStreams(&stream); +} + +std::map> +CPDF_PageContentGenerator::GenerateModifiedStreams() { + auto buf = pdfium::MakeUnique(); + + std::map> streams; + if (GenerateStreamWithNewObjects(buf.get())) + streams[CPDF_PageObject::kNoContentStream] = std::move(buf); + + // TODO(pdfium:1051): Generate other streams and add to |streams|. + + return streams; +} + +bool CPDF_PageContentGenerator::GenerateStreamWithNewObjects( + std::ostringstream* buf) { // Set the default graphic state values - buf << "q\n"; + *buf << "q\n"; if (!m_pObjHolder->GetLastCTM().IsIdentity()) - buf << m_pObjHolder->GetLastCTM().GetInverse() << " cm\n"; - ProcessDefaultGraphics(&buf); + *buf << m_pObjHolder->GetLastCTM().GetInverse() << " cm\n"; + ProcessDefaultGraphics(buf); // Process the page objects - if (!ProcessPageObjects(&buf)) - return; + if (!ProcessPageObjects(buf)) + return false; // Return graphics to original state - buf << "Q\n"; + *buf << "Q\n"; + + return true; +} - // Add buffer to a stream in page's 'Contents' - CPDF_Dictionary* pPageDict = m_pObjHolder->GetDict(); - if (!pPageDict) +void CPDF_PageContentGenerator::UpdateContentStreams( + std::map>* new_stream_data) { + // If no streams were regenerated or removed, nothing to do here. + if (new_stream_data->empty()) return; - CPDF_Object* pContent = pPageDict->GetObjectFor("Contents"); - CPDF_Stream* pStream = pDoc->NewIndirect(); - pStream->SetData(&buf); - if (pContent) { - CPDF_Array* pArray = ToArray(pContent); - if (pArray) { - pArray->Add(pStream->MakeReference(pDoc)); - return; - } - CPDF_Reference* pReference = ToReference(pContent); - if (!pReference) { - pPageDict->SetFor("Contents", pStream->MakeReference(pDoc)); - return; - } - CPDF_Object* pDirectObj = pReference->GetDirect(); - if (!pDirectObj) { - pPageDict->SetFor("Contents", pStream->MakeReference(pDoc)); - return; - } - CPDF_Array* pObjArray = pDirectObj->AsArray(); - if (pObjArray) { - pObjArray->Add(pStream->MakeReference(pDoc)); - return; - } - if (pDirectObj->IsStream()) { - CPDF_Array* pContentArray = pDoc->NewIndirect(); - pContentArray->Add(pDirectObj->MakeReference(pDoc)); - pContentArray->Add(pStream->MakeReference(pDoc)); - pPageDict->SetFor("Contents", pContentArray->MakeReference(pDoc)); - return; + CPDF_PageContentManager page_content_manager(m_pObjHolder.Get()); + + for (auto& pair : *new_stream_data) { + int32_t stream_index = pair.first; + std::ostringstream* buf = pair.second.get(); + + if (stream_index == CPDF_PageObject::kNoContentStream) { + int new_stream_index = page_content_manager.AddStream(buf); + UpdateStreamlessPageObjects(new_stream_index); + continue; } + + CPDF_Stream* old_stream = + page_content_manager.GetStreamByIndex(stream_index); + ASSERT(old_stream); + + old_stream->SetData(buf); } - pPageDict->SetFor("Contents", pStream->MakeReference(pDoc)); } ByteString CPDF_PageContentGenerator::RealizeResource( @@ -165,6 +173,12 @@ bool CPDF_PageContentGenerator::ProcessPageObjects(std::ostringstream* buf) { return bDirty; } +void CPDF_PageContentGenerator::UpdateStreamlessPageObjects( + int new_content_stream_index) { + // TODO(pdfium:1051): Mark page objects that did not have a content stream + // with the new content stream index. +} + void CPDF_PageContentGenerator::ProcessImage(std::ostringstream* buf, CPDF_ImageObject* pImageObj) { if ((pImageObj->matrix().a == 0 && pImageObj->matrix().b == 0) || -- cgit v1.2.3