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