Add FPDFPageObj_TransformF() API Add a variation of the FPDFPageObj_Transform() API that takes a FS_MATRIX, instead of 6 doubles for the matrix. The new API also returns whether it succeeded or not. - Reimplement FPDFPageObj_Transform() using FPDFPageObj_TransformF(). - Switch a couple of existing FPDFPageObj_Transform() calls in tests to use the new API. - Add test to show the new API correctly handles bad inputs and returns false. Bug: 352379279 Change-Id: I70c507c24ad69c71771e3a457fedeca37bdc1da4 Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/121630 Reviewed-by: dan sinclair <dsinclair@google.com> Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/fpdf_edit_embeddertest.cpp b/fpdfsdk/fpdf_edit_embeddertest.cpp index e5ace98..2f7d6b0 100644 --- a/fpdfsdk/fpdf_edit_embeddertest.cpp +++ b/fpdfsdk/fpdf_edit_embeddertest.cpp
@@ -308,7 +308,8 @@ ScopedFPDFWideString text = GetFPDFWideString(L"这是第一句。 这是第二行。"); EXPECT_TRUE(FPDFText_SetText(text_object, text.get())); - FPDFPageObj_Transform(text_object, 1, 0, 0, 1, 50, 200); + const FS_MATRIX matrix(1, 0, 0, 1, 50, 200); + ASSERT_TRUE(FPDFPageObj_TransformF(text_object, &matrix)); FPDFPage_InsertObject(page.get(), text_object); EXPECT_TRUE(FPDFPage_GenerateContent(page.get())); @@ -355,7 +356,8 @@ EXPECT_TRUE( FPDFText_SetCharcodes(text_object, charcodes.data(), charcodes.size())); - FPDFPageObj_Transform(text_object, 1, 0, 0, 1, 50, 200); + const FS_MATRIX matrix(1, 0, 0, 1, 50, 200); + ASSERT_TRUE(FPDFPageObj_TransformF(text_object, &matrix)); FPDFPage_InsertObject(page.get(), text_object); EXPECT_TRUE(FPDFPage_GenerateContent(page.get())); @@ -5324,6 +5326,17 @@ VerifySavedDocument(kExpectedWidth, kExpectedHeight, HelloWorldChecksum()); } +TEST_F(FPDFEditEmbedderTest, PageObjTransformFWithBadParameters) { + ScopedFPDFDocument doc(FPDF_CreateNewDocument()); + ScopedFPDFPageObject image(FPDFPageObj_NewImageObj(doc.get())); + ASSERT_TRUE(image); + + const FS_MATRIX matrix(1, 2, 3, 4, 5, 6); + EXPECT_FALSE(FPDFPageObj_TransformF(nullptr, nullptr)); + EXPECT_FALSE(FPDFPageObj_TransformF(image.get(), nullptr)); + EXPECT_FALSE(FPDFPageObj_TransformF(nullptr, &matrix)); +} + class FPDFEditMoveEmbedderTest : public EmbedderTest { protected: std::vector<std::string> HashesForDocument(int page_count) {
diff --git a/fpdfsdk/fpdf_editpage.cpp b/fpdfsdk/fpdf_editpage.cpp index 9ddd89f..5ed4c08 100644 --- a/fpdfsdk/fpdf_editpage.cpp +++ b/fpdfsdk/fpdf_editpage.cpp
@@ -640,12 +640,24 @@ double d, double e, double f) { - CPDF_PageObject* pPageObj = CPDFPageObjectFromFPDFPageObject(page_object); - if (!pPageObj) - return; + const FS_MATRIX matrix((float)a, (float)b, (float)c, (float)d, (float)e, + (float)f); + FPDFPageObj_TransformF(page_object, &matrix); +} - CFX_Matrix matrix((float)a, (float)b, (float)c, (float)d, (float)e, (float)f); - pPageObj->Transform(matrix); +FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV +FPDFPageObj_TransformF(FPDF_PAGEOBJECT page_object, const FS_MATRIX* matrix) { + if (!matrix) { + return false; + } + + CPDF_PageObject* cpage_object = CPDFPageObjectFromFPDFPageObject(page_object); + if (!cpage_object) { + return false; + } + + cpage_object->Transform(CFXMatrixFromFSMatrix(*matrix)); + return true; } FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
diff --git a/fpdfsdk/fpdf_view_c_api_test.c b/fpdfsdk/fpdf_view_c_api_test.c index 542dd88..5042fcf 100644 --- a/fpdfsdk/fpdf_view_c_api_test.c +++ b/fpdfsdk/fpdf_view_c_api_test.c
@@ -232,6 +232,7 @@ CHK(FPDFPageObj_SetStrokeColor); CHK(FPDFPageObj_SetStrokeWidth); CHK(FPDFPageObj_Transform); + CHK(FPDFPageObj_TransformF); CHK(FPDFPage_CountObjects); CHK(FPDFPage_Delete); CHK(FPDFPage_GenerateContent);
diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h index 35b5803..deae22f 100644 --- a/public/fpdf_edit.h +++ b/public/fpdf_edit.h
@@ -284,6 +284,21 @@ double f); // Experimental API. +// Transform |page_object| by the given matrix. +// +// page_object - handle to a page object. +// matrix - the transform matrix. +// +// Returns TRUE on success. +// +// This can be used to scale, rotate, shear and translate the |page_object|. +// It is an improved version of FPDFPageObj_Transform() that does not do +// unnecessary double to float conversions, and only uses 1 parameter for the +// matrix. It also returns whether the operation succeeded or not. +FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV +FPDFPageObj_TransformF(FPDF_PAGEOBJECT page_object, const FS_MATRIX* matrix); + +// Experimental API. // Get the transform matrix of a page object. // // page_object - handle to a page object.