summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwileyrya <wileyrr@gmail.com>2017-05-31 14:49:05 -0500
committerChromium commit bot <commit-bot@chromium.org>2017-06-01 15:03:14 +0000
commite858aa4b70db7408bda1aed71827d9eee1dd98c5 (patch)
treeb80ff68a8a32487bb2511fb8d83af917e6e6583b
parent5be0b291bce26e1a12c9a7becb7c9a9e7857a456 (diff)
downloadpdfium-e858aa4b70db7408bda1aed71827d9eee1dd98c5.tar.xz
Fix content generation to only generate dirty page objects.
BUG=pdfium:717 R=dsinclair@chromium.org,thestig@chromium.org Change-Id: I7e0e6fd301d40f9b5341d40cf11167b7748af243 Reviewed-on: https://pdfium-review.googlesource.com/6071 Reviewed-by: dsinclair <dsinclair@chromium.org> Reviewed-by: Lei Zhang <thestig@chromium.org> Commit-Queue: dsinclair <dsinclair@chromium.org>
-rw-r--r--core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp68
-rw-r--r--core/fpdfapi/edit/cpdf_pagecontentgenerator.h1
-rw-r--r--core/fpdfapi/page/cpdf_imageobject.cpp1
-rw-r--r--core/fpdfapi/page/cpdf_pageobject.cpp5
-rw-r--r--core/fpdfapi/page/cpdf_pageobject.h4
-rw-r--r--core/fpdfapi/page/cpdf_pathobject.cpp1
-rw-r--r--core/fpdfapi/page/cpdf_textobject.cpp2
-rw-r--r--fpdfsdk/fpdfedit_embeddertest.cpp84
-rw-r--r--fpdfsdk/fpdfeditimg.cpp4
-rw-r--r--fpdfsdk/fpdfeditpage.cpp66
-rw-r--r--fpdfsdk/fpdfeditpath.cpp9
-rw-r--r--testing/resources/bug_717.pdfbin0 -> 79942 bytes
12 files changed, 201 insertions, 44 deletions
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
index 2cf10bd7cb..7abf7a4964 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
@@ -17,6 +17,7 @@
#include "core/fpdfapi/page/cpdf_path.h"
#include "core/fpdfapi/page/cpdf_pathobject.h"
#include "core/fpdfapi/page/cpdf_textobject.h"
+#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fpdfapi/parser/cpdf_name.h"
@@ -59,23 +60,49 @@ CPDF_PageContentGenerator::CPDF_PageContentGenerator(CPDF_Page* pPage)
CPDF_PageContentGenerator::~CPDF_PageContentGenerator() {}
void CPDF_PageContentGenerator::GenerateContent() {
+ CPDF_Document* pDoc = m_pDocument.Get();
CFX_ByteTextBuf buf;
- for (auto& pPageObj : m_pageObjects) {
- if (CPDF_ImageObject* pImageObject = pPageObj->AsImage())
- ProcessImage(&buf, pImageObject);
- else if (CPDF_PathObject* pPathObj = pPageObj->AsPath())
- ProcessPath(&buf, pPathObj);
- else if (CPDF_TextObject* pTextObj = pPageObj->AsText())
- ProcessText(&buf, pTextObj);
+ if (!m_pageObjects.empty()) {
+ if (!ProcessPageObjects(&buf))
+ return;
}
CPDF_Dictionary* pPageDict = m_pPage->m_pFormDict.Get();
CPDF_Object* pContent =
- pPageDict ? pPageDict->GetDirectObjectFor("Contents") : nullptr;
- if (pContent)
- pPageDict->RemoveFor("Contents");
-
- CPDF_Stream* pStream = m_pDocument->NewIndirect<CPDF_Stream>();
+ pPageDict ? pPageDict->GetObjectFor("Contents") : nullptr;
+ CPDF_Stream* pStream = pDoc->NewIndirect<CPDF_Stream>();
pStream->SetData(buf.GetBuffer(), buf.GetLength());
+ if (pContent) {
+ CPDF_Array* pArray = ToArray(pContent);
+ if (pArray) {
+ pArray->AddNew<CPDF_Reference>(pDoc, pStream->GetObjNum());
+ return;
+ }
+ CPDF_Reference* pReference = ToReference(pContent);
+ if (!pReference) {
+ pPageDict->SetNewFor<CPDF_Reference>("Contents", m_pDocument.Get(),
+ pStream->GetObjNum());
+ return;
+ }
+ CPDF_Object* pDirectObj = pReference->GetDirect();
+ if (!pDirectObj) {
+ pPageDict->SetNewFor<CPDF_Reference>("Contents", m_pDocument.Get(),
+ pStream->GetObjNum());
+ return;
+ }
+ CPDF_Array* pObjArray = pDirectObj->AsArray();
+ if (pObjArray) {
+ pObjArray->AddNew<CPDF_Reference>(pDoc, pStream->GetObjNum());
+ return;
+ }
+ if (pDirectObj->IsStream()) {
+ CPDF_Array* pContentArray = pDoc->NewIndirect<CPDF_Array>();
+ pContentArray->AddNew<CPDF_Reference>(pDoc, pDirectObj->GetObjNum());
+ pContentArray->AddNew<CPDF_Reference>(pDoc, pStream->GetObjNum());
+ pPageDict->SetNewFor<CPDF_Reference>("Contents", pDoc,
+ pContentArray->GetObjNum());
+ return;
+ }
+ }
pPageDict->SetNewFor<CPDF_Reference>("Contents", m_pDocument.Get(),
pStream->GetObjNum());
}
@@ -107,6 +134,23 @@ CFX_ByteString CPDF_PageContentGenerator::RealizeResource(
return name;
}
+bool CPDF_PageContentGenerator::ProcessPageObjects(CFX_ByteTextBuf* buf) {
+ bool bDirty = false;
+ for (auto& pPageObj : m_pageObjects) {
+ if (!pPageObj->IsDirty())
+ continue;
+ bDirty = true;
+ if (CPDF_ImageObject* pImageObject = pPageObj->AsImage())
+ ProcessImage(buf, pImageObject);
+ else if (CPDF_PathObject* pPathObj = pPageObj->AsPath())
+ ProcessPath(buf, pPathObj);
+ else if (CPDF_TextObject* pTextObj = pPageObj->AsText())
+ ProcessText(buf, pTextObj);
+ pPageObj->SetDirty(false);
+ }
+ return bDirty;
+}
+
void CPDF_PageContentGenerator::ProcessImage(CFX_ByteTextBuf* buf,
CPDF_ImageObject* pImageObj) {
if ((pImageObj->matrix().a == 0 && pImageObj->matrix().b == 0) ||
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.h b/core/fpdfapi/edit/cpdf_pagecontentgenerator.h
index 6c54d3130e..302375d536 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.h
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.h
@@ -30,6 +30,7 @@ class CPDF_PageContentGenerator {
private:
friend class CPDF_PageContentGeneratorTest;
+ bool ProcessPageObjects(CFX_ByteTextBuf* buf);
void ProcessPath(CFX_ByteTextBuf* buf, CPDF_PathObject* pPathObj);
void ProcessImage(CFX_ByteTextBuf* buf, CPDF_ImageObject* pImageObj);
void ProcessGraphics(CFX_ByteTextBuf* buf, CPDF_PageObject* pPageObj);
diff --git a/core/fpdfapi/page/cpdf_imageobject.cpp b/core/fpdfapi/page/cpdf_imageobject.cpp
index 8732c00954..a74ac4802c 100644
--- a/core/fpdfapi/page/cpdf_imageobject.cpp
+++ b/core/fpdfapi/page/cpdf_imageobject.cpp
@@ -25,6 +25,7 @@ CPDF_PageObject::Type CPDF_ImageObject::GetType() const {
void CPDF_ImageObject::Transform(const CFX_Matrix& matrix) {
m_Matrix.Concat(matrix);
CalcBoundingBox();
+ SetDirty(true);
}
bool CPDF_ImageObject::IsImage() const {
diff --git a/core/fpdfapi/page/cpdf_pageobject.cpp b/core/fpdfapi/page/cpdf_pageobject.cpp
index 09a98eee7d..79d9bbc540 100644
--- a/core/fpdfapi/page/cpdf_pageobject.cpp
+++ b/core/fpdfapi/page/cpdf_pageobject.cpp
@@ -6,7 +6,7 @@
#include "core/fpdfapi/page/cpdf_pageobject.h"
-CPDF_PageObject::CPDF_PageObject() {}
+CPDF_PageObject::CPDF_PageObject() : m_bDirty(false) {}
CPDF_PageObject::~CPDF_PageObject() {}
@@ -76,18 +76,21 @@ void CPDF_PageObject::CopyData(const CPDF_PageObject* pSrc) {
m_Right = pSrc->m_Right;
m_Top = pSrc->m_Top;
m_Bottom = pSrc->m_Bottom;
+ m_bDirty = true;
}
void CPDF_PageObject::TransformClipPath(CFX_Matrix& matrix) {
if (!m_ClipPath.HasRef())
return;
m_ClipPath.Transform(matrix);
+ SetDirty(true);
}
void CPDF_PageObject::TransformGeneralState(CFX_Matrix& matrix) {
if (!m_GeneralState.HasRef())
return;
m_GeneralState.GetMutableMatrix()->Concat(matrix);
+ SetDirty(true);
}
FX_RECT CPDF_PageObject::GetBBox(const CFX_Matrix* pMatrix) const {
diff --git a/core/fpdfapi/page/cpdf_pageobject.h b/core/fpdfapi/page/cpdf_pageobject.h
index 668621ff51..d23cd971f8 100644
--- a/core/fpdfapi/page/cpdf_pageobject.h
+++ b/core/fpdfapi/page/cpdf_pageobject.h
@@ -49,6 +49,8 @@ class CPDF_PageObject : public CPDF_GraphicStates {
virtual CPDF_FormObject* AsForm();
virtual const CPDF_FormObject* AsForm() const;
+ void SetDirty(bool value) { m_bDirty = value; }
+ bool IsDirty() const { return m_bDirty; }
void TransformClipPath(CFX_Matrix& matrix);
void TransformGeneralState(CFX_Matrix& matrix);
@@ -69,6 +71,8 @@ class CPDF_PageObject : public CPDF_GraphicStates {
private:
CPDF_PageObject(const CPDF_PageObject& src) = delete;
void operator=(const CPDF_PageObject& src) = delete;
+
+ bool m_bDirty;
};
#endif // CORE_FPDFAPI_PAGE_CPDF_PAGEOBJECT_H_
diff --git a/core/fpdfapi/page/cpdf_pathobject.cpp b/core/fpdfapi/page/cpdf_pathobject.cpp
index c4d55bc20f..b54ad6e151 100644
--- a/core/fpdfapi/page/cpdf_pathobject.cpp
+++ b/core/fpdfapi/page/cpdf_pathobject.cpp
@@ -17,6 +17,7 @@ CPDF_PageObject::Type CPDF_PathObject::GetType() const {
void CPDF_PathObject::Transform(const CFX_Matrix& matrix) {
m_Matrix.Concat(matrix);
CalcBoundingBox();
+ SetDirty(true);
}
bool CPDF_PathObject::IsPath() const {
diff --git a/core/fpdfapi/page/cpdf_textobject.cpp b/core/fpdfapi/page/cpdf_textobject.cpp
index b8f3f61073..7a70101789 100644
--- a/core/fpdfapi/page/cpdf_textobject.cpp
+++ b/core/fpdfapi/page/cpdf_textobject.cpp
@@ -115,6 +115,7 @@ void CPDF_TextObject::Transform(const CFX_Matrix& matrix) {
pTextMatrix[3] = text_matrix.d;
m_Pos = CFX_PointF(text_matrix.e, text_matrix.f);
CalcPositionData(0);
+ SetDirty(true);
}
bool CPDF_TextObject::IsText() const {
@@ -164,6 +165,7 @@ void CPDF_TextObject::SetSegments(const CFX_ByteString* pStrs,
void CPDF_TextObject::SetText(const CFX_ByteString& str) {
SetSegments(&str, nullptr, 1);
RecalcPositionData();
+ SetDirty(true);
}
float CPDF_TextObject::GetCharWidth(uint32_t charcode) const {
diff --git a/fpdfsdk/fpdfedit_embeddertest.cpp b/fpdfsdk/fpdfedit_embeddertest.cpp
index 6045618411..f52848c81d 100644
--- a/fpdfsdk/fpdfedit_embeddertest.cpp
+++ b/fpdfsdk/fpdfedit_embeddertest.cpp
@@ -368,6 +368,90 @@ TEST_F(FPDFEditEmbeddertest, PathOnTopOfText) {
UnloadPage(page);
}
+TEST_F(FPDFEditEmbeddertest, EditOverExistingContent) {
+ // Load document with existing content
+ EXPECT_TRUE(OpenDocument("bug_717.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ EXPECT_NE(nullptr, page);
+
+ // Add a transparent rectangle on top of the existing content
+ FPDF_PAGEOBJECT red_rect2 = FPDFPageObj_CreateNewRect(90, 700, 25, 50);
+ EXPECT_TRUE(FPDFPath_SetFillColor(red_rect2, 255, 0, 0, 100));
+ EXPECT_TRUE(FPDFPath_SetDrawMode(red_rect2, FPDF_FILLMODE_ALTERNATE, 0));
+ FPDFPage_InsertObject(page, red_rect2);
+
+ // Add an opaque rectangle on top of the existing content
+ FPDF_PAGEOBJECT red_rect = FPDFPageObj_CreateNewRect(115, 700, 25, 50);
+ EXPECT_TRUE(FPDFPath_SetFillColor(red_rect, 255, 0, 0, 255));
+ EXPECT_TRUE(FPDFPath_SetDrawMode(red_rect, FPDF_FILLMODE_ALTERNATE, 0));
+ FPDFPage_InsertObject(page, red_rect);
+
+ FPDF_BITMAP bitmap = RenderPage(page);
+ CompareBitmap(bitmap, 612, 792, "ad04e5bd0f471a9a564fb034bd0fb073");
+ FPDFBitmap_Destroy(bitmap);
+ EXPECT_TRUE(FPDFPage_GenerateContent(page));
+
+ // Now save the result, closing the page and document
+ EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
+ FPDF_ClosePage(page);
+
+ // Render the saved result
+ std::string new_file = GetString();
+ FPDF_FILEACCESS file_access;
+ memset(&file_access, 0, sizeof(file_access));
+ file_access.m_FileLen = new_file.size();
+ file_access.m_GetBlock = GetBlockFromString;
+ file_access.m_Param = &new_file;
+ FPDF_DOCUMENT new_doc = FPDF_LoadCustomDocument(&file_access, nullptr);
+ ASSERT_NE(nullptr, new_doc);
+ EXPECT_EQ(1, FPDF_GetPageCount(new_doc));
+ FPDF_PAGE new_page = FPDF_LoadPage(new_doc, 0);
+ ASSERT_NE(nullptr, new_page);
+ FPDF_BITMAP new_bitmap = RenderPage(new_page);
+ CompareBitmap(new_bitmap, 612, 792, "ad04e5bd0f471a9a564fb034bd0fb073");
+ FPDFBitmap_Destroy(new_bitmap);
+
+ ClearString();
+ // Add another opaque rectangle on top of the existing content
+ FPDF_PAGEOBJECT green_rect = FPDFPageObj_CreateNewRect(150, 700, 25, 50);
+ EXPECT_TRUE(FPDFPath_SetFillColor(green_rect, 0, 255, 0, 255));
+ EXPECT_TRUE(FPDFPath_SetDrawMode(green_rect, FPDF_FILLMODE_ALTERNATE, 0));
+ FPDFPage_InsertObject(new_page, green_rect);
+
+ // Add another transparent rectangle on top of existing content
+ FPDF_PAGEOBJECT green_rect2 = FPDFPageObj_CreateNewRect(175, 700, 25, 50);
+ EXPECT_TRUE(FPDFPath_SetFillColor(green_rect2, 0, 255, 0, 100));
+ EXPECT_TRUE(FPDFPath_SetDrawMode(green_rect2, FPDF_FILLMODE_ALTERNATE, 0));
+ FPDFPage_InsertObject(new_page, green_rect2);
+ new_bitmap = RenderPage(new_page);
+ CompareBitmap(new_bitmap, 612, 792, "4b5b00f824620f8c9b8801ebb98e1cdd");
+ FPDFBitmap_Destroy(new_bitmap);
+ EXPECT_TRUE(FPDFPage_GenerateContent(new_page));
+
+ // Now save the result, closing the page and document
+ EXPECT_TRUE(FPDF_SaveAsCopy(new_doc, this, 0));
+ FPDF_ClosePage(new_page);
+ FPDF_CloseDocument(new_doc);
+
+ // Render the saved result
+ new_file = GetString();
+ memset(&file_access, 0, sizeof(file_access));
+ file_access.m_FileLen = new_file.size();
+ file_access.m_GetBlock = GetBlockFromString;
+ file_access.m_Param = &new_file;
+ new_doc = FPDF_LoadCustomDocument(&file_access, nullptr);
+ ASSERT_NE(nullptr, new_doc);
+ EXPECT_EQ(1, FPDF_GetPageCount(new_doc));
+ new_page = FPDF_LoadPage(new_doc, 0);
+ ASSERT_NE(nullptr, new_page);
+ new_bitmap = RenderPage(new_page);
+ CompareBitmap(new_bitmap, 612, 792, "4b5b00f824620f8c9b8801ebb98e1cdd");
+ FPDFBitmap_Destroy(new_bitmap);
+
+ FPDF_ClosePage(new_page);
+ FPDF_CloseDocument(new_doc);
+}
+
TEST_F(FPDFEditEmbeddertest, AddStrokedPaths) {
// Start with a blank page
FPDF_PAGE page = FPDFPage_New(CreateNewDocument(), 0, 612, 792);
diff --git a/fpdfsdk/fpdfeditimg.cpp b/fpdfsdk/fpdfeditimg.cpp
index 9f4b2968ee..fdc98e06e9 100644
--- a/fpdfsdk/fpdfeditimg.cpp
+++ b/fpdfsdk/fpdfeditimg.cpp
@@ -39,7 +39,7 @@ bool LoadJpegHelper(FPDF_PAGE* pages,
pImgObj->GetImage()->SetJpegImageInline(pFile);
else
pImgObj->GetImage()->SetJpegImage(pFile);
-
+ pImgObj->SetDirty(true);
return true;
}
@@ -87,6 +87,7 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFImageObj_SetMatrix(FPDF_PAGEOBJECT image_object,
static_cast<float>(c), static_cast<float>(d),
static_cast<float>(e), static_cast<float>(f)));
pImgObj->CalcBoundingBox();
+ pImgObj->SetDirty(true);
return true;
}
@@ -106,5 +107,6 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFImageObj_SetBitmap(FPDF_PAGE* pages,
CFX_RetainPtr<CFX_DIBitmap> holder(CFXBitmapFromFPDFBitmap(bitmap));
pImgObj->GetImage()->SetImage(holder);
pImgObj->CalcBoundingBox();
+ pImgObj->SetDirty(true);
return true;
}
diff --git a/fpdfsdk/fpdfeditpage.cpp b/fpdfsdk/fpdfeditpage.cpp
index a474414435..da156cd790 100644
--- a/fpdfsdk/fpdfeditpage.cpp
+++ b/fpdfsdk/fpdfeditpage.cpp
@@ -61,6 +61,38 @@ bool IsPageObject(CPDF_Page* pPage) {
return pObject && !pObject->GetString().Compare("Page");
}
+void CalcBoundingBox(CPDF_PageObject* pPageObj) {
+ switch (pPageObj->GetType()) {
+ case CPDF_PageObject::TEXT: {
+ break;
+ }
+ case CPDF_PageObject::PATH: {
+ CPDF_PathObject* pPathObj = pPageObj->AsPath();
+ pPathObj->CalcBoundingBox();
+ break;
+ }
+ case CPDF_PageObject::IMAGE: {
+ CPDF_ImageObject* pImageObj = pPageObj->AsImage();
+ pImageObj->CalcBoundingBox();
+ break;
+ }
+ case CPDF_PageObject::SHADING: {
+ CPDF_ShadingObject* pShadingObj = pPageObj->AsShading();
+ pShadingObj->CalcBoundingBox();
+ break;
+ }
+ case CPDF_PageObject::FORM: {
+ CPDF_FormObject* pFormObj = pPageObj->AsForm();
+ pFormObj->CalcBoundingBox();
+ break;
+ }
+ default: {
+ NOTREACHED();
+ break;
+ }
+ }
+}
+
} // namespace
DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_CreateNewDocument() {
@@ -144,37 +176,9 @@ DLLEXPORT void STDCALL FPDFPage_InsertObject(FPDF_PAGE page,
CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
if (!IsPageObject(pPage))
return;
-
+ pPageObj->SetDirty(true);
pPage->GetPageObjectList()->push_back(std::move(pPageObjHolder));
- switch (pPageObj->GetType()) {
- case CPDF_PageObject::TEXT: {
- break;
- }
- case CPDF_PageObject::PATH: {
- CPDF_PathObject* pPathObj = pPageObj->AsPath();
- pPathObj->CalcBoundingBox();
- break;
- }
- case CPDF_PageObject::IMAGE: {
- CPDF_ImageObject* pImageObj = pPageObj->AsImage();
- pImageObj->CalcBoundingBox();
- break;
- }
- case CPDF_PageObject::SHADING: {
- CPDF_ShadingObject* pShadingObj = pPageObj->AsShading();
- pShadingObj->CalcBoundingBox();
- break;
- }
- case CPDF_PageObject::FORM: {
- CPDF_FormObject* pFormObj = pPageObj->AsForm();
- pFormObj->CalcBoundingBox();
- break;
- }
- default: {
- NOTREACHED();
- break;
- }
- }
+ CalcBoundingBox(pPageObj);
}
DLLEXPORT int STDCALL FPDFPage_CountObject(FPDF_PAGE page) {
@@ -271,6 +275,7 @@ DLLEXPORT void STDCALL FPDFPageObj_SetBlendMode(FPDF_PAGEOBJECT page_object,
return;
pPageObj->m_GeneralState.SetBlendMode(blend_mode);
+ pPageObj->SetDirty(true);
}
DLLEXPORT void STDCALL FPDFPage_TransformAnnots(FPDF_PAGE page,
@@ -327,6 +332,7 @@ FPDF_BOOL FPDFPageObj_SetFillColor(FPDF_PAGEOBJECT page_object,
pPageObj->m_GeneralState.SetFillAlpha(A / 255.f);
pPageObj->m_ColorState.SetFillColor(
CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3);
+ pPageObj->SetDirty(true);
return true;
}
diff --git a/fpdfsdk/fpdfeditpath.cpp b/fpdfsdk/fpdfeditpath.cpp
index ad5ca9433f..f58d1e18a9 100644
--- a/fpdfsdk/fpdfeditpath.cpp
+++ b/fpdfsdk/fpdfeditpath.cpp
@@ -40,6 +40,7 @@ DLLEXPORT FPDF_BOOL FPDFPath_SetStrokeColor(FPDF_PAGEOBJECT path,
pPathObj->m_GeneralState.SetStrokeAlpha(A / 255.f);
pPathObj->m_ColorState.SetStrokeColor(
CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3);
+ pPathObj->SetDirty(true);
return true;
}
@@ -49,6 +50,7 @@ DLLEXPORT FPDF_BOOL FPDFPath_SetStrokeWidth(FPDF_PAGEOBJECT path, float width) {
auto* pPathObj = static_cast<CPDF_PathObject*>(path);
pPathObj->m_GraphState.SetLineWidth(width);
+ pPathObj->SetDirty(true);
return true;
}
@@ -84,6 +86,7 @@ DLLEXPORT FPDF_BOOL FPDFPath_MoveTo(FPDF_PAGEOBJECT path, float x, float y) {
auto* pPathObj = static_cast<CPDF_PathObject*>(path);
pPathObj->m_Path.AppendPoint(CFX_PointF(x, y), FXPT_TYPE::MoveTo, false);
+ pPathObj->SetDirty(true);
return true;
}
@@ -93,6 +96,7 @@ DLLEXPORT FPDF_BOOL FPDFPath_LineTo(FPDF_PAGEOBJECT path, float x, float y) {
auto* pPathObj = static_cast<CPDF_PathObject*>(path);
pPathObj->m_Path.AppendPoint(CFX_PointF(x, y), FXPT_TYPE::LineTo, false);
+ pPathObj->SetDirty(true);
return true;
}
@@ -110,6 +114,7 @@ DLLEXPORT FPDF_BOOL FPDFPath_BezierTo(FPDF_PAGEOBJECT path,
pPathObj->m_Path.AppendPoint(CFX_PointF(x1, y1), FXPT_TYPE::BezierTo, false);
pPathObj->m_Path.AppendPoint(CFX_PointF(x2, y2), FXPT_TYPE::BezierTo, false);
pPathObj->m_Path.AppendPoint(CFX_PointF(x3, y3), FXPT_TYPE::BezierTo, false);
+ pPathObj->SetDirty(true);
return true;
}
@@ -122,6 +127,7 @@ DLLEXPORT FPDF_BOOL FPDFPath_Close(FPDF_PAGEOBJECT path) {
return false;
pPathObj->m_Path.ClosePath();
+ pPathObj->SetDirty(true);
return true;
}
@@ -140,6 +146,7 @@ DLLEXPORT FPDF_BOOL FPDFPath_SetDrawMode(FPDF_PAGEOBJECT path,
else
pPathObj->m_FillType = 0;
pPathObj->m_bStroke = stroke != 0;
+ pPathObj->SetDirty(true);
return true;
}
@@ -157,6 +164,7 @@ DLLEXPORT void STDCALL FPDFPath_SetLineJoin(FPDF_PAGEOBJECT path,
CFX_GraphStateData::LineJoin lineJoin =
static_cast<CFX_GraphStateData::LineJoin>(line_join);
pPathObj->m_GraphState.SetLineJoin(lineJoin);
+ pPathObj->SetDirty(true);
}
DLLEXPORT void STDCALL FPDFPath_SetLineCap(FPDF_PAGEOBJECT path, int line_cap) {
@@ -170,4 +178,5 @@ DLLEXPORT void STDCALL FPDFPath_SetLineCap(FPDF_PAGEOBJECT path, int line_cap) {
CFX_GraphStateData::LineCap lineCap =
static_cast<CFX_GraphStateData::LineCap>(line_cap);
pPathObj->m_GraphState.SetLineCap(lineCap);
+ pPathObj->SetDirty(true);
}
diff --git a/testing/resources/bug_717.pdf b/testing/resources/bug_717.pdf
new file mode 100644
index 0000000000..e3abd00e9e
--- /dev/null
+++ b/testing/resources/bug_717.pdf
Binary files differ