Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
fpdf_ppo_embeddertest.cpp
Go to the documentation of this file.
1// Copyright 2016 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 <iterator>
6#include <memory>
7#include <string>
8#include <vector>
9
10#include "core/fpdfapi/page/cpdf_form.h"
11#include "core/fpdfapi/page/cpdf_formobject.h"
12#include "core/fpdfapi/parser/cpdf_array.h"
13#include "core/fpdfapi/parser/cpdf_dictionary.h"
14#include "core/fpdfapi/parser/cpdf_document.h"
15#include "core/fpdfapi/parser/cpdf_name.h"
16#include "core/fpdfapi/parser/cpdf_number.h"
17#include "core/fpdfapi/parser/cpdf_stream.h"
18#include "core/fpdfapi/parser/cpdf_string.h"
19#include "core/fxge/cfx_defaultrenderdevice.h"
20#include "fpdfsdk/cpdfsdk_helpers.h"
21#include "public/cpp/fpdf_scopers.h"
22#include "public/fpdf_edit.h"
23#include "public/fpdf_ppo.h"
24#include "public/fpdf_save.h"
25#include "public/fpdfview.h"
26#include "testing/embedder_test.h"
27#include "testing/embedder_test_constants.h"
28#include "testing/gtest/include/gtest/gtest.h"
29#include "testing/utils/file_util.h"
30#include "testing/utils/path_service.h"
31
32namespace {
33
34class FPDFPPOEmbedderTest : public EmbedderTest {};
35
36int FakeBlockWriter(FPDF_FILEWRITE* pThis,
37 const void* pData,
38 unsigned long size) {
39 return 1; // Always succeeds.
40}
41
42constexpr int kRectanglesMultiPagesPageCount = 2;
43
44const char* RectanglesMultiPagesExpectedChecksum(int page_index) {
45 if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
46 static constexpr const char* kChecksums[kRectanglesMultiPagesPageCount] = {
47 "07606a12487bd0c28a88f23fa00fc313", "94ea6e1eef220833a3ec14d6a1c612b0"};
48 return kChecksums[page_index];
49 }
50 static constexpr const char* kChecksums[kRectanglesMultiPagesPageCount] = {
51 "72d0d7a19a2f40e010ca6a1133b33e1e", "fb18142190d770cfbc329d2b071aee4d"};
52 return kChecksums[page_index];
53}
54
55const char* Bug750568PageHash(int page_index) {
56 constexpr int kBug750568PageCount = 4;
57 if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
58 static constexpr const char* kChecksums[kBug750568PageCount] = {
59 "eaa139e944eafb43d31e8742a0e158de", "226485e9d4fa6a67dfe0a88723f12060",
60 "c5601a3492ae5dcc5dd25140fc463bfe", "1f60055b54de4fac8a59c65e90da156e"};
61 return kChecksums[page_index];
62 }
63 static constexpr const char* kChecksums[kBug750568PageCount] = {
64 "64ad08132a1c5a166768298c8a578f57", "83b83e2f6bc80707d0a917c7634140b9",
65 "913cd3723a451e4e46fbc2c05702d1ee", "81fb7cfd4860f855eb468f73dfeb6d60"};
66 return kChecksums[page_index];
67}
68
69} // namespace
70
71TEST_F(FPDFPPOEmbedderTest, NoViewerPreferences) {
72 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
73
74 ScopedFPDFDocument output_doc(FPDF_CreateNewDocument());
75 EXPECT_TRUE(output_doc);
76 EXPECT_FALSE(FPDF_CopyViewerPreferences(output_doc.get(), document()));
77}
78
79TEST_F(FPDFPPOEmbedderTest, ViewerPreferences) {
80 ASSERT_TRUE(OpenDocument("viewer_ref.pdf"));
81
82 ScopedFPDFDocument output_doc(FPDF_CreateNewDocument());
83 EXPECT_TRUE(output_doc);
84 EXPECT_TRUE(FPDF_CopyViewerPreferences(output_doc.get(), document()));
85}
86
87TEST_F(FPDFPPOEmbedderTest, ImportPagesByIndex) {
88 ASSERT_TRUE(OpenDocument("viewer_ref.pdf"));
89
90 FPDF_PAGE page = LoadPage(0);
91 EXPECT_TRUE(page);
92
93 ScopedFPDFDocument output_doc(FPDF_CreateNewDocument());
94 ASSERT_TRUE(output_doc);
95 EXPECT_TRUE(FPDF_CopyViewerPreferences(output_doc.get(), document()));
96
97 static constexpr int kPageIndices[] = {1};
98 EXPECT_TRUE(FPDF_ImportPagesByIndex(
99 output_doc.get(), document(), kPageIndices, std::size(kPageIndices), 0));
100 EXPECT_EQ(1, FPDF_GetPageCount(output_doc.get()));
101
102 UnloadPage(page);
103}
104
105TEST_F(FPDFPPOEmbedderTest, ImportPages) {
106 ASSERT_TRUE(OpenDocument("viewer_ref.pdf"));
107
108 FPDF_PAGE page = LoadPage(0);
109 EXPECT_TRUE(page);
110
111 ScopedFPDFDocument output_doc(FPDF_CreateNewDocument());
112 ASSERT_TRUE(output_doc);
113 EXPECT_TRUE(FPDF_CopyViewerPreferences(output_doc.get(), document()));
114 EXPECT_TRUE(FPDF_ImportPages(output_doc.get(), document(), "1", 0));
115 EXPECT_EQ(1, FPDF_GetPageCount(output_doc.get()));
116
117 UnloadPage(page);
118}
119
120TEST_F(FPDFPPOEmbedderTest, ImportNPages) {
121 ASSERT_TRUE(OpenDocument("rectangles_multi_pages.pdf"));
122
123 ScopedFPDFDocument output_doc_2up(
124 FPDF_ImportNPagesToOne(document(), 612, 792, 2, 1));
125 ASSERT_TRUE(output_doc_2up);
126 EXPECT_EQ(3, FPDF_GetPageCount(output_doc_2up.get()));
127 ScopedFPDFDocument output_doc_5up(
128 FPDF_ImportNPagesToOne(document(), 612, 792, 5, 1));
129 ASSERT_TRUE(output_doc_5up);
130 EXPECT_EQ(1, FPDF_GetPageCount(output_doc_5up.get()));
131 ScopedFPDFDocument output_doc_8up(
132 FPDF_ImportNPagesToOne(document(), 792, 612, 8, 1));
133 ASSERT_TRUE(output_doc_8up);
134 EXPECT_EQ(1, FPDF_GetPageCount(output_doc_8up.get()));
135 ScopedFPDFDocument output_doc_128up(
136 FPDF_ImportNPagesToOne(document(), 792, 612, 128, 1));
137 ASSERT_TRUE(output_doc_128up);
138 EXPECT_EQ(1, FPDF_GetPageCount(output_doc_128up.get()));
139}
140
141TEST_F(FPDFPPOEmbedderTest, BadNupParams) {
142 ASSERT_TRUE(OpenDocument("rectangles_multi_pages.pdf"));
143
144 FPDF_DOCUMENT output_doc_zero_row =
145 FPDF_ImportNPagesToOne(document(), 612, 792, 0, 3);
146 ASSERT_FALSE(output_doc_zero_row);
147 FPDF_DOCUMENT output_doc_zero_col =
148 FPDF_ImportNPagesToOne(document(), 612, 792, 2, 0);
149 ASSERT_FALSE(output_doc_zero_col);
150 FPDF_DOCUMENT output_doc_zero_width =
151 FPDF_ImportNPagesToOne(document(), 0, 792, 2, 1);
152 ASSERT_FALSE(output_doc_zero_width);
153 FPDF_DOCUMENT output_doc_zero_height =
154 FPDF_ImportNPagesToOne(document(), 612, 0, 7, 1);
155 ASSERT_FALSE(output_doc_zero_height);
156}
157
158// TODO(Xlou): Add more tests to check output doc content of
159// FPDF_ImportNPagesToOne()
160TEST_F(FPDFPPOEmbedderTest, NupRenderImage) {
161 ASSERT_TRUE(OpenDocument("rectangles_multi_pages.pdf"));
162 ScopedFPDFDocument output_doc_3up(
163 FPDF_ImportNPagesToOne(document(), 792, 612, 3, 1));
164 ASSERT_TRUE(output_doc_3up);
165 ASSERT_EQ(kRectanglesMultiPagesPageCount,
166 FPDF_GetPageCount(output_doc_3up.get()));
167 for (int i = 0; i < kRectanglesMultiPagesPageCount; ++i) {
168 ScopedFPDFPage page(FPDF_LoadPage(output_doc_3up.get(), i));
169 ASSERT_TRUE(page);
170 ScopedFPDFBitmap bitmap = RenderPage(page.get());
171 EXPECT_EQ(792, FPDFBitmap_GetWidth(bitmap.get()));
172 EXPECT_EQ(612, FPDFBitmap_GetHeight(bitmap.get()));
173 EXPECT_EQ(RectanglesMultiPagesExpectedChecksum(i),
174 HashBitmap(bitmap.get()));
175 }
176}
177
178TEST_F(FPDFPPOEmbedderTest, ImportPageToXObject) {
179 const char* checksum = []() {
180 if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
181 return "d6ebc0a8afc22fe0137f54ce54e1a19c";
182 }
183 return "2d88d180af7109eb346439f7c855bb29";
184 }();
185
186 ASSERT_TRUE(OpenDocument("rectangles.pdf"));
187
188 {
189 ScopedFPDFDocument output_doc(FPDF_CreateNewDocument());
190 ASSERT_TRUE(output_doc);
191
192 FPDF_XOBJECT xobject =
193 FPDF_NewXObjectFromPage(output_doc.get(), document(), 0);
194 ASSERT_TRUE(xobject);
195
196 for (int i = 0; i < 2; ++i) {
197 ScopedFPDFPage page(FPDFPage_New(output_doc.get(), 0, 612, 792));
198 ASSERT_TRUE(page);
199
200 FPDF_PAGEOBJECT page_object = FPDF_NewFormObjectFromXObject(xobject);
201 ASSERT_TRUE(page_object);
202 EXPECT_EQ(FPDF_PAGEOBJ_FORM, FPDFPageObj_GetType(page_object));
203 FPDFPage_InsertObject(page.get(), page_object);
204 EXPECT_TRUE(FPDFPage_GenerateContent(page.get()));
205
206 ScopedFPDFBitmap page_bitmap = RenderPage(page.get());
207 CompareBitmap(page_bitmap.get(), 612, 792, checksum);
208
209 float left;
210 float bottom;
211 float right;
212 float top;
213 ASSERT_TRUE(
214 FPDFPageObj_GetBounds(page_object, &left, &bottom, &right, &top));
215 EXPECT_FLOAT_EQ(-1.0f, left);
216 EXPECT_FLOAT_EQ(-1.0f, bottom);
217 EXPECT_FLOAT_EQ(201.0f, right);
218 EXPECT_FLOAT_EQ(301.0f, top);
219 }
220
221 EXPECT_TRUE(FPDF_SaveAsCopy(output_doc.get(), this, 0));
222
223 FPDF_CloseXObject(xobject);
224 }
225
226 constexpr int kExpectedPageCount = 2;
227 ASSERT_TRUE(OpenSavedDocument());
228
229 FPDF_PAGE saved_pages[kExpectedPageCount];
230 FPDF_PAGEOBJECT xobjects[kExpectedPageCount];
231 for (int i = 0; i < kExpectedPageCount; ++i) {
232 saved_pages[i] = LoadSavedPage(i);
233 ASSERT_TRUE(saved_pages[i]);
234
235 EXPECT_EQ(1, FPDFPage_CountObjects(saved_pages[i]));
236 xobjects[i] = FPDFPage_GetObject(saved_pages[i], 0);
237 ASSERT_TRUE(xobjects[i]);
238 ASSERT_EQ(FPDF_PAGEOBJ_FORM, FPDFPageObj_GetType(xobjects[i]));
239 EXPECT_EQ(8, FPDFFormObj_CountObjects(xobjects[i]));
240
241 {
242 ScopedFPDFBitmap page_bitmap = RenderPage(saved_pages[i]);
243 CompareBitmap(page_bitmap.get(), 612, 792, checksum);
244 }
245 }
246
247 for (int i = 0; i < kExpectedPageCount; ++i) {
248 float left;
249 float bottom;
250 float right;
251 float top;
252 ASSERT_TRUE(
253 FPDFPageObj_GetBounds(xobjects[i], &left, &bottom, &right, &top));
254 EXPECT_FLOAT_EQ(-1.0f, left);
255 EXPECT_FLOAT_EQ(-1.0f, bottom);
256 EXPECT_FLOAT_EQ(201.0f, right);
257 EXPECT_FLOAT_EQ(301.0f, top);
258 }
259
260 // Peek at object internals to make sure the two XObjects use the same stream.
261 EXPECT_NE(xobjects[0], xobjects[1]);
263 ASSERT_TRUE(obj1->AsForm());
264 ASSERT_TRUE(obj1->AsForm()->form());
265 ASSERT_TRUE(obj1->AsForm()->form()->GetStream());
267 ASSERT_TRUE(obj2->AsForm());
268 ASSERT_TRUE(obj2->AsForm()->form());
269 ASSERT_TRUE(obj2->AsForm()->form()->GetStream());
270 EXPECT_EQ(obj1->AsForm()->form()->GetStream(),
272
273 for (FPDF_PAGE saved_page : saved_pages)
274 CloseSavedPage(saved_page);
275
276 CloseSavedDocument();
277}
278
280 const char* checksum = []() {
281 if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
282 return "8e7d672f49f9ca98fb9157824cefc204";
283 }
284 return "4d5ca14827b7707f8283e639b33c121a";
285 }();
286
287 ASSERT_TRUE(OpenDocument("rectangles.pdf"));
288
289 FPDF_XOBJECT xobject = FPDF_NewXObjectFromPage(document(), document(), 0);
290 ASSERT_TRUE(xobject);
291
292 FPDF_PAGE page = LoadPage(0);
293 ASSERT_TRUE(page);
294
295 {
296 ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
297 CompareBitmap(bitmap.get(), 200, 300, pdfium::RectanglesChecksum());
298 }
299
300 FPDF_PAGEOBJECT page_object = FPDF_NewFormObjectFromXObject(xobject);
301 ASSERT_TRUE(page_object);
302 ASSERT_EQ(FPDF_PAGEOBJ_FORM, FPDFPageObj_GetType(page_object));
303
304 static constexpr FS_MATRIX kMatrix = {0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f};
305 EXPECT_TRUE(FPDFPageObj_SetMatrix(page_object, &kMatrix));
306
307 FPDFPage_InsertObject(page, page_object);
308 EXPECT_TRUE(FPDFPage_GenerateContent(page));
309
310 {
311 ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
312 CompareBitmap(bitmap.get(), 200, 300, checksum);
313 }
314
315 FPDF_CloseXObject(xobject);
316
317 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
318 VerifySavedDocument(200, 300, checksum);
319
320 UnloadPage(page);
321}
322
323TEST_F(FPDFPPOEmbedderTest, XObjectNullParams) {
324 ASSERT_TRUE(OpenDocument("rectangles.pdf"));
325 ASSERT_EQ(1, FPDF_GetPageCount(document()));
326
327 EXPECT_FALSE(FPDF_NewXObjectFromPage(nullptr, nullptr, -1));
328 EXPECT_FALSE(FPDF_NewXObjectFromPage(nullptr, nullptr, 0));
329 EXPECT_FALSE(FPDF_NewXObjectFromPage(nullptr, nullptr, 1));
330 EXPECT_FALSE(FPDF_NewXObjectFromPage(document(), nullptr, -1));
331 EXPECT_FALSE(FPDF_NewXObjectFromPage(document(), nullptr, 0));
332 EXPECT_FALSE(FPDF_NewXObjectFromPage(document(), nullptr, 1));
333 EXPECT_FALSE(FPDF_NewXObjectFromPage(nullptr, document(), -1));
334 EXPECT_FALSE(FPDF_NewXObjectFromPage(nullptr, document(), 0));
335 EXPECT_FALSE(FPDF_NewXObjectFromPage(nullptr, document(), 1));
336
337 {
338 ScopedFPDFDocument output_doc(FPDF_CreateNewDocument());
339 ASSERT_TRUE(output_doc);
340 EXPECT_FALSE(FPDF_NewXObjectFromPage(output_doc.get(), document(), -1));
341 EXPECT_FALSE(FPDF_NewXObjectFromPage(output_doc.get(), document(), 1));
342 }
343
344 // Should be a no-op.
345 FPDF_CloseXObject(nullptr);
346
347 EXPECT_FALSE(FPDF_NewFormObjectFromXObject(nullptr));
348}
349
350TEST_F(FPDFPPOEmbedderTest, BUG_925981) {
351 ASSERT_TRUE(OpenDocument("bug_925981.pdf"));
352 ScopedFPDFDocument output_doc_2up(
353 FPDF_ImportNPagesToOne(document(), 612, 792, 2, 1));
354 EXPECT_EQ(1, FPDF_GetPageCount(output_doc_2up.get()));
355}
356
357TEST_F(FPDFPPOEmbedderTest, BUG_1229106) {
358 static constexpr int kPageCount = 4;
359 static constexpr int kTwoUpPageCount = 2;
360 static const char kRectsChecksum[] = "140d629b3c96a07ced2e3e408ea85a1d";
361 static const char kTwoUpChecksum[] = "fa4501562301b2e75da354bd067495ec";
362
363 ASSERT_TRUE(OpenDocument("bug_1229106.pdf"));
364
365 // Show all pages render the same.
366 ASSERT_EQ(kPageCount, FPDF_GetPageCount(document()));
367 for (int i = 0; i < kPageCount; ++i) {
368 FPDF_PAGE page = LoadPage(0);
369 ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
370 CompareBitmap(bitmap.get(), 792, 612, kRectsChecksum);
371 UnloadPage(page);
372 }
373
374 // Create a 2-up PDF.
375 ScopedFPDFDocument output_doc_2up(
376 FPDF_ImportNPagesToOne(document(), 612, 792, 1, 2));
377 ASSERT_EQ(kTwoUpPageCount, FPDF_GetPageCount(output_doc_2up.get()));
378 for (int i = 0; i < kTwoUpPageCount; ++i) {
379 ScopedFPDFPage page(FPDF_LoadPage(output_doc_2up.get(), i));
380 ScopedFPDFBitmap bitmap = RenderPage(page.get());
381 CompareBitmap(bitmap.get(), 612, 792, kTwoUpChecksum);
382 }
383}
384
385TEST_F(FPDFPPOEmbedderTest, BadRepeatViewerPref) {
386 ASSERT_TRUE(OpenDocument("repeat_viewer_ref.pdf"));
387
388 ScopedFPDFDocument output_doc(FPDF_CreateNewDocument());
389 EXPECT_TRUE(output_doc);
390 EXPECT_TRUE(FPDF_CopyViewerPreferences(output_doc.get(), document()));
391
392 FPDF_FILEWRITE writer;
393 writer.version = 1;
394 writer.WriteBlock = FakeBlockWriter;
395
396 EXPECT_TRUE(FPDF_SaveAsCopy(output_doc.get(), &writer, 0));
397}
398
399TEST_F(FPDFPPOEmbedderTest, BadCircularViewerPref) {
400 ASSERT_TRUE(OpenDocument("circular_viewer_ref.pdf"));
401
402 ScopedFPDFDocument output_doc(FPDF_CreateNewDocument());
403 EXPECT_TRUE(output_doc);
404 EXPECT_TRUE(FPDF_CopyViewerPreferences(output_doc.get(), document()));
405
406 FPDF_FILEWRITE writer;
407 writer.version = 1;
408 writer.WriteBlock = FakeBlockWriter;
409
410 EXPECT_TRUE(FPDF_SaveAsCopy(output_doc.get(), &writer, 0));
411}
412
413TEST_F(FPDFPPOEmbedderTest, CopyViewerPrefTypes) {
414 ASSERT_TRUE(OpenDocument("viewer_pref_types.pdf"));
415
416 ScopedFPDFDocument output_doc(FPDF_CreateNewDocument());
417 ASSERT_TRUE(output_doc);
418 EXPECT_TRUE(FPDF_CopyViewerPreferences(output_doc.get(), document()));
419
420 // Peek under the hook to check the result.
421 const CPDF_Document* output_doc_impl =
422 CPDFDocumentFromFPDFDocument(output_doc.get());
423 RetainPtr<const CPDF_Dictionary> prefs =
424 output_doc_impl->GetRoot()->GetDictFor("ViewerPreferences");
425 ASSERT_TRUE(prefs);
426 EXPECT_EQ(6u, prefs->size());
427
428 RetainPtr<const CPDF_Object> bool_obj = prefs->GetObjectFor("Bool");
429 ASSERT_TRUE(bool_obj);
430 EXPECT_TRUE(bool_obj->IsBoolean());
431
432 RetainPtr<const CPDF_Number> num_obj = prefs->GetNumberFor("Num");
433 ASSERT_TRUE(num_obj);
434 EXPECT_TRUE(num_obj->IsInteger());
435 EXPECT_EQ(1, num_obj->GetInteger());
436
437 RetainPtr<const CPDF_String> str_obj = prefs->GetStringFor("Str");
438 ASSERT_TRUE(str_obj);
439 EXPECT_EQ("str", str_obj->GetString());
440
441 EXPECT_EQ("name", prefs->GetNameFor("Name"));
442
443 RetainPtr<const CPDF_Array> empty_array_obj =
444 prefs->GetArrayFor("EmptyArray");
445 ASSERT_TRUE(empty_array_obj);
446 EXPECT_TRUE(empty_array_obj->IsEmpty());
447
448 RetainPtr<const CPDF_Array> good_array_obj = prefs->GetArrayFor("GoodArray");
449 ASSERT_TRUE(good_array_obj);
450 EXPECT_EQ(4u, good_array_obj->size());
451}
452
453TEST_F(FPDFPPOEmbedderTest, BadIndices) {
454 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
455
456 FPDF_PAGE page = LoadPage(0);
457 EXPECT_TRUE(page);
458
459 ScopedFPDFDocument output_doc(FPDF_CreateNewDocument());
460 EXPECT_TRUE(output_doc);
461
462 static constexpr int kBadIndices1[] = {-1};
463 EXPECT_FALSE(FPDF_ImportPagesByIndex(
464 output_doc.get(), document(), kBadIndices1, std::size(kBadIndices1), 0));
465
466 static constexpr int kBadIndices2[] = {1};
467 EXPECT_FALSE(FPDF_ImportPagesByIndex(
468 output_doc.get(), document(), kBadIndices2, std::size(kBadIndices2), 0));
469
470 static constexpr int kBadIndices3[] = {-1, 0, 1};
471 EXPECT_FALSE(FPDF_ImportPagesByIndex(
472 output_doc.get(), document(), kBadIndices3, std::size(kBadIndices3), 0));
473
474 static constexpr int kBadIndices4[] = {42};
475 EXPECT_FALSE(FPDF_ImportPagesByIndex(
476 output_doc.get(), document(), kBadIndices4, std::size(kBadIndices4), 0));
477
478 UnloadPage(page);
479}
480
481TEST_F(FPDFPPOEmbedderTest, GoodIndices) {
482 ASSERT_TRUE(OpenDocument("viewer_ref.pdf"));
483
484 FPDF_PAGE page = LoadPage(0);
485 EXPECT_TRUE(page);
486
487 ScopedFPDFDocument output_doc(FPDF_CreateNewDocument());
488 EXPECT_TRUE(output_doc);
489
490 static constexpr int kGoodIndices1[] = {0, 0, 0, 0};
491 EXPECT_TRUE(FPDF_ImportPagesByIndex(output_doc.get(), document(),
492 kGoodIndices1, std::size(kGoodIndices1),
493 0));
494 EXPECT_EQ(4, FPDF_GetPageCount(output_doc.get()));
495
496 static constexpr int kGoodIndices2[] = {0};
497 EXPECT_TRUE(FPDF_ImportPagesByIndex(output_doc.get(), document(),
498 kGoodIndices2, std::size(kGoodIndices2),
499 0));
500 EXPECT_EQ(5, FPDF_GetPageCount(output_doc.get()));
501
502 static constexpr int kGoodIndices3[] = {4};
503 EXPECT_TRUE(FPDF_ImportPagesByIndex(output_doc.get(), document(),
504 kGoodIndices3, std::size(kGoodIndices3),
505 0));
506 EXPECT_EQ(6, FPDF_GetPageCount(output_doc.get()));
507
508 static constexpr int kGoodIndices4[] = {1, 2, 3};
509 EXPECT_TRUE(FPDF_ImportPagesByIndex(output_doc.get(), document(),
510 kGoodIndices4, std::size(kGoodIndices4),
511 0));
512 EXPECT_EQ(9, FPDF_GetPageCount(output_doc.get()));
513
514 // Passing in a nullptr should import all the pages.
515 EXPECT_TRUE(
516 FPDF_ImportPagesByIndex(output_doc.get(), document(), nullptr, 0, 0));
517 EXPECT_EQ(14, FPDF_GetPageCount(output_doc.get()));
518
519 UnloadPage(page);
520}
521
522TEST_F(FPDFPPOEmbedderTest, BadRanges) {
523 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
524
525 FPDF_PAGE page = LoadPage(0);
526 EXPECT_TRUE(page);
527
528 ScopedFPDFDocument output_doc(FPDF_CreateNewDocument());
529 EXPECT_TRUE(output_doc);
530 EXPECT_FALSE(FPDF_ImportPages(output_doc.get(), document(), "clams", 0));
531 EXPECT_FALSE(FPDF_ImportPages(output_doc.get(), document(), "0", 0));
532 EXPECT_FALSE(FPDF_ImportPages(output_doc.get(), document(), "42", 0));
533 EXPECT_FALSE(FPDF_ImportPages(output_doc.get(), document(), "1,2", 0));
534 EXPECT_FALSE(FPDF_ImportPages(output_doc.get(), document(), "1-2", 0));
535 EXPECT_FALSE(FPDF_ImportPages(output_doc.get(), document(), ",1", 0));
536 EXPECT_FALSE(FPDF_ImportPages(output_doc.get(), document(), "1,", 0));
537 EXPECT_FALSE(FPDF_ImportPages(output_doc.get(), document(), "1-", 0));
538 EXPECT_FALSE(FPDF_ImportPages(output_doc.get(), document(), "-1", 0));
539 EXPECT_FALSE(FPDF_ImportPages(output_doc.get(), document(), "-,0,,,1-", 0));
540
541 UnloadPage(page);
542}
543
544TEST_F(FPDFPPOEmbedderTest, GoodRanges) {
545 ASSERT_TRUE(OpenDocument("viewer_ref.pdf"));
546
547 FPDF_PAGE page = LoadPage(0);
548 EXPECT_TRUE(page);
549
550 ScopedFPDFDocument output_doc(FPDF_CreateNewDocument());
551 EXPECT_TRUE(output_doc);
552 EXPECT_TRUE(FPDF_CopyViewerPreferences(output_doc.get(), document()));
553 EXPECT_TRUE(FPDF_ImportPages(output_doc.get(), document(), "1,1,1,1", 0));
554 EXPECT_EQ(4, FPDF_GetPageCount(output_doc.get()));
555 EXPECT_TRUE(FPDF_ImportPages(output_doc.get(), document(), "1-1", 0));
556 EXPECT_EQ(5, FPDF_GetPageCount(output_doc.get()));
557 EXPECT_TRUE(FPDF_ImportPages(output_doc.get(), document(), "5-5", 0));
558 EXPECT_EQ(6, FPDF_GetPageCount(output_doc.get()));
559 EXPECT_TRUE(FPDF_ImportPages(output_doc.get(), document(), "2-4", 0));
560 EXPECT_EQ(9, FPDF_GetPageCount(output_doc.get()));
561
562 UnloadPage(page);
563}
564
565TEST_F(FPDFPPOEmbedderTest, BUG_664284) {
566 ASSERT_TRUE(OpenDocument("bug_664284.pdf"));
567
568 FPDF_PAGE page = LoadPage(0);
569 ASSERT_NE(nullptr, page);
570
571 ScopedFPDFDocument output_doc(FPDF_CreateNewDocument());
572 EXPECT_TRUE(output_doc);
573
574 static constexpr int kIndices[] = {0};
575 EXPECT_TRUE(FPDF_ImportPagesByIndex(output_doc.get(), document(), kIndices,
576 std::size(kIndices), 0));
577
578 UnloadPage(page);
579}
580
581TEST_F(FPDFPPOEmbedderTest, BUG_750568) {
582 ASSERT_TRUE(OpenDocument("bug_750568.pdf"));
583 ASSERT_EQ(4, FPDF_GetPageCount(document()));
584
585 for (size_t i = 0; i < 4; ++i) {
586 FPDF_PAGE page = LoadPage(i);
587 ASSERT_TRUE(page);
588
589 ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
590 CompareBitmap(bitmap.get(), 200, 200, Bug750568PageHash(i));
591 UnloadPage(page);
592 }
593
594 ScopedFPDFDocument output_doc(FPDF_CreateNewDocument());
595 ASSERT_TRUE(output_doc);
596
597 static constexpr int kIndices[] = {0, 1, 2, 3};
598 EXPECT_TRUE(FPDF_ImportPagesByIndex(output_doc.get(), document(), kIndices,
599 std::size(kIndices), 0));
600 ASSERT_EQ(4, FPDF_GetPageCount(output_doc.get()));
601 for (size_t i = 0; i < 4; ++i) {
602 ScopedFPDFPage page(FPDF_LoadPage(output_doc.get(), i));
603 ASSERT_TRUE(page);
604
605 ScopedFPDFBitmap bitmap = RenderPage(page.get());
606 CompareBitmap(bitmap.get(), 200, 200, Bug750568PageHash(i));
607 }
608}
609
610TEST_F(FPDFPPOEmbedderTest, ImportWithZeroLengthStream) {
611 ASSERT_TRUE(OpenDocument("zero_length_stream.pdf"));
612 FPDF_PAGE page = LoadPage(0);
613 ASSERT_TRUE(page);
614
615 ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
616 CompareBitmap(bitmap.get(), 200, 200, pdfium::HelloWorldChecksum());
617 UnloadPage(page);
618
619 ScopedFPDFDocument new_doc(FPDF_CreateNewDocument());
620 ASSERT_TRUE(new_doc);
621
622 static constexpr int kIndices[] = {0};
623 EXPECT_TRUE(FPDF_ImportPagesByIndex(new_doc.get(), document(), kIndices,
624 std::size(kIndices), 0));
625
626 EXPECT_EQ(1, FPDF_GetPageCount(new_doc.get()));
627 ScopedFPDFPage new_page(FPDF_LoadPage(new_doc.get(), 0));
628 ASSERT_TRUE(new_page);
629 ScopedFPDFBitmap new_bitmap = RenderPage(new_page.get());
630 CompareBitmap(new_bitmap.get(), 200, 200, pdfium::HelloWorldChecksum());
631}
632
634 ASSERT_TRUE(OpenDocument("hello_world.pdf"));
635 EXPECT_EQ(1, FPDF_GetPageCount(document()));
636
637 std::string file_path = PathService::GetTestFilePath("rectangles.pdf");
638 ASSERT_FALSE(file_path.empty());
639 std::vector<uint8_t> file_contents = GetFileContents(file_path.c_str());
640 ASSERT_FALSE(file_contents.empty());
641
642 ScopedFPDFDocument src_doc(FPDF_LoadMemDocument(
643 file_contents.data(), file_contents.size(), nullptr));
644 ASSERT_TRUE(src_doc);
645
646 static constexpr int kIndices[] = {0};
647 EXPECT_TRUE(FPDF_ImportPagesByIndex(document(), src_doc.get(), kIndices,
648 std::size(kIndices), 0));
649 EXPECT_EQ(2, FPDF_GetPageCount(document()));
650
651 EXPECT_TRUE(FPDF_ImportPages(document(), src_doc.get(), "1", 0));
652 EXPECT_EQ(3, FPDF_GetPageCount(document()));
653}
654
656 ASSERT_TRUE(OpenDocument("bad_page_type.pdf"));
657 EXPECT_EQ(2, FPDF_GetPageCount(document()));
658
659 std::string file_path = PathService::GetTestFilePath("rectangles.pdf");
660 ASSERT_FALSE(file_path.empty());
661 std::vector<uint8_t> file_contents = GetFileContents(file_path.c_str());
662 ASSERT_FALSE(file_contents.empty());
663
664 ScopedFPDFDocument src_doc(FPDF_LoadMemDocument(
665 file_contents.data(), file_contents.size(), nullptr));
666 ASSERT_TRUE(src_doc);
667 EXPECT_EQ(1, FPDF_GetPageCount(src_doc.get()));
668
669 FPDFPage_Delete(document(), 0);
670 EXPECT_EQ(1, FPDF_GetPageCount(document()));
671
672 static constexpr int kPageIndices[] = {0};
673 ASSERT_TRUE(FPDF_ImportPagesByIndex(document(), src_doc.get(), kPageIndices,
674 std::size(kPageIndices), 0));
675 EXPECT_EQ(2, FPDF_GetPageCount(document()));
676 const char* const new_page_1_checksum = []() {
677 if (CFX_DefaultRenderDevice::UseSkiaRenderer()) {
678 return "b4e411a6b5ffa59a50efede2efece597";
679 }
680 return "0a90de37f52127619c3dfb642b5fa2fe";
681 }();
682 const char new_page_2_checksum[] = "39336760026e7f3d26135e3b765125c3";
683 {
684 FPDF_PAGE page = LoadPage(0);
685 ASSERT_TRUE(page);
686 ScopedFPDFBitmap bitmap = RenderPage(page);
687 CompareBitmap(bitmap.get(), 200, 300, new_page_1_checksum);
688 UnloadPage(page);
689 }
690 {
691 FPDF_PAGE page = LoadPage(1);
692 ASSERT_TRUE(page);
693 ScopedFPDFBitmap bitmap = RenderPage(page);
694 CompareBitmap(bitmap.get(), 200, 100, new_page_2_checksum);
695 UnloadPage(page);
696 }
697
698 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
699
700 ASSERT_TRUE(OpenSavedDocument());
701 EXPECT_EQ(2, FPDF_GetPageCount(saved_document()));
702 {
703 FPDF_PAGE page = LoadSavedPage(0);
704 ASSERT_TRUE(page);
705 ScopedFPDFBitmap bitmap = RenderPage(page);
706 CompareBitmap(bitmap.get(), 200, 300, new_page_1_checksum);
707 CloseSavedPage(page);
708 }
709 {
710 FPDF_PAGE page = LoadSavedPage(1);
711 ASSERT_TRUE(page);
712 ScopedFPDFBitmap bitmap = RenderPage(page);
713 CompareBitmap(bitmap.get(), 200, 100, new_page_2_checksum);
714 CloseSavedPage(page);
715 }
716}
const CPDF_Form * form() const
RetainPtr< const CPDF_Stream > GetStream() const
virtual CPDF_FormObject * AsForm()
CPDF_PageObject * CPDFPageObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object)
FPDF_EXPORT int FPDF_CALLCONV FPDFFormObj_CountObjects(FPDF_PAGEOBJECT form_object)
FPDF_EXPORT void FPDF_CALLCONV FPDFPage_InsertObject(FPDF_PAGE page, FPDF_PAGEOBJECT page_object)
FPDF_EXPORT FPDF_PAGEOBJECT FPDF_CALLCONV FPDFPage_GetObject(FPDF_PAGE page, int index)
FPDF_EXPORT int FPDF_CALLCONV FPDFPageObj_GetType(FPDF_PAGEOBJECT page_object)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPageObj_GetBounds(FPDF_PAGEOBJECT page_object, float *left, float *bottom, float *right, float *top)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPageObj_SetMatrix(FPDF_PAGEOBJECT page_object, const FS_MATRIX *matrix)
#define FPDF_PAGEOBJ_FORM
Definition fpdf_edit.h:43
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPage_GenerateContent(FPDF_PAGE page)
FPDF_EXPORT int FPDF_CALLCONV FPDFPage_CountObjects(FPDF_PAGE page)
FPDF_EXPORT void FPDF_CALLCONV FPDF_CloseXObject(FPDF_XOBJECT xobject)
Definition fpdf_ppo.cpp:831
FPDF_EXPORT FPDF_PAGEOBJECT FPDF_CALLCONV FPDF_NewFormObjectFromXObject(FPDF_XOBJECT xobject)
Definition fpdf_ppo.cpp:837
FPDF_EXPORT FPDF_XOBJECT FPDF_CALLCONV FPDF_NewXObjectFromPage(FPDF_DOCUMENT dest_doc, FPDF_DOCUMENT src_doc, int src_page_index)
Definition fpdf_ppo.cpp:814
TEST_F(FPDFPPOEmbedderTest, NoViewerPreferences)
const char * RectanglesChecksum()
const char * HelloWorldChecksum()
int(* WriteBlock)(struct FPDF_FILEWRITE_ *pThis, const void *pData, unsigned long size)
Definition fpdf_save.h:39