Upload upstream chromium 73.0.3683.0
[platform/framework/web/chromium-efl.git] / printing / emf_win_unittest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
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/emf_win.h"
6
7 // For quick access.
8 #include <stdint.h>
9 #include <wingdi.h>
10 #include <winspool.h>
11
12 #include <memory>
13 #include <string>
14
15 #include "base/files/file_path.h"
16 #include "base/files/file_util.h"
17 #include "base/files/scoped_temp_dir.h"
18 #include "base/path_service.h"
19 #include "base/win/scoped_hdc.h"
20 #include "printing/printing_context.h"
21 #include "printing/printing_context_win.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "ui/gfx/geometry/point.h"
24 #include "ui/gfx/geometry/size.h"
25
26 namespace printing {
27
28 namespace {
29
30 // This test is automatically disabled if no printer named "UnitTest Printer" is
31 // available.
32 class EmfPrintingTest : public testing::Test, public PrintingContext::Delegate {
33  public:
34   typedef testing::Test Parent;
35   static bool IsTestCaseDisabled() {
36     // It is assumed this printer is a HP Color LaserJet 4550 PCL or 4700.
37     HDC hdc = CreateDC(L"WINSPOOL", L"UnitTest Printer", nullptr, nullptr);
38     if (!hdc)
39       return true;
40     DeleteDC(hdc);
41     return false;
42   }
43
44   // PrintingContext::Delegate methods.
45   gfx::NativeView GetParentView() override { return nullptr; }
46   std::string GetAppLocale() override { return std::string(); }
47 };
48
49 const uint32_t EMF_HEADER_SIZE = 128;
50
51 }  // namespace
52
53 TEST(EmfTest, DC) {
54   // Simplest use case.
55   uint32_t size;
56   std::vector<char> data;
57   {
58     Emf emf;
59     EXPECT_TRUE(emf.Init());
60     EXPECT_TRUE(emf.context());
61     // An empty EMF is invalid, so we put at least a rectangle in it.
62     ::Rectangle(emf.context(), 10, 10, 190, 190);
63     EXPECT_TRUE(emf.FinishDocument());
64     size = emf.GetDataSize();
65     EXPECT_GT(size, EMF_HEADER_SIZE);
66     EXPECT_TRUE(emf.GetDataAsVector(&data));
67     EXPECT_EQ(data.size(), size);
68   }
69
70   // Playback the data.
71   Emf emf;
72   EXPECT_TRUE(emf.InitFromData(&data.front(), size));
73   HDC hdc = CreateCompatibleDC(nullptr);
74   EXPECT_TRUE(hdc);
75   RECT output_rect = {0, 0, 10, 10};
76   EXPECT_TRUE(emf.Playback(hdc, &output_rect));
77   EXPECT_TRUE(DeleteDC(hdc));
78 }
79
80 // Disabled if no "UnitTest printer" exist. Useful to reproduce bug 1186598.
81 TEST_F(EmfPrintingTest, Enumerate) {
82   if (IsTestCaseDisabled())
83     return;
84
85   PrintSettings settings;
86
87   // My test case is a HP Color LaserJet 4550 PCL.
88   settings.set_device_name(L"UnitTest Printer");
89
90   // Initialize it.
91   PrintingContextWin context(this);
92   EXPECT_EQ(PrintingContext::OK, context.InitWithSettingsForTest(settings));
93
94   base::FilePath emf_file;
95   EXPECT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &emf_file));
96   emf_file = emf_file.Append(FILE_PATH_LITERAL("printing"))
97                      .Append(FILE_PATH_LITERAL("test"))
98                      .Append(FILE_PATH_LITERAL("data"))
99                      .Append(FILE_PATH_LITERAL("test4.emf"));
100
101   // Load any EMF with an image.
102   std::string emf_data;
103   base::ReadFileToString(emf_file, &emf_data);
104   ASSERT_TRUE(emf_data.size());
105
106   Emf emf;
107   EXPECT_TRUE(emf.InitFromData(&emf_data[0], emf_data.size()));
108
109   // This will print to file. The reason is that when running inside a
110   // unit_test, PrintingContext automatically dumps its files to the
111   // current directory.
112   // TODO(maruel):  Clean the .PRN file generated in current directory.
113   context.NewDocument(L"EmfTest.Enumerate");
114   context.NewPage();
115   // Process one at a time.
116   RECT page_bounds = emf.GetPageBounds(1).ToRECT();
117   Emf::Enumerator emf_enum(emf, context.context(), &page_bounds);
118   for (Emf::Enumerator::const_iterator itr = emf_enum.begin();
119        itr != emf_enum.end();
120        ++itr) {
121     // To help debugging.
122     ptrdiff_t index = itr - emf_enum.begin();
123     // If you get this assert, you need to lookup iType in wingdi.h. It starts
124     // with EMR_HEADER.
125     EMR_HEADER;
126     EXPECT_TRUE(itr->SafePlayback(&emf_enum.context_)) <<
127         " index: " << index << " type: " << itr->record()->iType;
128   }
129   context.PageDone();
130   context.DocumentDone();
131 }
132
133 // Disabled if no "UnitTest printer" exists.
134 TEST_F(EmfPrintingTest, PageBreak) {
135   base::win::ScopedCreateDC dc(
136       CreateDC(L"WINSPOOL", L"UnitTest Printer", nullptr, nullptr));
137   if (!dc.Get())
138     return;
139   uint32_t size;
140   std::vector<char> data;
141   {
142     Emf emf;
143     EXPECT_TRUE(emf.Init());
144     EXPECT_TRUE(emf.context());
145     int pages = 3;
146     while (pages) {
147       emf.StartPage(gfx::Size(), gfx::Rect(), 1);
148       ::Rectangle(emf.context(), 10, 10, 190, 190);
149       EXPECT_TRUE(emf.FinishPage());
150       --pages;
151     }
152     EXPECT_EQ(3U, emf.GetPageCount());
153     EXPECT_TRUE(emf.FinishDocument());
154     size = emf.GetDataSize();
155     EXPECT_TRUE(emf.GetDataAsVector(&data));
156     EXPECT_EQ(data.size(), size);
157   }
158
159   // Playback the data.
160   DOCINFO di = {0};
161   di.cbSize = sizeof(DOCINFO);
162   di.lpszDocName = L"Test Job";
163   int job_id = ::StartDoc(dc.Get(), &di);
164   Emf emf;
165   EXPECT_TRUE(emf.InitFromData(&data.front(), size));
166   EXPECT_TRUE(emf.SafePlayback(dc.Get()));
167   ::EndDoc(dc.Get());
168   // Since presumably the printer is not real, let us just delete the job from
169   // the queue.
170   HANDLE printer = nullptr;
171   if (::OpenPrinter(const_cast<LPTSTR>(L"UnitTest Printer"), &printer,
172                     nullptr)) {
173     ::SetJob(printer, job_id, 0, nullptr, JOB_CONTROL_DELETE);
174     ClosePrinter(printer);
175   }
176 }
177
178 TEST(EmfTest, FileBackedEmf) {
179   // Simplest use case.
180   base::ScopedTempDir scratch_metafile_dir;
181   ASSERT_TRUE(scratch_metafile_dir.CreateUniqueTempDir());
182   base::FilePath metafile_path;
183   EXPECT_TRUE(base::CreateTemporaryFileInDir(scratch_metafile_dir.GetPath(),
184                                              &metafile_path));
185   uint32_t size;
186   std::vector<char> data;
187   {
188     Emf emf;
189     EXPECT_TRUE(emf.InitToFile(metafile_path));
190     EXPECT_TRUE(emf.context());
191     // An empty EMF is invalid, so we put at least a rectangle in it.
192     ::Rectangle(emf.context(), 10, 10, 190, 190);
193     EXPECT_TRUE(emf.FinishDocument());
194     size = emf.GetDataSize();
195     EXPECT_GT(size, EMF_HEADER_SIZE);
196     EXPECT_TRUE(emf.GetDataAsVector(&data));
197     EXPECT_EQ(data.size(), size);
198   }
199   int64_t file_size = 0;
200   base::GetFileSize(metafile_path, &file_size);
201   EXPECT_EQ(size, file_size);
202
203   // Playback the data.
204   HDC hdc = CreateCompatibleDC(nullptr);
205   EXPECT_TRUE(hdc);
206   Emf emf;
207   EXPECT_TRUE(emf.InitFromFile(metafile_path));
208   RECT output_rect = {0, 0, 10, 10};
209   EXPECT_TRUE(emf.Playback(hdc, &output_rect));
210   EXPECT_TRUE(DeleteDC(hdc));
211 }
212
213 }  // namespace printing