summaryrefslogtreecommitdiff
path: root/core/fpdfapi
diff options
context:
space:
mode:
Diffstat (limited to 'core/fpdfapi')
-rw-r--r--core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp42
-rw-r--r--core/fpdfapi/edit/cpdf_pagecontentgenerator.h1
-rw-r--r--core/fpdfapi/page/cpdf_contentparser.h1
-rw-r--r--core/fpdfapi/page/cpdf_pageobjectholder.cpp3
-rw-r--r--core/fpdfapi/page/cpdf_pageobjectholder.h2
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_