diff options
author | Nicolas Pena <npm@chromium.org> | 2017-06-28 15:31:56 -0400 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2017-06-28 19:58:25 +0000 |
commit | 9ba8fbc02e86a6b7cb5c4142d9481ae3238c1ec4 (patch) | |
tree | 3121a73de34a92edd84b982e04b2b900a878e90c /core/fpdfapi | |
parent | d4fb57a4e23ccc2e374c64ea5d5705f492fdd083 (diff) | |
download | pdfium-9ba8fbc02e86a6b7cb5c4142d9481ae3238c1ec4.tar.xz |
Set default graphics before generating page contents
In this CL, the content generator sets some default graphics states
before processing the page objects. In particular, a default ExtGState
is now set before processing, and the last CTM is now stored right
after parsing finishes: the only command to change matrix is ctm, and
it concatenates, so inverting requires knowing the current value.
Bug: pdfium:779
Change-Id: I35b1c07550ce91839fb0e20fbf717e3e80c9b9d6
Reviewed-on: https://pdfium-review.googlesource.com/7070
Commit-Queue: Nicolás Peña <npm@chromium.org>
Reviewed-by: dsinclair <dsinclair@chromium.org>
Diffstat (limited to 'core/fpdfapi')
-rw-r--r-- | core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp | 42 | ||||
-rw-r--r-- | core/fpdfapi/edit/cpdf_pagecontentgenerator.h | 1 | ||||
-rw-r--r-- | core/fpdfapi/page/cpdf_contentparser.h | 1 | ||||
-rw-r--r-- | core/fpdfapi/page/cpdf_pageobjectholder.cpp | 3 | ||||
-rw-r--r-- | core/fpdfapi/page/cpdf_pageobjectholder.h | 2 |
5 files changed, 49 insertions, 0 deletions
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp index eeb6f81721..10b3933742 100644 --- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp +++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp @@ -65,9 +65,24 @@ void CPDF_PageContentGenerator::GenerateContent() { CPDF_Document* pDoc = m_pDocument.Get(); std::ostringstream buf; + + // Set the default graphic state values + buf << "q\n"; + if (!m_pObjHolder->GetLastCTM().IsIdentity()) { + CFX_Matrix reverse; + reverse.SetReverse(m_pObjHolder->GetLastCTM()); + buf << reverse << " cm\n"; + } + ProcessDefaultGraphics(&buf); + + // Process the page objects if (!ProcessPageObjects(&buf)) return; + // Return graphics to original state + buf << "Q\n"; + + // Add buffer to a stream in page's 'Contents' CPDF_Dictionary* pPageDict = m_pObjHolder->m_pFormDict.Get(); CPDF_Object* pContent = pPageDict ? pPageDict->GetObjectFor("Contents") : nullptr; @@ -142,6 +157,7 @@ bool CPDF_PageContentGenerator::ProcessPageObjects(std::ostringstream* buf) { for (auto& pPageObj : m_pageObjects) { if (m_pObjHolder->IsPage() && !pPageObj->IsDirty()) continue; + bDirty = true; if (CPDF_ImageObject* pImageObject = pPageObj->AsImage()) ProcessImage(buf, pImageObject); @@ -304,6 +320,32 @@ void CPDF_PageContentGenerator::ProcessGraphics(std::ostringstream* buf, *buf << "/" << PDF_NameEncode(name) << " gs "; } +void CPDF_PageContentGenerator::ProcessDefaultGraphics( + std::ostringstream* buf) { + *buf << "0 0 0 RG 0 0 0 rg 1 w " + << static_cast<int>(CFX_GraphStateData::LineCapButt) << " J " + << static_cast<int>(CFX_GraphStateData::LineJoinMiter) << " j\n"; + GraphicsData defaultGraphics; + defaultGraphics.fillAlpha = 1.0f; + defaultGraphics.strokeAlpha = 1.0f; + defaultGraphics.blendType = FXDIB_BLEND_NORMAL; + auto it = m_pObjHolder->m_GraphicsMap.find(defaultGraphics); + CFX_ByteString name; + if (it != m_pObjHolder->m_GraphicsMap.end()) { + name = it->second; + } else { + auto gsDict = pdfium::MakeUnique<CPDF_Dictionary>(); + gsDict->SetNewFor<CPDF_Number>("ca", defaultGraphics.fillAlpha); + gsDict->SetNewFor<CPDF_Number>("CA", defaultGraphics.strokeAlpha); + gsDict->SetNewFor<CPDF_Name>("BM", "Normal"); + CPDF_Object* pDict = m_pDocument->AddIndirectObject(std::move(gsDict)); + uint32_t dwObjNum = pDict->GetObjNum(); + name = RealizeResource(dwObjNum, "ExtGState"); + m_pObjHolder->m_GraphicsMap[defaultGraphics] = name; + } + *buf << "/" << PDF_NameEncode(name).c_str() << " gs "; +} + // This method adds text to the buffer, BT begins the text object, ET ends it. // Tm sets the text matrix (allows positioning and transforming text). // Tf sets the font name (from Font in Resources) and font size. diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.h b/core/fpdfapi/edit/cpdf_pagecontentgenerator.h index 2d90eb4465..5295d8747b 100644 --- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.h +++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.h @@ -35,6 +35,7 @@ class CPDF_PageContentGenerator { void ProcessPath(std::ostringstream* buf, CPDF_PathObject* pPathObj); void ProcessImage(std::ostringstream* buf, CPDF_ImageObject* pImageObj); void ProcessGraphics(std::ostringstream* buf, CPDF_PageObject* pPageObj); + void ProcessDefaultGraphics(std::ostringstream* buf); void ProcessText(std::ostringstream* buf, CPDF_TextObject* pTextObj); CFX_ByteString RealizeResource(uint32_t dwResourceObjNum, const CFX_ByteString& bsType); diff --git a/core/fpdfapi/page/cpdf_contentparser.h b/core/fpdfapi/page/cpdf_contentparser.h index 58a977301f..b18e07036c 100644 --- a/core/fpdfapi/page/cpdf_contentparser.h +++ b/core/fpdfapi/page/cpdf_contentparser.h @@ -29,6 +29,7 @@ class CPDF_ContentParser { ~CPDF_ContentParser(); ParseStatus GetStatus() const { return m_Status; } + CPDF_StreamContentParser* GetParser() const { return m_pParser.get(); } void Start(CPDF_Page* pPage); void Start(CPDF_Form* pForm, CPDF_AllStates* pGraphicStates, diff --git a/core/fpdfapi/page/cpdf_pageobjectholder.cpp b/core/fpdfapi/page/cpdf_pageobjectholder.cpp index 50ef780396..614fa34d2b 100644 --- a/core/fpdfapi/page/cpdf_pageobjectholder.cpp +++ b/core/fpdfapi/page/cpdf_pageobjectholder.cpp @@ -8,6 +8,7 @@ #include <algorithm> +#include "core/fpdfapi/page/cpdf_allstates.h" #include "core/fpdfapi/page/cpdf_contentparser.h" #include "core/fpdfapi/page/cpdf_pageobject.h" #include "core/fpdfapi/parser/cpdf_dictionary.h" @@ -38,6 +39,8 @@ void CPDF_PageObjectHolder::ContinueParse(IFX_Pause* pPause) { return; m_ParseState = CONTENT_PARSED; + if (m_pParser->GetParser() && m_pParser->GetParser()->GetCurStates()) + m_LastCTM = m_pParser->GetParser()->GetCurStates()->m_CTM; m_pParser.reset(); } diff --git a/core/fpdfapi/page/cpdf_pageobjectholder.h b/core/fpdfapi/page/cpdf_pageobjectholder.h index 4733e06b2c..87ebbc8460 100644 --- a/core/fpdfapi/page/cpdf_pageobjectholder.h +++ b/core/fpdfapi/page/cpdf_pageobjectholder.h @@ -55,6 +55,7 @@ class CPDF_PageObjectHolder { const CPDF_PageObjectList* GetPageObjectList() const { return &m_PageObjectList; } + const CFX_Matrix& GetLastCTM() const { return m_LastCTM; } bool BackgroundAlphaNeeded() const { return m_bBackgroundAlphaNeeded; } void SetBackgroundAlphaNeeded(bool needed) { @@ -89,6 +90,7 @@ class CPDF_PageObjectHolder { ParseState m_ParseState; std::unique_ptr<CPDF_ContentParser> m_pParser; CPDF_PageObjectList m_PageObjectList; + CFX_Matrix m_LastCTM; }; #endif // CORE_FPDFAPI_PAGE_CPDF_PAGEOBJECTHOLDER_H_ |