[M120 Migration][VD] Remove accessing oom_score_adj in zygote process
[platform/framework/web/chromium-efl.git] / printing / pdf_metafile_cg_mac_unittest.cc
1 // Copyright 2011 The Chromium 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 "printing/pdf_metafile_cg_mac.h"
6
7 #include <CoreGraphics/CoreGraphics.h>
8 #include <stdint.h>
9
10 #include <memory>
11 #include <string>
12 #include <vector>
13
14 #include "base/files/file_util.h"
15 #include "base/hash/sha1.h"
16 #include "base/path_service.h"
17 #include "printing/mojom/print.mojom.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "ui/gfx/codec/png_codec.h"
20 #include "ui/gfx/geometry/rect.h"
21
22 namespace printing {
23
24 namespace {
25
26 base::FilePath GetPdfTestData(const base::FilePath::StringType& filename) {
27   base::FilePath root_path;
28   if (!base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &root_path)) {
29     return base::FilePath();
30   }
31   return root_path.Append("pdf").Append("test").Append("data").Append(filename);
32 }
33
34 base::FilePath GetPrintingTestData(const base::FilePath::StringType& filename) {
35   base::FilePath root_path;
36   if (!base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &root_path)) {
37     return base::FilePath();
38   }
39   return root_path.Append("printing")
40       .Append("test")
41       .Append("data")
42       .Append("pdf_cg")
43       .Append(filename);
44 }
45
46 std::unique_ptr<PdfMetafileCg> GetPdfMetafile(
47     const base::FilePath::StringType& pdf_filename) {
48   // Get test data.
49   base::FilePath pdf_file = GetPdfTestData(pdf_filename);
50   if (pdf_file.empty())
51     return nullptr;
52
53   std::string pdf_data;
54   if (!base::ReadFileToString(pdf_file, &pdf_data))
55     return nullptr;
56
57   // Initialize and check metafile.
58   auto pdf_cg = std::make_unique<PdfMetafileCg>();
59   if (!pdf_cg->InitFromData(base::as_bytes(base::make_span(pdf_data))))
60     return nullptr;
61   return pdf_cg;
62 }
63
64 void RenderedPdfSha1(const base::FilePath::StringType& pdf_filename,
65                      size_t page_number,
66                      const gfx::Rect& expected_page_bounds,
67                      const gfx::Size& dest_size,
68                      bool autorotate,
69                      bool fit_to_page,
70                      base::SHA1Digest* rendered_hash) {
71   // Initialize and verify the metafile.
72   std::unique_ptr<PdfMetafileCg> pdf_cg = GetPdfMetafile(pdf_filename);
73   ASSERT_TRUE(pdf_cg);
74   ASSERT_LE(page_number, pdf_cg->GetPageCount());
75   const gfx::Rect bounds = pdf_cg->GetPageBounds(page_number);
76   ASSERT_EQ(expected_page_bounds, bounds);
77
78   // Set up rendering context.
79   constexpr size_t kBitsPerComponent = 8;
80   constexpr size_t kBytesPerPixel = 4;
81   const size_t kStride = dest_size.width() * kBytesPerPixel;
82   std::vector<uint8_t> rendered_bitmap(dest_size.height() * kStride);
83   base::apple::ScopedCFTypeRef<CGColorSpaceRef> color_space(
84       CGColorSpaceCreateDeviceRGB());
85   base::apple::ScopedCFTypeRef<CGContextRef> context(CGBitmapContextCreate(
86       rendered_bitmap.data(), dest_size.width(), dest_size.height(),
87       kBitsPerComponent, kStride, color_space.get(),
88       uint32_t{kCGImageAlphaPremultipliedFirst} | kCGBitmapByteOrder32Little));
89
90   // Render using metafile and calculate the output hash.
91   ASSERT_TRUE(pdf_cg->RenderPage(page_number, context.get(),
92                                  gfx::Rect(dest_size).ToCGRect(), autorotate,
93                                  fit_to_page));
94   *rendered_hash = base::SHA1HashSpan(rendered_bitmap);
95 }
96
97 void ExpectedPngSha1(const base::FilePath::StringType& expected_png_filename,
98                      const gfx::Size& expected_png_size,
99                      base::SHA1Digest* expected_hash) {
100   base::FilePath expected_png_file = GetPrintingTestData(expected_png_filename);
101   ASSERT_FALSE(expected_png_file.empty());
102   std::string expected_png_data;
103   ASSERT_TRUE(base::ReadFileToString(expected_png_file, &expected_png_data));
104
105   // Decode expected PNG and calculate the output hash.
106   std::vector<uint8_t> expected_png_bitmap;
107   int png_width;
108   int png_height;
109   ASSERT_TRUE(gfx::PNGCodec::Decode(
110       reinterpret_cast<const uint8_t*>(expected_png_data.data()),
111       expected_png_data.size(), gfx::PNGCodec::FORMAT_BGRA,
112       &expected_png_bitmap, &png_width, &png_height));
113   ASSERT_EQ(expected_png_size.width(), png_width);
114   ASSERT_EQ(expected_png_size.height(), png_height);
115   *expected_hash = base::SHA1HashSpan(expected_png_bitmap);
116 }
117
118 void TestRenderPageWithTransformParams(
119     const base::FilePath::StringType& pdf_filename,
120     size_t page_number,
121     const gfx::Rect& expected_page_bounds,
122     const base::FilePath::StringType& expected_png_filename,
123     const gfx::Size& dest_size,
124     bool autorotate,
125     bool fit_to_page) {
126   base::SHA1Digest rendered_hash;
127   RenderedPdfSha1(pdf_filename, page_number, expected_page_bounds, dest_size,
128                   autorotate, fit_to_page, &rendered_hash);
129   base::SHA1Digest expected_hash;
130   ExpectedPngSha1(expected_png_filename, dest_size, &expected_hash);
131
132   // Make sure the hashes match.
133   EXPECT_EQ(expected_hash, rendered_hash);
134 }
135
136 void TestRenderPage(const base::FilePath::StringType& pdf_filename,
137                     size_t page_number,
138                     const gfx::Rect& expected_page_bounds,
139                     const base::FilePath::StringType& expected_png_filename,
140                     const gfx::Size& dest_size) {
141   TestRenderPageWithTransformParams(
142       pdf_filename, page_number, expected_page_bounds, expected_png_filename,
143       dest_size, /*autorotate=*/true, /*fit_to_page=*/false);
144 }
145
146 }  // namespace
147
148 TEST(PdfMetafileCgTest, Pdf) {
149   // Test in-renderer constructor.
150   PdfMetafileCg pdf;
151   EXPECT_TRUE(pdf.Init());
152   EXPECT_TRUE(pdf.context());
153
154   // Render page 1.
155   constexpr gfx::Rect kRect1(10, 10, 520, 700);
156   constexpr gfx::Size kSize1(540, 720);
157   pdf.StartPage(kSize1, kRect1, 1.25, mojom::PageOrientation::kUpright);
158   pdf.FinishPage();
159
160   // Render page 2.
161   constexpr gfx::Rect kRect2(10, 10, 520, 700);
162   constexpr gfx::Size kSize2(720, 540);
163   pdf.StartPage(kSize2, kRect2, 2.0, mojom::PageOrientation::kUpright);
164   pdf.FinishPage();
165
166   pdf.FinishDocument();
167
168   // Check data size.
169   const uint32_t size = pdf.GetDataSize();
170   EXPECT_GT(size, 0U);
171
172   // Get resulting data.
173   std::vector<char> buffer(size, 0);
174   pdf.GetData(&buffer.front(), size);
175
176   // Test browser-side constructor.
177   PdfMetafileCg pdf2;
178   // TODO(thestig): Make `buffer` uint8_t and avoid the base::as_bytes() call.
179   EXPECT_TRUE(pdf2.InitFromData(base::as_bytes(base::make_span(buffer))));
180
181   // Get the first 4 characters from pdf2.
182   std::vector<char> buffer2(4, 0);
183   pdf2.GetData(&buffer2.front(), 4);
184
185   // Test that the header begins with "%PDF".
186   std::string header(&buffer2.front(), 4);
187   EXPECT_EQ(0U, header.find("%PDF", 0));
188
189   // Test that the PDF is correctly reconstructed.
190   EXPECT_EQ(2U, pdf2.GetPageCount());
191   gfx::Size page_size = pdf2.GetPageBounds(1).size();
192   EXPECT_EQ(540, page_size.width());
193   EXPECT_EQ(720, page_size.height());
194   page_size = pdf2.GetPageBounds(2).size();
195   EXPECT_EQ(720, page_size.width());
196   EXPECT_EQ(540, page_size.height());
197 }
198
199 TEST(PdfMetafileCgTest, GetPageBounds) {
200   // Get test data.
201   base::FilePath pdf_file = GetPdfTestData("rectangles_multi_pages.pdf");
202   ASSERT_FALSE(pdf_file.empty());
203   std::string pdf_data;
204   ASSERT_TRUE(base::ReadFileToString(pdf_file, &pdf_data));
205
206   // Initialize and check metafile.
207   PdfMetafileCg pdf_cg;
208   ASSERT_TRUE(pdf_cg.InitFromData(base::as_bytes(base::make_span(pdf_data))));
209   ASSERT_EQ(5u, pdf_cg.GetPageCount());
210
211   // Since the input into GetPageBounds() is a 1-indexed page number, 0 and 6
212   // are out of bounds.
213   gfx::Rect bounds;
214   for (size_t i : {0, 6}) {
215     bounds = pdf_cg.GetPageBounds(i);
216     EXPECT_EQ(0, bounds.x());
217     EXPECT_EQ(0, bounds.y());
218     EXPECT_EQ(0, bounds.width());
219     EXPECT_EQ(0, bounds.height());
220   }
221
222   // Whereas 1-5 are in bounds.
223   for (size_t i = 1; i < 6; ++i) {
224     bounds = pdf_cg.GetPageBounds(i);
225     EXPECT_EQ(0, bounds.x());
226     EXPECT_EQ(0, bounds.y());
227     EXPECT_EQ(200, bounds.width());
228     EXPECT_EQ(250, bounds.height());
229   }
230 }
231
232 TEST(PdfMetafileCgTest, RenderPortraitRectangles) {
233   constexpr gfx::Rect kPageBounds(200, 300);
234   constexpr gfx::Size kDestinationSize(200, 300);
235   TestRenderPage("rectangles.pdf", /*page_number=*/1, kPageBounds,
236                  "render_portrait_rectangles_expected.0.png", kDestinationSize);
237 }
238
239 TEST(PdfMetafileCgTest, RenderAutorotatedPortraitRectangles) {
240   constexpr gfx::Rect kPageBounds(200, 300);
241   constexpr gfx::Size kDestinationSize(300, 200);
242   TestRenderPage("rectangles.pdf", /*page_number=*/1, kPageBounds,
243                  "render_autorotated_portrait_rectangles_expected.0.png",
244                  kDestinationSize);
245 }
246
247 TEST(PdfMetafileCgTest, RenderLargePortraitRectangles) {
248   constexpr gfx::Rect kPageBounds(200, 300);
249   constexpr gfx::Size kDestinationSize(100, 120);
250   TestRenderPage("rectangles.pdf", /*page_number=*/1, kPageBounds,
251                  "render_large_portrait_rectangles_expected.0.png",
252                  kDestinationSize);
253 }
254
255 TEST(PdfMetafileCgTest, RenderSmallPortraitRectangles) {
256   constexpr gfx::Rect kPageBounds(200, 300);
257   constexpr gfx::Size kDestinationSize(300, 450);
258   TestRenderPage("rectangles.pdf", /*page_number=*/1, kPageBounds,
259                  "render_small_portrait_rectangles_expected.0.png",
260                  kDestinationSize);
261 }
262
263 TEST(PdfMetafileCgTest, RenderLandscapeRectangles) {
264   constexpr gfx::Rect kPageBounds(800, 500);
265   constexpr gfx::Size kDestinationSize(400, 600);
266   TestRenderPage("landscape_rectangles.pdf", /*page_number=*/1, kPageBounds,
267                  "render_landscape_rectangles_expected.0.png",
268                  kDestinationSize);
269 }
270
271 TEST(PdfMetafileCgTest, RenderRotatedRectangles) {
272   constexpr gfx::Rect kPageBounds(800, 500);
273   constexpr gfx::Size kLandscapeDestinationSize(600, 400);
274   constexpr gfx::Size kPortraitDestinationSize(400, 600);
275
276   TestRenderPage("rotated_rectangles.pdf", /*page_number=*/1, kPageBounds,
277                  "render_rotated_rectangles_expected.0.png",
278                  kLandscapeDestinationSize);
279   TestRenderPage("rotated_rectangles.pdf", /*page_number=*/2, kPageBounds,
280                  "render_rotated_rectangles_expected.1.png",
281                  kPortraitDestinationSize);
282   TestRenderPage("rotated_rectangles.pdf", /*page_number=*/3, kPageBounds,
283                  "render_rotated_rectangles_expected.2.png",
284                  kLandscapeDestinationSize);
285   TestRenderPage("rotated_rectangles.pdf", /*page_number=*/4, kPageBounds,
286                  "render_rotated_rectangles_expected.3.png",
287                  kPortraitDestinationSize);
288
289   TestRenderPage("rotated_rectangles.pdf", /*page_number=*/1, kPageBounds,
290                  "render_autorotated_rotated_rectangles_expected.0.png",
291                  kPortraitDestinationSize);
292   TestRenderPage("rotated_rectangles.pdf", /*page_number=*/2, kPageBounds,
293                  "render_autorotated_rotated_rectangles_expected.1.png",
294                  kLandscapeDestinationSize);
295   TestRenderPage("rotated_rectangles.pdf", /*page_number=*/3, kPageBounds,
296                  "render_autorotated_rotated_rectangles_expected.2.png",
297                  kPortraitDestinationSize);
298   TestRenderPage("rotated_rectangles.pdf", /*page_number=*/4, kPageBounds,
299                  "render_autorotated_rotated_rectangles_expected.3.png",
300                  kLandscapeDestinationSize);
301 }
302
303 TEST(PdfMetafileCgTest, RenderLargeLandscapeRectangles) {
304   constexpr gfx::Rect kPageBounds(800, 500);
305   constexpr gfx::Size kDestinationSize(200, 300);
306   TestRenderPage("landscape_rectangles.pdf", /*page_number=*/1, kPageBounds,
307                  "render_large_landscape_rectangles_expected.0.png",
308                  kDestinationSize);
309 }
310
311 TEST(PdfMetafileCgTest, RenderSmallLandscapeRectangles) {
312   constexpr gfx::Rect kPageBounds(800, 500);
313   constexpr gfx::Size kDestinationSize(600, 900);
314   TestRenderPage("landscape_rectangles.pdf", /*page_number=*/1, kPageBounds,
315                  "render_small_landscape_rectangles_expected.0.png",
316                  kDestinationSize);
317 }
318
319 TEST(PdfMetafileCgTest, RenderScaledLargeLandscapeRectangles) {
320   constexpr gfx::Rect kPageBounds(800, 500);
321   constexpr gfx::Size kDestinationSize(300, 450);
322   TestRenderPageWithTransformParams(
323       "landscape_rectangles.pdf", /*page_number=*/1, kPageBounds,
324       "render_scaled_large_landscape_rectangles_expected.0.png",
325       kDestinationSize,
326       /*autorotate=*/true, /*fit_to_page=*/true);
327 }
328
329 TEST(PdfMetafileCgTest, RenderScaledSmallLandscapeRectangles) {
330   constexpr gfx::Rect kPageBounds(800, 500);
331   constexpr gfx::Size kDestinationSize(600, 900);
332   TestRenderPageWithTransformParams(
333       "landscape_rectangles.pdf", /*page_number=*/1, kPageBounds,
334       "render_scaled_small_landscape_rectangles_expected.0.png",
335       kDestinationSize,
336       /*autorotate=*/true, /*fit_to_page=*/true);
337 }
338
339 }  // namespace printing