Make bounding box changes take effect immediately.
Similar to https://crbug.com/pdfium/1209 for FPDFPage_SetRotation(),
FPDFPage_SetCropBox() and FPDFPage_SetMediaBox() do not take effect
immediately. Fix this by adding more CPDF_Page::UpdateDimensions()
calls.
Add tests similar to the FPDFPage_SetRotation() tests to make sure this
works correctly.
Change-Id: I5cebff52d0a637c871d26036c2b5ad290608dab0
Reviewed-on: https://pdfium-review.googlesource.com/c/47670
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/fpdf_transformpage.cpp b/fpdfsdk/fpdf_transformpage.cpp
index 2b86abb..aedfff4 100644
--- a/fpdfsdk/fpdf_transformpage.cpp
+++ b/fpdfsdk/fpdf_transformpage.cpp
@@ -30,8 +30,11 @@
void SetBoundingBox(CPDF_Page* page,
const ByteString& key,
const CFX_FloatRect& rect) {
- if (page)
- page->GetDict()->SetRectFor(key, rect);
+ if (!page)
+ return;
+
+ page->GetDict()->SetRectFor(key, rect);
+ page->UpdateDimensions();
}
bool GetBoundingBox(CPDF_Page* page,
diff --git a/fpdfsdk/fpdf_transformpage_embeddertest.cpp b/fpdfsdk/fpdf_transformpage_embeddertest.cpp
index 2a80e4e..36f86f3 100644
--- a/fpdfsdk/fpdf_transformpage_embeddertest.cpp
+++ b/fpdfsdk/fpdf_transformpage_embeddertest.cpp
@@ -188,6 +188,153 @@
UnloadPage(page);
}
+TEST_F(FPDFTransformEmbedderTest, SetCropBox) {
+ const char kOriginalMD5[] = "0a90de37f52127619c3dfb642b5fa2fe";
+ const char kCroppedMD5[] = "9937883715d5144c079fb8f7e3d4f395";
+
+ {
+ ASSERT_TRUE(OpenDocument("rectangles.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ {
+ // Render the page as is.
+ FS_RECTF cropbox;
+ EXPECT_FALSE(FPDFPage_GetCropBox(page, &cropbox.left, &cropbox.bottom,
+ &cropbox.right, &cropbox.top));
+ const int page_width = static_cast<int>(FPDF_GetPageWidth(page));
+ const int page_height = static_cast<int>(FPDF_GetPageHeight(page));
+ EXPECT_EQ(200, page_width);
+ EXPECT_EQ(300, page_height);
+ ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
+ CompareBitmap(bitmap.get(), page_width, page_height, kOriginalMD5);
+ }
+
+ FPDFPage_SetCropBox(page, 10, 20, 100, 150);
+
+ {
+ // Render the page after setting the CropBox.
+ // Note that the change affects the rendering, as expected.
+ // It behaves just like the case below, rather than the case above.
+ FS_RECTF cropbox;
+ EXPECT_TRUE(FPDFPage_GetCropBox(page, &cropbox.left, &cropbox.bottom,
+ &cropbox.right, &cropbox.top));
+ EXPECT_EQ(10, cropbox.left);
+ EXPECT_EQ(20, cropbox.bottom);
+ EXPECT_EQ(100, cropbox.right);
+ EXPECT_EQ(150, cropbox.top);
+ const int page_width = static_cast<int>(FPDF_GetPageWidth(page));
+ const int page_height = static_cast<int>(FPDF_GetPageHeight(page));
+ EXPECT_EQ(90, page_width);
+ EXPECT_EQ(130, page_height);
+ ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
+ CompareBitmap(bitmap.get(), page_width, page_height, kCroppedMD5);
+ }
+
+ UnloadPage(page);
+ }
+
+ {
+ // Save a copy, open the copy, and render it.
+ // Note that it renders the rotation.
+ EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
+ OpenSavedDocument(nullptr);
+ FPDF_PAGE saved_page = LoadSavedPage(0);
+ ASSERT_TRUE(saved_page);
+
+ FS_RECTF cropbox;
+ EXPECT_TRUE(FPDFPage_GetCropBox(saved_page, &cropbox.left, &cropbox.bottom,
+ &cropbox.right, &cropbox.top));
+ EXPECT_EQ(10, cropbox.left);
+ EXPECT_EQ(20, cropbox.bottom);
+ EXPECT_EQ(100, cropbox.right);
+ EXPECT_EQ(150, cropbox.top);
+ const int page_width = static_cast<int>(FPDF_GetPageWidth(saved_page));
+ const int page_height = static_cast<int>(FPDF_GetPageHeight(saved_page));
+ EXPECT_EQ(90, page_width);
+ EXPECT_EQ(130, page_height);
+ ScopedFPDFBitmap bitmap = RenderSavedPage(saved_page);
+ CompareBitmap(bitmap.get(), page_width, page_height, kCroppedMD5);
+
+ CloseSavedPage(saved_page);
+ CloseSavedDocument();
+ }
+}
+
+TEST_F(FPDFTransformEmbedderTest, SetMediaBox) {
+ const char kOriginalMD5[] = "0a90de37f52127619c3dfb642b5fa2fe";
+ const char kShrunkMD5[] = "eab5958f62f7ce65d7c32de98389fee1";
+
+ {
+ ASSERT_TRUE(OpenDocument("rectangles.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ {
+ // Render the page as is.
+ FS_RECTF mediabox;
+ EXPECT_FALSE(FPDFPage_GetMediaBox(page, &mediabox.left, &mediabox.bottom,
+ &mediabox.right, &mediabox.top));
+ const int page_width = static_cast<int>(FPDF_GetPageWidth(page));
+ const int page_height = static_cast<int>(FPDF_GetPageHeight(page));
+ EXPECT_EQ(200, page_width);
+ EXPECT_EQ(300, page_height);
+ ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
+ CompareBitmap(bitmap.get(), page_width, page_height, kOriginalMD5);
+ }
+
+ FPDFPage_SetMediaBox(page, 20, 30, 100, 150);
+
+ {
+ // Render the page after setting the MediaBox.
+ // Note that the change affects the rendering, as expected.
+ // It behaves just like the case below, rather than the case above.
+ FS_RECTF mediabox;
+ EXPECT_TRUE(FPDFPage_GetMediaBox(page, &mediabox.left, &mediabox.bottom,
+ &mediabox.right, &mediabox.top));
+ EXPECT_EQ(20, mediabox.left);
+ EXPECT_EQ(30, mediabox.bottom);
+ EXPECT_EQ(100, mediabox.right);
+ EXPECT_EQ(150, mediabox.top);
+ const int page_width = static_cast<int>(FPDF_GetPageWidth(page));
+ const int page_height = static_cast<int>(FPDF_GetPageHeight(page));
+ EXPECT_EQ(80, page_width);
+ EXPECT_EQ(120, page_height);
+ ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
+ CompareBitmap(bitmap.get(), page_width, page_height, kShrunkMD5);
+ }
+
+ UnloadPage(page);
+ }
+
+ {
+ // Save a copy, open the copy, and render it.
+ // Note that it renders the rotation.
+ EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
+ OpenSavedDocument(nullptr);
+ FPDF_PAGE saved_page = LoadSavedPage(0);
+ ASSERT_TRUE(saved_page);
+
+ FS_RECTF mediabox;
+ EXPECT_TRUE(FPDFPage_GetMediaBox(saved_page, &mediabox.left,
+ &mediabox.bottom, &mediabox.right,
+ &mediabox.top));
+ EXPECT_EQ(20, mediabox.left);
+ EXPECT_EQ(30, mediabox.bottom);
+ EXPECT_EQ(100, mediabox.right);
+ EXPECT_EQ(150, mediabox.top);
+ const int page_width = static_cast<int>(FPDF_GetPageWidth(saved_page));
+ const int page_height = static_cast<int>(FPDF_GetPageHeight(saved_page));
+ EXPECT_EQ(80, page_width);
+ EXPECT_EQ(120, page_height);
+ ScopedFPDFBitmap bitmap = RenderSavedPage(saved_page);
+ CompareBitmap(bitmap.get(), page_width, page_height, kShrunkMD5);
+
+ CloseSavedPage(saved_page);
+ CloseSavedDocument();
+ }
+}
+
TEST_F(FPDFTransformEmbedderTest, ClipPath) {
ASSERT_TRUE(OpenDocument("hello_world.pdf"));