summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp10
-rw-r--r--core/fpdfapi/page/cpdf_page.cpp4
-rw-r--r--core/fpdfapi/page/cpdf_page.h1
-rw-r--r--fpdfsdk/fpdfedit_embeddertest.cpp55
-rw-r--r--public/fpdf_edit.h53
5 files changed, 91 insertions, 32 deletions
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
index e06c28d7ae..8b39a7a136 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
@@ -269,10 +269,10 @@ void CPDF_PageContentGenerator::ProcessGraphics(std::ostringstream* buf,
GraphicsData graphD;
graphD.fillAlpha = pPageObj->m_GeneralState.GetFillAlpha();
graphD.strokeAlpha = pPageObj->m_GeneralState.GetStrokeAlpha();
- int blend_type = pPageObj->m_GeneralState.GetBlendType();
+ graphD.blendType = pPageObj->m_GeneralState.GetBlendType();
if (graphD.fillAlpha == 1.0f && graphD.strokeAlpha == 1.0f &&
- (blend_type == FXDIB_BLEND_UNSUPPORTED ||
- blend_type == FXDIB_BLEND_NORMAL)) {
+ (graphD.blendType == FXDIB_BLEND_UNSUPPORTED ||
+ graphD.blendType == FXDIB_BLEND_NORMAL)) {
return;
}
@@ -288,8 +288,8 @@ void CPDF_PageContentGenerator::ProcessGraphics(std::ostringstream* buf,
if (graphD.strokeAlpha != 1.0f)
gsDict->SetNewFor<CPDF_Number>("CA", graphD.strokeAlpha);
- if (blend_type != FXDIB_BLEND_UNSUPPORTED &&
- blend_type != FXDIB_BLEND_NORMAL) {
+ if (graphD.blendType != FXDIB_BLEND_UNSUPPORTED &&
+ graphD.blendType != FXDIB_BLEND_NORMAL) {
gsDict->SetNewFor<CPDF_Name>("BM",
pPageObj->m_GeneralState.GetBlendMode());
}
diff --git a/core/fpdfapi/page/cpdf_page.cpp b/core/fpdfapi/page/cpdf_page.cpp
index 092a1cad41..075aa9023d 100644
--- a/core/fpdfapi/page/cpdf_page.cpp
+++ b/core/fpdfapi/page/cpdf_page.cpp
@@ -183,7 +183,9 @@ int CPDF_Page::GetPageRotation() const {
bool GraphicsData::operator<(const GraphicsData& other) const {
if (fillAlpha != other.fillAlpha)
return fillAlpha < other.fillAlpha;
- return strokeAlpha < other.strokeAlpha;
+ if (strokeAlpha != other.strokeAlpha)
+ return strokeAlpha < other.strokeAlpha;
+ return blendType < other.blendType;
}
bool FontData::operator<(const FontData& other) const {
diff --git a/core/fpdfapi/page/cpdf_page.h b/core/fpdfapi/page/cpdf_page.h
index 77cc793d81..0a080a58ae 100644
--- a/core/fpdfapi/page/cpdf_page.h
+++ b/core/fpdfapi/page/cpdf_page.h
@@ -26,6 +26,7 @@ class CPDF_PageRenderContext;
struct GraphicsData {
float fillAlpha;
float strokeAlpha;
+ int blendType;
bool operator<(const GraphicsData& other) const;
};
diff --git a/fpdfsdk/fpdfedit_embeddertest.cpp b/fpdfsdk/fpdfedit_embeddertest.cpp
index 40081e6d75..1146a8c546 100644
--- a/fpdfsdk/fpdfedit_embeddertest.cpp
+++ b/fpdfsdk/fpdfedit_embeddertest.cpp
@@ -556,6 +556,61 @@ TEST_F(FPDFEditEmbeddertest, AddStandardFontText) {
FPDF_ClosePage(page);
}
+TEST_F(FPDFEditEmbeddertest, GraphicsData) {
+ // New page
+ std::unique_ptr<void, FPDFPageDeleter> page(
+ FPDFPage_New(CreateNewDocument(), 0, 612, 792));
+
+ // Create a rect with nontrivial graphics
+ FPDF_PAGEOBJECT rect1 = FPDFPageObj_CreateNewRect(10, 10, 100, 100);
+ FPDFPageObj_SetBlendMode(rect1, "Color");
+ FPDFPage_InsertObject(page.get(), rect1);
+ EXPECT_TRUE(FPDFPage_GenerateContent(page.get()));
+
+ // Check that the ExtGState was created
+ CPDF_Page* the_page = CPDFPageFromFPDFPage(page.get());
+ CPDF_Dictionary* graphics_dict =
+ the_page->m_pResources->GetDictFor("ExtGState");
+ ASSERT_TRUE(graphics_dict);
+ EXPECT_EQ(1, static_cast<int>(graphics_dict->GetCount()));
+
+ // Add a text object causing no change to the graphics dictionary
+ FPDF_PAGEOBJECT text1 = FPDFPageObj_NewTextObj(document(), "Arial", 12.0f);
+ // Only alpha, the last component, matters for the graphics dictionary. And
+ // the default value is 255.
+ EXPECT_TRUE(FPDFText_SetFillColor(text1, 100, 100, 100, 255));
+ FPDFPage_InsertObject(page.get(), text1);
+ EXPECT_TRUE(FPDFPage_GenerateContent(page.get()));
+ EXPECT_EQ(1, static_cast<int>(graphics_dict->GetCount()));
+
+ // Add a text object increasing the size of the graphics dictionary
+ FPDF_PAGEOBJECT text2 =
+ FPDFPageObj_NewTextObj(document(), "Times-Roman", 12.0f);
+ FPDFPage_InsertObject(page.get(), text2);
+ FPDFPageObj_SetBlendMode(text2, "Darken");
+ EXPECT_TRUE(FPDFText_SetFillColor(text2, 0, 0, 255, 150));
+ EXPECT_TRUE(FPDFPage_GenerateContent(page.get()));
+ EXPECT_EQ(2, static_cast<int>(graphics_dict->GetCount()));
+
+ // Add a path that should reuse graphics
+ // TODO(npm): This causes a crash on Windows.
+ /*FPDF_PAGEOBJECT path = FPDFPageObj_CreateNewPath(400, 100);
+ FPDFPageObj_SetBlendMode(path, "Darken");
+ EXPECT_TRUE(FPDFPath_SetFillColor(path, 200, 200, 100, 150));
+ FPDFPage_InsertObject(page.get(), path);
+ EXPECT_TRUE(FPDFPage_GenerateContent(page.get()));
+ EXPECT_EQ(2, static_cast<int>(graphics_dict->GetCount()));*/
+
+ // Add a rect increasing the size of the graphics dictionary
+ FPDF_PAGEOBJECT rect2 = FPDFPageObj_CreateNewRect(10, 10, 100, 100);
+ FPDFPageObj_SetBlendMode(rect2, "Darken");
+ EXPECT_TRUE(FPDFPath_SetFillColor(rect2, 0, 0, 255, 150));
+ EXPECT_TRUE(FPDFPath_SetStrokeColor(rect2, 0, 0, 0, 200));
+ FPDFPage_InsertObject(page.get(), rect2);
+ EXPECT_TRUE(FPDFPage_GenerateContent(page.get()));
+ EXPECT_EQ(3, static_cast<int>(graphics_dict->GetCount()));
+}
+
TEST_F(FPDFEditEmbeddertest, DoubleGenerating) {
// Start with a blank page
FPDF_PAGE page = FPDFPage_New(CreateNewDocument(), 0, 612, 792);
diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h
index aceca351cd..022832fe78 100644
--- a/public/fpdf_edit.h
+++ b/public/fpdf_edit.h
@@ -136,23 +136,23 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFPage_HasTransparency(FPDF_PAGE page);
// |FPDFPage_GenerateContent| or any changes to |page| will be lost.
DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GenerateContent(FPDF_PAGE page);
-// Checks if |pageObject| contains transparency.
+// Checks if |page_object| contains transparency.
//
-// pageObject - handle to a page object.
+// page_object - handle to a page object.
//
// Returns TRUE if |pageObject| contains transparency.
DLLEXPORT FPDF_BOOL STDCALL
-FPDFPageObj_HasTransparency(FPDF_PAGEOBJECT pageObject);
+FPDFPageObj_HasTransparency(FPDF_PAGEOBJECT page_object);
-// Get type of |pageObject|.
+// Get type of |page_object|.
//
-// pageObject - handle to a page object.
+// page_object - handle to a page object.
//
// Returns one of the FPDF_PAGEOBJ_* values on success, FPDF_PAGEOBJ_UNKNOWN on
// error.
-DLLEXPORT int STDCALL FPDFPageObj_GetType(FPDF_PAGEOBJECT pageObject);
+DLLEXPORT int STDCALL FPDFPageObj_GetType(FPDF_PAGEOBJECT page_object);
-// Transform |pageObject| by the given matrix.
+// Transform |page_object| by the given matrix.
//
// page_object - handle to a page object.
// a - matrix value.
@@ -304,30 +304,30 @@ DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPageObj_CreateNewRect(float x,
float w,
float h);
-// Get the bounding box of |pageObject|.
+// Get the bounding box of |page_object|.
//
-// pageObject - handle to a page object.
-// left - pointer where the left coordinate will be stored
-// bottom - pointer where the bottom coordinate will be stored
-// right - pointer where the right coordinate will be stored
-// top - pointer where the top coordinate will be stored
+// page_object - handle to a page object.
+// left - pointer where the left coordinate will be stored
+// bottom - pointer where the bottom coordinate will be stored
+// right - pointer where the right coordinate will be stored
+// top - pointer where the top coordinate will be stored
//
// Returns TRUE on success.
-DLLEXPORT FPDF_BOOL STDCALL FPDFPageObj_GetBounds(FPDF_PAGEOBJECT pageObject,
+DLLEXPORT FPDF_BOOL STDCALL FPDFPageObj_GetBounds(FPDF_PAGEOBJECT page_object,
float* left,
float* bottom,
float* right,
float* top);
-// Set the blend mode of |pageObject|.
+// Set the blend mode of |page_object|.
//
-// pageObject - handle to a page object.
-// blend_mode - string containing the blend mode.
+// page_object - handle to a page object.
+// blend_mode - string containing the blend mode.
//
// Blend mode can be one of following: Color, ColorBurn, ColorDodge, Darken,
// Difference, Exclusion, HardLight, Hue, Lighten, Luminosity, Multiply, Normal,
// Overlay, Saturation, Screen, SoftLight
-DLLEXPORT void STDCALL FPDFPageObj_SetBlendMode(FPDF_PAGEOBJECT page,
+DLLEXPORT void STDCALL FPDFPageObj_SetBlendMode(FPDF_PAGEOBJECT page_object,
FPDF_BYTESTRING blend_mode);
// Set the stroke RGBA of a path. Range of values: 0 - 255.
@@ -353,24 +353,25 @@ DLLEXPORT FPDF_BOOL FPDFPath_SetStrokeColor(FPDF_PAGEOBJECT path,
// Returns TRUE on success
DLLEXPORT FPDF_BOOL FPDFPath_SetStrokeWidth(FPDF_PAGEOBJECT path, float width);
-// Set the line join of |pageObject|.
+// Set the line join of |page_object|.
//
-// pageObject - handle to a page object.
-// line_join - line join
+// page_object - handle to a page object.
+// line_join - line join
//
// Line join can be one of following: FPDF_LINEJOIN_MITER, FPDF_LINEJOIN_ROUND,
// FPDF_LINEJOIN_BEVEL
-DLLEXPORT void STDCALL FPDFPath_SetLineJoin(FPDF_PAGEOBJECT page,
+DLLEXPORT void STDCALL FPDFPath_SetLineJoin(FPDF_PAGEOBJECT page_object,
int line_join);
-// Set the line cap of |pageObject|.
+// Set the line cap of |page_object|.
//
-// pageObject - handle to a page object.
-// line_cap - line cap
+// page_object - handle to a page object.
+// line_cap - line cap
//
// Line cap can be one of following: FPDF_LINECAP_BUTT, FPDF_LINECAP_ROUND,
// FPDF_LINECAP_PROJECTING_SQUARE
-DLLEXPORT void STDCALL FPDFPath_SetLineCap(FPDF_PAGEOBJECT page, int line_cap);
+DLLEXPORT void STDCALL FPDFPath_SetLineCap(FPDF_PAGEOBJECT page_object,
+ int line_cap);
// Set the fill RGBA of a path. Range of values: 0 - 255.
//