1 // Copyright 2018 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "public/fpdf_transformpage.h"
6
7 #include "build/build_config.h"
8 #include "core/fxge/cfx_defaultrenderdevice.h"
9 #include "testing/embedder_test.h"
10 #include "testing/embedder_test_constants.h"
11
12 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
13 #include "testing/scoped_locale.h"
14 #endif
15
16 using pdfium::RectanglesChecksum;
17
18 namespace {
19
ShrunkChecksum()20 const char* ShrunkChecksum() {
21 if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
22 return "78c52d6029283090036e6db6683401e2";
23 }
24 return "f4136cc9209207ab60eb8381a3df2e69";
25 }
26
27 } // namespace
28
29 class FPDFTransformEmbedderTest : public EmbedderTest {};
30
TEST_F(FPDFTransformEmbedderTest,GetBoundingBoxes)31 TEST_F(FPDFTransformEmbedderTest, GetBoundingBoxes) {
32 ASSERT_TRUE(OpenDocument("cropped_text.pdf"));
33 ASSERT_EQ(4, FPDF_GetPageCount(document()));
34
35 {
36 ScopedEmbedderTestPage page = LoadScopedPage(1);
37 ASSERT_TRUE(page);
38
39 FS_RECTF mediabox;
40 EXPECT_TRUE(FPDFPage_GetMediaBox(page.get(), &mediabox.left,
41 &mediabox.bottom, &mediabox.right,
42 &mediabox.top));
43 EXPECT_EQ(-50, mediabox.left);
44 EXPECT_EQ(-50, mediabox.bottom);
45 EXPECT_EQ(200, mediabox.right);
46 EXPECT_EQ(200, mediabox.top);
47
48 FS_RECTF cropbox;
49 EXPECT_TRUE(FPDFPage_GetCropBox(page.get(), &cropbox.left, &cropbox.bottom,
50 &cropbox.right, &cropbox.top));
51 EXPECT_EQ(50, cropbox.left);
52 EXPECT_EQ(50, cropbox.bottom);
53 EXPECT_EQ(150, cropbox.right);
54 EXPECT_EQ(150, cropbox.top);
55
56 FS_RECTF bleedbox;
57 EXPECT_TRUE(FPDFPage_GetBleedBox(page.get(), &bleedbox.left,
58 &bleedbox.bottom, &bleedbox.right,
59 &bleedbox.top));
60 EXPECT_EQ(0, bleedbox.left);
61 EXPECT_EQ(10, bleedbox.bottom);
62 EXPECT_EQ(150, bleedbox.right);
63 EXPECT_EQ(145, bleedbox.top);
64
65 FS_RECTF trimbox;
66 EXPECT_TRUE(FPDFPage_GetTrimBox(page.get(), &trimbox.left, &trimbox.bottom,
67 &trimbox.right, &trimbox.top));
68 EXPECT_EQ(25, trimbox.left);
69 EXPECT_EQ(30, trimbox.bottom);
70 EXPECT_EQ(140, trimbox.right);
71 EXPECT_EQ(145, trimbox.top);
72
73 FS_RECTF artbox;
74 EXPECT_TRUE(FPDFPage_GetArtBox(page.get(), &artbox.left, &artbox.bottom,
75 &artbox.right, &artbox.top));
76 EXPECT_EQ(50, artbox.left);
77 EXPECT_EQ(60, artbox.bottom);
78 EXPECT_EQ(135, artbox.right);
79 EXPECT_EQ(140, artbox.top);
80 }
81
82 {
83 ScopedEmbedderTestPage page = LoadScopedPage(3);
84 ASSERT_TRUE(page);
85
86 FS_RECTF mediabox;
87 EXPECT_TRUE(FPDFPage_GetMediaBox(page.get(), &mediabox.left,
88 &mediabox.bottom, &mediabox.right,
89 &mediabox.top));
90 EXPECT_EQ(0, mediabox.left);
91 EXPECT_EQ(0, mediabox.bottom);
92 EXPECT_EQ(200, mediabox.right);
93 EXPECT_EQ(200, mediabox.top);
94
95 FS_RECTF cropbox;
96 EXPECT_TRUE(FPDFPage_GetCropBox(page.get(), &cropbox.left, &cropbox.bottom,
97 &cropbox.right, &cropbox.top));
98 EXPECT_EQ(150, cropbox.left);
99 EXPECT_EQ(150, cropbox.bottom);
100 EXPECT_EQ(60, cropbox.right);
101 EXPECT_EQ(60, cropbox.top);
102
103 EXPECT_FALSE(FPDFPage_GetCropBox(page.get(), nullptr, &cropbox.bottom,
104 &cropbox.right, &cropbox.top));
105 EXPECT_FALSE(FPDFPage_GetCropBox(page.get(), &cropbox.left, nullptr,
106 &cropbox.right, &cropbox.top));
107 EXPECT_FALSE(FPDFPage_GetCropBox(page.get(), &cropbox.left, &cropbox.bottom,
108 nullptr, &cropbox.top));
109 EXPECT_FALSE(FPDFPage_GetCropBox(page.get(), &cropbox.left, &cropbox.bottom,
110 &cropbox.right, nullptr));
111 EXPECT_FALSE(
112 FPDFPage_GetCropBox(page.get(), nullptr, nullptr, nullptr, nullptr));
113
114 FS_RECTF bleedbox;
115 EXPECT_TRUE(FPDFPage_GetBleedBox(page.get(), &bleedbox.left,
116 &bleedbox.bottom, &bleedbox.right,
117 &bleedbox.top));
118 EXPECT_EQ(160, bleedbox.left);
119 EXPECT_EQ(165, bleedbox.bottom);
120 EXPECT_EQ(0, bleedbox.right);
121 EXPECT_EQ(10, bleedbox.top);
122
123 FS_RECTF trimbox;
124 EXPECT_TRUE(FPDFPage_GetTrimBox(page.get(), &trimbox.left, &trimbox.bottom,
125 &trimbox.right, &trimbox.top));
126 EXPECT_EQ(155, trimbox.left);
127 EXPECT_EQ(165, trimbox.bottom);
128 EXPECT_EQ(25, trimbox.right);
129 EXPECT_EQ(30, trimbox.top);
130
131 FS_RECTF artbox;
132 EXPECT_TRUE(FPDFPage_GetArtBox(page.get(), &artbox.left, &artbox.bottom,
133 &artbox.right, &artbox.top));
134 EXPECT_EQ(140, artbox.left);
135 EXPECT_EQ(145, artbox.bottom);
136 EXPECT_EQ(65, artbox.right);
137 EXPECT_EQ(70, artbox.top);
138 }
139 }
140
TEST_F(FPDFTransformEmbedderTest,NoCropBox)141 TEST_F(FPDFTransformEmbedderTest, NoCropBox) {
142 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
143 ASSERT_EQ(1, FPDF_GetPageCount(document()));
144
145 ScopedEmbedderTestPage page = LoadScopedPage(0);
146 ASSERT_TRUE(page);
147
148 FS_RECTF cropbox = {-1.0f, 0.0f, 3.0f, -2.0f};
149 EXPECT_FALSE(FPDFPage_GetCropBox(page.get(), &cropbox.left, &cropbox.bottom,
150 &cropbox.right, &cropbox.top));
151 EXPECT_EQ(-1.0f, cropbox.left);
152 EXPECT_EQ(-2.0f, cropbox.bottom);
153 EXPECT_EQ(3.0f, cropbox.right);
154 EXPECT_EQ(0.0f, cropbox.top);
155 }
156
TEST_F(FPDFTransformEmbedderTest,NoBleedBox)157 TEST_F(FPDFTransformEmbedderTest, NoBleedBox) {
158 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
159 ASSERT_EQ(1, FPDF_GetPageCount(document()));
160
161 ScopedEmbedderTestPage page = LoadScopedPage(0);
162 ASSERT_TRUE(page);
163
164 FS_RECTF bleedbox = {-1.0f, 10.f, 3.0f, -1.0f};
165 EXPECT_FALSE(FPDFPage_GetBleedBox(page.get(), &bleedbox.left,
166 &bleedbox.bottom, &bleedbox.right,
167 &bleedbox.top));
168 EXPECT_EQ(-1.0f, bleedbox.left);
169 EXPECT_EQ(-1.0f, bleedbox.bottom);
170 EXPECT_EQ(3.0f, bleedbox.right);
171 EXPECT_EQ(10.0f, bleedbox.top);
172 }
173
TEST_F(FPDFTransformEmbedderTest,NoTrimBox)174 TEST_F(FPDFTransformEmbedderTest, NoTrimBox) {
175 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
176 ASSERT_EQ(1, FPDF_GetPageCount(document()));
177
178 ScopedEmbedderTestPage page = LoadScopedPage(0);
179 ASSERT_TRUE(page);
180
181 FS_RECTF trimbox = {-11.0f, 0.0f, 3.0f, -10.0f};
182 EXPECT_FALSE(FPDFPage_GetTrimBox(page.get(), &trimbox.left, &trimbox.bottom,
183 &trimbox.right, &trimbox.top));
184 EXPECT_EQ(-11.0f, trimbox.left);
185 EXPECT_EQ(-10.0f, trimbox.bottom);
186 EXPECT_EQ(3.0f, trimbox.right);
187 EXPECT_EQ(0.0f, trimbox.top);
188 }
189
TEST_F(FPDFTransformEmbedderTest,NoArtBox)190 TEST_F(FPDFTransformEmbedderTest, NoArtBox) {
191 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
192 ASSERT_EQ(1, FPDF_GetPageCount(document()));
193
194 ScopedEmbedderTestPage page = LoadScopedPage(0);
195 ASSERT_TRUE(page);
196
197 FS_RECTF artbox = {-1.0f, 0.0f, 3.0f, -1.0f};
198 EXPECT_FALSE(FPDFPage_GetArtBox(page.get(), &artbox.left, &artbox.bottom,
199 &artbox.right, &artbox.top));
200 EXPECT_EQ(-1.0f, artbox.left);
201 EXPECT_EQ(-1.0f, artbox.bottom);
202 EXPECT_EQ(3.0f, artbox.right);
203 EXPECT_EQ(0.0f, artbox.top);
204 }
205
TEST_F(FPDFTransformEmbedderTest,SetCropBox)206 TEST_F(FPDFTransformEmbedderTest, SetCropBox) {
207 const char* cropped_checksum = []() {
208 if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
209 return "4b9d2d2246be61c583f454245fe3172f";
210 }
211 return "9937883715d5144c079fb8f7e3d4f395";
212 }();
213 {
214 ASSERT_TRUE(OpenDocument("rectangles.pdf"));
215 ScopedEmbedderTestPage page = LoadScopedPage(0);
216 ASSERT_TRUE(page);
217
218 {
219 // Render the page as is.
220 FS_RECTF cropbox;
221 EXPECT_FALSE(FPDFPage_GetCropBox(page.get(), &cropbox.left,
222 &cropbox.bottom, &cropbox.right,
223 &cropbox.top));
224 const int page_width = static_cast<int>(FPDF_GetPageWidth(page.get()));
225 const int page_height = static_cast<int>(FPDF_GetPageHeight(page.get()));
226 EXPECT_EQ(200, page_width);
227 EXPECT_EQ(300, page_height);
228 ScopedFPDFBitmap bitmap = RenderLoadedPage(page.get());
229 CompareBitmap(bitmap.get(), page_width, page_height,
230 RectanglesChecksum());
231 }
232
233 FPDFPage_SetCropBox(page.get(), 10, 20, 100, 150);
234
235 {
236 // Render the page after setting the CropBox.
237 // Note that the change affects the rendering, as expected.
238 // It behaves just like the case below, rather than the case above.
239 FS_RECTF cropbox;
240 EXPECT_TRUE(FPDFPage_GetCropBox(page.get(), &cropbox.left,
241 &cropbox.bottom, &cropbox.right,
242 &cropbox.top));
243 EXPECT_EQ(10, cropbox.left);
244 EXPECT_EQ(20, cropbox.bottom);
245 EXPECT_EQ(100, cropbox.right);
246 EXPECT_EQ(150, cropbox.top);
247 const int page_width = static_cast<int>(FPDF_GetPageWidth(page.get()));
248 const int page_height = static_cast<int>(FPDF_GetPageHeight(page.get()));
249 EXPECT_EQ(90, page_width);
250 EXPECT_EQ(130, page_height);
251 ScopedFPDFBitmap bitmap = RenderLoadedPage(page.get());
252 CompareBitmap(bitmap.get(), page_width, page_height, cropped_checksum);
253 }
254 }
255
256 {
257 // Save a copy, open the copy, and render it.
258 // Note that it renders the rotation.
259 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
260 ASSERT_TRUE(OpenSavedDocument());
261 FPDF_PAGE saved_page = LoadSavedPage(0);
262 ASSERT_TRUE(saved_page);
263
264 FS_RECTF cropbox;
265 EXPECT_TRUE(FPDFPage_GetCropBox(saved_page, &cropbox.left, &cropbox.bottom,
266 &cropbox.right, &cropbox.top));
267 EXPECT_EQ(10, cropbox.left);
268 EXPECT_EQ(20, cropbox.bottom);
269 EXPECT_EQ(100, cropbox.right);
270 EXPECT_EQ(150, cropbox.top);
271 const int page_width = static_cast<int>(FPDF_GetPageWidth(saved_page));
272 const int page_height = static_cast<int>(FPDF_GetPageHeight(saved_page));
273 EXPECT_EQ(90, page_width);
274 EXPECT_EQ(130, page_height);
275 ScopedFPDFBitmap bitmap = RenderSavedPage(saved_page);
276 CompareBitmap(bitmap.get(), page_width, page_height, cropped_checksum);
277
278 CloseSavedPage(saved_page);
279 CloseSavedDocument();
280 }
281 }
282
TEST_F(FPDFTransformEmbedderTest,SetMediaBox)283 TEST_F(FPDFTransformEmbedderTest, SetMediaBox) {
284 const char* shrunk_checksum_set_media_box = []() {
285 if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
286 return "9f28f0610a7f789c24cfd5f9bd5dc3de";
287 }
288 return "eab5958f62f7ce65d7c32de98389fee1";
289 }();
290
291 {
292 ASSERT_TRUE(OpenDocument("rectangles.pdf"));
293 ScopedEmbedderTestPage page = LoadScopedPage(0);
294 ASSERT_TRUE(page);
295
296 {
297 // Render the page as is.
298 FS_RECTF mediabox;
299 EXPECT_FALSE(FPDFPage_GetMediaBox(page.get(), &mediabox.left,
300 &mediabox.bottom, &mediabox.right,
301 &mediabox.top));
302 const int page_width = static_cast<int>(FPDF_GetPageWidth(page.get()));
303 const int page_height = static_cast<int>(FPDF_GetPageHeight(page.get()));
304 EXPECT_EQ(200, page_width);
305 EXPECT_EQ(300, page_height);
306 ScopedFPDFBitmap bitmap = RenderLoadedPage(page.get());
307 CompareBitmap(bitmap.get(), page_width, page_height,
308 RectanglesChecksum());
309 }
310
311 FPDFPage_SetMediaBox(page.get(), 20, 30, 100, 150);
312
313 {
314 // Render the page after setting the MediaBox.
315 // Note that the change affects the rendering, as expected.
316 // It behaves just like the case below, rather than the case above.
317 FS_RECTF mediabox;
318 EXPECT_TRUE(FPDFPage_GetMediaBox(page.get(), &mediabox.left,
319 &mediabox.bottom, &mediabox.right,
320 &mediabox.top));
321 EXPECT_EQ(20, mediabox.left);
322 EXPECT_EQ(30, mediabox.bottom);
323 EXPECT_EQ(100, mediabox.right);
324 EXPECT_EQ(150, mediabox.top);
325 const int page_width = static_cast<int>(FPDF_GetPageWidth(page.get()));
326 const int page_height = static_cast<int>(FPDF_GetPageHeight(page.get()));
327 EXPECT_EQ(80, page_width);
328 EXPECT_EQ(120, page_height);
329 ScopedFPDFBitmap bitmap = RenderLoadedPage(page.get());
330 CompareBitmap(bitmap.get(), page_width, page_height,
331 shrunk_checksum_set_media_box);
332 }
333 }
334
335 {
336 // Save a copy, open the copy, and render it.
337 // Note that it renders the rotation.
338 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
339 ASSERT_TRUE(OpenSavedDocument());
340 FPDF_PAGE saved_page = LoadSavedPage(0);
341 ASSERT_TRUE(saved_page);
342
343 FS_RECTF mediabox;
344 EXPECT_TRUE(FPDFPage_GetMediaBox(saved_page, &mediabox.left,
345 &mediabox.bottom, &mediabox.right,
346 &mediabox.top));
347 EXPECT_EQ(20, mediabox.left);
348 EXPECT_EQ(30, mediabox.bottom);
349 EXPECT_EQ(100, mediabox.right);
350 EXPECT_EQ(150, mediabox.top);
351 const int page_width = static_cast<int>(FPDF_GetPageWidth(saved_page));
352 const int page_height = static_cast<int>(FPDF_GetPageHeight(saved_page));
353 EXPECT_EQ(80, page_width);
354 EXPECT_EQ(120, page_height);
355 ScopedFPDFBitmap bitmap = RenderSavedPage(saved_page);
356 CompareBitmap(bitmap.get(), page_width, page_height,
357 shrunk_checksum_set_media_box);
358
359 CloseSavedPage(saved_page);
360 CloseSavedDocument();
361 }
362 }
363
TEST_F(FPDFTransformEmbedderTest,ClipPath)364 TEST_F(FPDFTransformEmbedderTest, ClipPath) {
365 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
366
367 ScopedEmbedderTestPage page = LoadScopedPage(0);
368 ASSERT_TRUE(page);
369
370 ScopedFPDFClipPath clip(FPDF_CreateClipPath(10.0f, 10.0f, 90.0f, 90.0f));
371 EXPECT_TRUE(clip);
372
373 // NULL arg call is a no-op.
374 FPDFPage_InsertClipPath(nullptr, clip.get());
375
376 // Do actual work.
377 FPDFPage_InsertClipPath(page.get(), clip.get());
378
379 // TODO(tsepez): test how inserting path affects page rendering.
380 }
381
TEST_F(FPDFTransformEmbedderTest,TransFormWithClip)382 TEST_F(FPDFTransformEmbedderTest, TransFormWithClip) {
383 const FS_MATRIX half_matrix{0.5, 0, 0, 0.5, 0, 0};
384 const FS_RECTF clip_rect = {0.0f, 0.0f, 20.0f, 10.0f};
385
386 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
387
388 ScopedEmbedderTestPage page = LoadScopedPage(0);
389 ASSERT_TRUE(page);
390
391 EXPECT_FALSE(FPDFPage_TransFormWithClip(nullptr, nullptr, nullptr));
392 EXPECT_FALSE(FPDFPage_TransFormWithClip(nullptr, &half_matrix, nullptr));
393 EXPECT_FALSE(FPDFPage_TransFormWithClip(nullptr, nullptr, &clip_rect));
394 EXPECT_FALSE(FPDFPage_TransFormWithClip(nullptr, &half_matrix, &clip_rect));
395 EXPECT_FALSE(FPDFPage_TransFormWithClip(page.get(), nullptr, nullptr));
396 EXPECT_TRUE(FPDFPage_TransFormWithClip(page.get(), &half_matrix, nullptr));
397 EXPECT_TRUE(FPDFPage_TransFormWithClip(page.get(), nullptr, &clip_rect));
398 EXPECT_TRUE(FPDFPage_TransFormWithClip(page.get(), &half_matrix, &clip_rect));
399 }
400
TEST_F(FPDFTransformEmbedderTest,TransFormWithClipWithPatterns)401 TEST_F(FPDFTransformEmbedderTest, TransFormWithClipWithPatterns) {
402 const FS_MATRIX half_matrix{0.5, 0, 0, 0.5, 0, 0};
403 const FS_RECTF clip_rect = {0.0f, 0.0f, 20.0f, 10.0f};
404
405 ASSERT_TRUE(OpenDocument("bug_547706.pdf"));
406
407 ScopedEmbedderTestPage page = LoadScopedPage(0);
408 ASSERT_TRUE(page);
409
410 EXPECT_TRUE(FPDFPage_TransFormWithClip(page.get(), &half_matrix, nullptr));
411 EXPECT_TRUE(FPDFPage_TransFormWithClip(page.get(), nullptr, &clip_rect));
412 EXPECT_TRUE(FPDFPage_TransFormWithClip(page.get(), &half_matrix, &clip_rect));
413 }
414
TEST_F(FPDFTransformEmbedderTest,TransFormWithClipAndSave)415 TEST_F(FPDFTransformEmbedderTest, TransFormWithClipAndSave) {
416 {
417 ASSERT_TRUE(OpenDocument("rectangles.pdf"));
418 ScopedEmbedderTestPage page = LoadScopedPage(0);
419 ASSERT_TRUE(page);
420
421 {
422 // Render the page as is.
423 const int page_width = static_cast<int>(FPDF_GetPageWidth(page.get()));
424 const int page_height = static_cast<int>(FPDF_GetPageHeight(page.get()));
425 EXPECT_EQ(200, page_width);
426 EXPECT_EQ(300, page_height);
427 ScopedFPDFBitmap bitmap = RenderLoadedPage(page.get());
428 CompareBitmap(bitmap.get(), page_width, page_height,
429 RectanglesChecksum());
430 }
431
432 {
433 // Render the page after transforming.
434 // Note that the change should affect the rendering, but does not.
435 // It should behaves just like the case below, rather than the case above.
436 // TODO(crbug.com/pdfium/1328): The checksum after invoking
437 // `FPDFPage_TransFormWithClip()` below should match `ShrunkChecksum()`.
438 const FS_MATRIX half_matrix{0.5, 0, 0, 0.5, 0, 0};
439 EXPECT_TRUE(
440 FPDFPage_TransFormWithClip(page.get(), &half_matrix, nullptr));
441 const int page_width = static_cast<int>(FPDF_GetPageWidth(page.get()));
442 const int page_height = static_cast<int>(FPDF_GetPageHeight(page.get()));
443 EXPECT_EQ(200, page_width);
444 EXPECT_EQ(300, page_height);
445 ScopedFPDFBitmap bitmap = RenderLoadedPage(page.get());
446 CompareBitmap(bitmap.get(), page_width, page_height,
447 RectanglesChecksum());
448 }
449 }
450
451 {
452 // Save a copy, open the copy, and render it.
453 // Note that it renders the transform.
454 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
455 ASSERT_TRUE(OpenSavedDocument());
456 FPDF_PAGE saved_page = LoadSavedPage(0);
457 ASSERT_TRUE(saved_page);
458
459 const int page_width = static_cast<int>(FPDF_GetPageWidth(saved_page));
460 const int page_height = static_cast<int>(FPDF_GetPageHeight(saved_page));
461 EXPECT_EQ(200, page_width);
462 EXPECT_EQ(300, page_height);
463 ScopedFPDFBitmap bitmap = RenderSavedPage(saved_page);
464 CompareBitmap(bitmap.get(), page_width, page_height, ShrunkChecksum());
465
466 CloseSavedPage(saved_page);
467 CloseSavedDocument();
468 }
469 }
470
471 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
TEST_F(FPDFTransformEmbedderTest,TransFormWithClipAndSaveWithLocale)472 TEST_F(FPDFTransformEmbedderTest, TransFormWithClipAndSaveWithLocale) {
473 pdfium::ScopedLocale scoped_locale("da_DK.UTF-8");
474
475 {
476 ASSERT_TRUE(OpenDocument("rectangles.pdf"));
477 ScopedEmbedderTestPage page = LoadScopedPage(0);
478 ASSERT_TRUE(page);
479
480 {
481 // Render the page as is.
482 const int page_width = static_cast<int>(FPDF_GetPageWidth(page.get()));
483 const int page_height = static_cast<int>(FPDF_GetPageHeight(page.get()));
484 EXPECT_EQ(200, page_width);
485 EXPECT_EQ(300, page_height);
486 ScopedFPDFBitmap bitmap = RenderLoadedPage(page.get());
487 CompareBitmap(bitmap.get(), page_width, page_height,
488 RectanglesChecksum());
489 }
490
491 {
492 // Render the page after transforming.
493 // Note that the change should affect the rendering, but does not.
494 // It should behaves just like the case below, rather than the case above.
495 // TODO(crbug.com/pdfium/1328): The checksum after invoking
496 // `FPDFPage_TransFormWithClip()` below should match `ShrunkChecksum()`.
497 const FS_MATRIX half_matrix{0.5, 0, 0, 0.5, 0, 0};
498 EXPECT_TRUE(
499 FPDFPage_TransFormWithClip(page.get(), &half_matrix, nullptr));
500 const int page_width = static_cast<int>(FPDF_GetPageWidth(page.get()));
501 const int page_height = static_cast<int>(FPDF_GetPageHeight(page.get()));
502 EXPECT_EQ(200, page_width);
503 EXPECT_EQ(300, page_height);
504 ScopedFPDFBitmap bitmap = RenderLoadedPage(page.get());
505 CompareBitmap(bitmap.get(), page_width, page_height,
506 RectanglesChecksum());
507 }
508 }
509
510 {
511 // Save a copy, open the copy, and render it.
512 // Note that it renders the transform.
513 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
514 ASSERT_TRUE(OpenSavedDocument());
515 FPDF_PAGE saved_page = LoadSavedPage(0);
516 ASSERT_TRUE(saved_page);
517
518 const int page_width = static_cast<int>(FPDF_GetPageWidth(saved_page));
519 const int page_height = static_cast<int>(FPDF_GetPageHeight(saved_page));
520 EXPECT_EQ(200, page_width);
521 EXPECT_EQ(300, page_height);
522 ScopedFPDFBitmap bitmap = RenderSavedPage(saved_page);
523 CompareBitmap(bitmap.get(), page_width, page_height, ShrunkChecksum());
524
525 CloseSavedPage(saved_page);
526 CloseSavedDocument();
527 }
528 }
529 #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
530