summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp24
-rw-r--r--core/fpdfapi/edit/cpdf_pagecontentgenerator.h14
-rw-r--r--core/fpdfapi/page/cpdf_page.cpp10
-rw-r--r--core/fpdfapi/page/cpdf_page.h17
-rw-r--r--fpdfsdk/fpdfedit_embeddertest.cpp62
5 files changed, 95 insertions, 32 deletions
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
index ff8b676de1..b5fe4c0f35 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
@@ -222,8 +222,8 @@ void CPDF_PageContentGenerator::ProcessGraphics(CFX_ByteTextBuf* buf,
return;
CFX_ByteString name;
- auto it = m_GraphicsMap.find(graphD);
- if (it != m_GraphicsMap.end()) {
+ auto it = m_pPage->m_GraphicsMap.find(graphD);
+ if (it != m_pPage->m_GraphicsMap.end()) {
name = it->second;
} else {
auto gsDict = pdfium::MakeUnique<CPDF_Dictionary>();
@@ -232,23 +232,11 @@ void CPDF_PageContentGenerator::ProcessGraphics(CFX_ByteTextBuf* buf,
CPDF_Object* pDict = m_pDocument->AddIndirectObject(std::move(gsDict));
uint32_t dwObjNum = pDict->GetObjNum();
name = RealizeResource(dwObjNum, "ExtGState");
- m_GraphicsMap[graphD] = name;
+ m_pPage->m_GraphicsMap[graphD] = name;
}
*buf << "/" << PDF_NameEncode(name) << " gs ";
}
-bool CPDF_PageContentGenerator::GraphicsData::operator<(
- const GraphicsData& other) const {
- if (fillAlpha != other.fillAlpha)
- return fillAlpha < other.fillAlpha;
- return strokeAlpha < other.strokeAlpha;
-}
-
-bool CPDF_PageContentGenerator::FontData::operator<(
- const FontData& other) const {
- return baseFont < other.baseFont;
-}
-
// 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.
@@ -262,9 +250,9 @@ void CPDF_PageContentGenerator::ProcessText(CFX_ByteTextBuf* buf,
pFont = CPDF_Font::GetStockFont(m_pDocument, "Helvetica");
FontData fontD;
fontD.baseFont = pFont->GetBaseFont();
- auto it = m_FontsMap.find(fontD);
+ auto it = m_pPage->m_FontsMap.find(fontD);
CFX_ByteString dictName;
- if (it != m_FontsMap.end()) {
+ if (it != m_pPage->m_FontsMap.end()) {
dictName = it->second;
} else {
auto fontDict = pdfium::MakeUnique<CPDF_Dictionary>();
@@ -274,7 +262,7 @@ void CPDF_PageContentGenerator::ProcessText(CFX_ByteTextBuf* buf,
CPDF_Object* pDict = m_pDocument->AddIndirectObject(std::move(fontDict));
uint32_t dwObjNum = pDict->GetObjNum();
dictName = RealizeResource(dwObjNum, "Font");
- m_FontsMap[fontD] = dictName;
+ m_pPage->m_FontsMap[fontD] = dictName;
}
*buf << "/" << PDF_NameEncode(dictName) << " " << pTextObj->GetFontSize()
<< " Tf ";
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.h b/core/fpdfapi/edit/cpdf_pagecontentgenerator.h
index fd80bd8f44..73e75187e4 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.h
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.h
@@ -7,7 +7,6 @@
#ifndef CORE_FPDFAPI_EDIT_CPDF_PAGECONTENTGENERATOR_H_
#define CORE_FPDFAPI_EDIT_CPDF_PAGECONTENTGENERATOR_H_
-#include <map>
#include <vector>
#include "core/fxcrt/fx_basic.h"
@@ -37,19 +36,6 @@ class CPDF_PageContentGenerator {
CFX_ByteString RealizeResource(uint32_t dwResourceObjNum,
const CFX_ByteString& bsType);
- struct GraphicsData {
- FX_FLOAT fillAlpha;
- FX_FLOAT strokeAlpha;
- bool operator<(const GraphicsData& other) const;
- };
-
- struct FontData {
- CFX_ByteString baseFont;
- bool operator<(const FontData& other) const;
- };
-
- std::map<GraphicsData, CFX_ByteString> m_GraphicsMap;
- std::map<FontData, CFX_ByteString> m_FontsMap;
CPDF_Page* const m_pPage;
CPDF_Document* const m_pDocument;
std::vector<CPDF_PageObject*> m_pageObjects;
diff --git a/core/fpdfapi/page/cpdf_page.cpp b/core/fpdfapi/page/cpdf_page.cpp
index ba30ce57c3..46123ab42e 100644
--- a/core/fpdfapi/page/cpdf_page.cpp
+++ b/core/fpdfapi/page/cpdf_page.cpp
@@ -175,3 +175,13 @@ CFX_Matrix CPDF_Page::GetDisplayMatrix(int xPos,
x0, y0));
return matrix;
}
+
+bool GraphicsData::operator<(const GraphicsData& other) const {
+ if (fillAlpha != other.fillAlpha)
+ return fillAlpha < other.fillAlpha;
+ return strokeAlpha < other.strokeAlpha;
+}
+
+bool FontData::operator<(const FontData& other) const {
+ return baseFont < other.baseFont;
+}
diff --git a/core/fpdfapi/page/cpdf_page.h b/core/fpdfapi/page/cpdf_page.h
index 6d29a8f34e..9e303562c6 100644
--- a/core/fpdfapi/page/cpdf_page.h
+++ b/core/fpdfapi/page/cpdf_page.h
@@ -7,6 +7,7 @@
#ifndef CORE_FPDFAPI_PAGE_CPDF_PAGE_H_
#define CORE_FPDFAPI_PAGE_CPDF_PAGE_H_
+#include <map>
#include <memory>
#include "core/fpdfapi/page/cpdf_pageobjectholder.h"
@@ -20,6 +21,19 @@ class CPDF_Object;
class CPDF_PageRenderCache;
class CPDF_PageRenderContext;
+// These structs are used to keep track of resources that have already been
+// generated in the page.
+struct GraphicsData {
+ FX_FLOAT fillAlpha;
+ FX_FLOAT strokeAlpha;
+ bool operator<(const GraphicsData& other) const;
+};
+
+struct FontData {
+ CFX_ByteString baseFont;
+ bool operator<(const FontData& other) const;
+};
+
class CPDF_Page : public CPDF_PageObjectHolder {
public:
class View {}; // Caller implements as desired, empty here due to layering.
@@ -52,6 +66,9 @@ class CPDF_Page : public CPDF_PageObjectHolder {
View* GetView() const { return m_pView; }
void SetView(View* pView) { m_pView = pView; }
+ std::map<GraphicsData, CFX_ByteString> m_GraphicsMap;
+ std::map<FontData, CFX_ByteString> m_FontsMap;
+
protected:
void StartParse();
diff --git a/fpdfsdk/fpdfedit_embeddertest.cpp b/fpdfsdk/fpdfedit_embeddertest.cpp
index fb561967ec..f877617b49 100644
--- a/fpdfsdk/fpdfedit_embeddertest.cpp
+++ b/fpdfsdk/fpdfedit_embeddertest.cpp
@@ -5,7 +5,10 @@
#include <memory>
#include <string>
+#include "core/fpdfapi/page/cpdf_page.h"
+#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fxcrt/fx_system.h"
+#include "fpdfsdk/fsdk_define.h"
#include "public/fpdf_edit.h"
#include "public/fpdfview.h"
#include "testing/embedder_test.h"
@@ -378,3 +381,62 @@ TEST_F(FPDFEditEmbeddertest, AddStandardFontText) {
FPDF_ClosePage(page);
FPDF_CloseDocument(doc);
}
+
+TEST_F(FPDFEditEmbeddertest, DoubleGenerating) {
+ // Start with a blank page
+ FPDF_DOCUMENT doc = FPDF_CreateNewDocument();
+ FPDF_PAGE page = FPDFPage_New(doc, 0, 612, 792);
+
+ // Add a red rectangle with some non-default alpha
+ FPDF_PAGEOBJECT rect = FPDFPageObj_CreateNewRect(10, 10, 100, 100);
+ EXPECT_TRUE(FPDFPath_SetFillColor(rect, 255, 0, 0, 128));
+ EXPECT_TRUE(FPDFPath_SetDrawMode(rect, FPDF_FILLMODE_WINDING, 0));
+ FPDFPage_InsertObject(page, rect);
+ EXPECT_TRUE(FPDFPage_GenerateContent(page));
+
+ // Check the ExtGState
+ CPDF_Page* the_page = CPDFPageFromFPDFPage(page);
+ CPDF_Dictionary* graphics_dict =
+ the_page->m_pResources->GetDictFor("ExtGState");
+ ASSERT_TRUE(graphics_dict);
+ EXPECT_EQ(1, static_cast<int>(graphics_dict->GetCount()));
+
+ // Check the bitmap
+ FPDF_BITMAP page_bitmap = RenderPage(page);
+ CompareBitmap(page_bitmap, 612, 792, "5384da3406d62360ffb5cac4476fff1c");
+ FPDFBitmap_Destroy(page_bitmap);
+
+ // Never mind, my new favorite color is blue, increase alpha
+ EXPECT_TRUE(FPDFPath_SetFillColor(rect, 0, 0, 255, 180));
+ EXPECT_TRUE(FPDFPage_GenerateContent(page));
+ EXPECT_EQ(2, static_cast<int>(graphics_dict->GetCount()));
+
+ // Check that bitmap displays changed content
+ page_bitmap = RenderPage(page);
+ CompareBitmap(page_bitmap, 612, 792, "2e51656f5073b0bee611d9cd086aa09c");
+ FPDFBitmap_Destroy(page_bitmap);
+
+ // And now generate, without changes
+ EXPECT_TRUE(FPDFPage_GenerateContent(page));
+ EXPECT_EQ(2, static_cast<int>(graphics_dict->GetCount()));
+ page_bitmap = RenderPage(page);
+ CompareBitmap(page_bitmap, 612, 792, "2e51656f5073b0bee611d9cd086aa09c");
+ FPDFBitmap_Destroy(page_bitmap);
+
+ // Add some text to the page
+ FPDF_PAGEOBJECT text = FPDFPageObj_NewTextObj(doc, "Arial", 12.0f);
+ EXPECT_TRUE(FPDFText_SetText(text, "Something something #text# something"));
+ FPDFPageObj_Transform(text, 1, 0, 0, 1, 300, 300);
+ FPDFPage_InsertObject(page, text);
+ EXPECT_TRUE(FPDFPage_GenerateContent(page));
+ CPDF_Dictionary* font_dict = the_page->m_pResources->GetDictFor("Font");
+ ASSERT_TRUE(font_dict);
+ EXPECT_EQ(1, static_cast<int>(font_dict->GetCount()));
+
+ // Generate yet again, check dicts are reasonably sized
+ EXPECT_TRUE(FPDFPage_GenerateContent(page));
+ EXPECT_EQ(2, static_cast<int>(graphics_dict->GetCount()));
+ EXPECT_EQ(1, static_cast<int>(font_dict->GetCount()));
+ FPDF_ClosePage(page);
+ FPDF_CloseDocument(doc);
+}