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