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.