blob: 249210460f21bf7cd6547311a2ee3713a57e4d2a [file] [log] [blame]
[email protected]b90d7e802011-01-09 16:32:201// Copyright (c) 2011 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]0e0fca32009-07-06 15:25:505#include "printing/emf_win.h"
initial.commit09911bf2008-07-26 23:55:296
7// For quick access.
8#include <wingdi.h>
[email protected]2aa8e182010-07-12 16:25:049#include <winspool.h>
initial.commit09911bf2008-07-26 23:55:2910
11#include "base/basictypes.h"
[email protected]daee4972009-07-09 14:28:2412#include "base/file_path.h"
initial.commit09911bf2008-07-26 23:55:2913#include "base/file_util.h"
initial.commit09911bf2008-07-26 23:55:2914#include "base/path_service.h"
[email protected]51e8d9352010-10-06 22:21:1715#include "base/scoped_ptr.h"
[email protected]f21104d2010-10-08 20:57:5716#include "base/scoped_temp_dir.h"
[email protected]0142bd4f2010-12-31 01:02:4717#include "base/win/scoped_hdc.h"
[email protected]daee4972009-07-09 14:28:2418#include "printing/printing_context.h"
initial.commit09911bf2008-07-26 23:55:2919#include "testing/gtest/include/gtest/gtest.h"
[email protected]edc531f92011-03-18 17:52:2320#include "ui/gfx/point.h"
21#include "ui/gfx/size.h"
initial.commit09911bf2008-07-26 23:55:2922
23namespace {
24
25// This test is automatically disabled if no printer named "UnitTest Printer" is
26// available.
27class EmfPrintingTest : public testing::Test {
28 public:
29 typedef testing::Test Parent;
30 static bool IsTestCaseDisabled() {
31 // It is assumed this printer is a HP Color LaserJet 4550 PCL or 4700.
32 HDC hdc = CreateDC(L"WINSPOOL", L"UnitTest Printer", NULL, NULL);
33 if (!hdc)
34 return true;
35 DeleteDC(hdc);
36 return false;
37 }
38};
39
[email protected]e6cddc572010-09-29 21:39:4540const uint32 EMF_HEADER_SIZE = 128;
41
initial.commit09911bf2008-07-26 23:55:2942} // namespace
43
[email protected]5ad76172011-03-02 19:25:1744namespace printing {
45
initial.commit09911bf2008-07-26 23:55:2946TEST(EmfTest, DC) {
initial.commit09911bf2008-07-26 23:55:2947 // Simplest use case.
[email protected]481edc52011-03-22 06:36:5848 uint32 size;
initial.commit09911bf2008-07-26 23:55:2949 std::vector<BYTE> data;
[email protected]481edc52011-03-22 06:36:5850 {
51 printing::Emf emf;
52 EXPECT_TRUE(emf.Init());
53 EXPECT_TRUE(emf.context() != NULL);
54 // An empty EMF is invalid, so we put at least a rectangle in it.
55 ::Rectangle(emf.context(), 10, 10, 190, 190);
56 EXPECT_TRUE(emf.FinishDocument());
57 size = emf.GetDataSize();
58 EXPECT_GT(size, EMF_HEADER_SIZE);
59 EXPECT_TRUE(emf.GetData(&data));
60 EXPECT_EQ(data.size(), size);
61 }
initial.commit09911bf2008-07-26 23:55:2962
63 // Playback the data.
[email protected]481edc52011-03-22 06:36:5864 printing::Emf emf;
[email protected]f2da4b02011-03-18 05:45:5165 EXPECT_TRUE(emf.InitFromData(&data.front(), size));
[email protected]481edc52011-03-22 06:36:5866 HDC hdc = CreateCompatibleDC(NULL);
67 EXPECT_TRUE(hdc);
initial.commit09911bf2008-07-26 23:55:2968 RECT output_rect = {0, 0, 10, 10};
69 EXPECT_TRUE(emf.Playback(hdc, &output_rect));
70 EXPECT_TRUE(DeleteDC(hdc));
71}
72
initial.commit09911bf2008-07-26 23:55:2973// Disabled if no "UnitTest printer" exist. Useful to reproduce bug 1186598.
74TEST_F(EmfPrintingTest, Enumerate) {
75 if (IsTestCaseDisabled())
76 return;
77
78 printing::PrintSettings settings;
79
80 // My test case is a HP Color LaserJet 4550 PCL.
81 settings.set_device_name(L"UnitTest Printer");
82
83 // Initialize it.
[email protected]51e8d9352010-10-06 22:21:1784 scoped_ptr<printing::PrintingContext> context(
[email protected]ee5f36e42010-12-03 22:40:3785 printing::PrintingContext::Create(std::string()));
[email protected]51e8d9352010-10-06 22:21:1786 EXPECT_EQ(context->InitWithSettings(settings), printing::PrintingContext::OK);
initial.commit09911bf2008-07-26 23:55:2987
[email protected]daee4972009-07-09 14:28:2488 FilePath emf_file;
89 EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &emf_file));
90 emf_file = emf_file.Append(FILE_PATH_LITERAL("printing"))
91 .Append(FILE_PATH_LITERAL("test"))
92 .Append(FILE_PATH_LITERAL("data"))
93 .Append(FILE_PATH_LITERAL("test4.emf"));
initial.commit09911bf2008-07-26 23:55:2994 // Load any EMF with an image.
[email protected]0e0fca32009-07-06 15:25:5095 printing::Emf emf;
initial.commit09911bf2008-07-26 23:55:2996 std::string emf_data;
[email protected]daee4972009-07-09 14:28:2497 file_util::ReadFileToString(emf_file, &emf_data);
initial.commit09911bf2008-07-26 23:55:2998 ASSERT_TRUE(emf_data.size());
[email protected]89eff96a2011-03-17 23:22:0699 EXPECT_TRUE(emf.InitFromData(&emf_data[0], emf_data.size()));
initial.commit09911bf2008-07-26 23:55:29100
101 // This will print to file. The reason is that when running inside a
102 // unit_test, printing::PrintingContext automatically dumps its files to the
103 // current directory.
104 // TODO(maruel): Clean the .PRN file generated in current directory.
[email protected]51e8d9352010-10-06 22:21:17105 context->NewDocument(L"EmfTest.Enumerate");
106 context->NewPage();
initial.commit09911bf2008-07-26 23:55:29107 // Process one at a time.
[email protected]51e8d9352010-10-06 22:21:17108 printing::Emf::Enumerator emf_enum(emf, context->context(),
[email protected]8f17cd3e2011-03-16 01:39:42109 &emf.GetPageBounds(1).ToRECT());
[email protected]0e0fca32009-07-06 15:25:50110 for (printing::Emf::Enumerator::const_iterator itr = emf_enum.begin();
initial.commit09911bf2008-07-26 23:55:29111 itr != emf_enum.end();
112 ++itr) {
113 // To help debugging.
114 ptrdiff_t index = itr - emf_enum.begin();
115 // If you get this assert, you need to lookup iType in wingdi.h. It starts
116 // with EMR_HEADER.
117 EMR_HEADER;
118 EXPECT_TRUE(itr->SafePlayback(NULL)) <<
119 " index: " << index << " type: " << itr->record()->iType;
120 }
[email protected]51e8d9352010-10-06 22:21:17121 context->PageDone();
122 context->DocumentDone();
initial.commit09911bf2008-07-26 23:55:29123}
[email protected]daee4972009-07-09 14:28:24124
[email protected]2aa8e182010-07-12 16:25:04125// Disabled if no "UnitTest printer" exists.
126TEST_F(EmfPrintingTest, PageBreak) {
[email protected]0142bd4f2010-12-31 01:02:47127 base::win::ScopedHDC dc(
128 CreateDC(L"WINSPOOL", L"UnitTest Printer", NULL, NULL));
[email protected]2aa8e182010-07-12 16:25:04129 if (!dc.Get())
130 return;
[email protected]481edc52011-03-22 06:36:58131 uint32 size;
[email protected]f2da4b02011-03-18 05:45:51132 std::vector<BYTE> data;
[email protected]481edc52011-03-22 06:36:58133 {
134 printing::Emf emf;
135 EXPECT_TRUE(emf.Init());
136 EXPECT_TRUE(emf.context() != NULL);
137 int pages = 3;
138 while (pages) {
139 EXPECT_TRUE(emf.StartPage(gfx::Size(), gfx::Point(), 1));
140 ::Rectangle(emf.context(), 10, 10, 190, 190);
141 EXPECT_TRUE(emf.FinishPage());
142 --pages;
143 }
144 EXPECT_TRUE(emf.FinishDocument());
145 size = emf.GetDataSize();
146 EXPECT_TRUE(emf.GetData(&data));
147 EXPECT_EQ(data.size(), size);
148 }
[email protected]2aa8e182010-07-12 16:25:04149
150 // Playback the data.
151 DOCINFO di = {0};
152 di.cbSize = sizeof(DOCINFO);
153 di.lpszDocName = L"Test Job";
154 int job_id = ::StartDoc(dc.Get(), &di);
[email protected]481edc52011-03-22 06:36:58155 printing::Emf emf;
[email protected]89eff96a2011-03-17 23:22:06156 EXPECT_TRUE(emf.InitFromData(&data.front(), size));
[email protected]2aa8e182010-07-12 16:25:04157 EXPECT_TRUE(emf.SafePlayback(dc.Get()));
158 ::EndDoc(dc.Get());
159 // Since presumably the printer is not real, let us just delete the job from
160 // the queue.
161 HANDLE printer = NULL;
162 if (::OpenPrinter(L"UnitTest Printer", &printer, NULL)) {
163 ::SetJob(printer, job_id, 0, NULL, JOB_CONTROL_DELETE);
164 ClosePrinter(printer);
165 }
166}
167
[email protected]481edc52011-03-22 06:36:58168TEST(EmfTest, FileBackedEmf) {
[email protected]e6cddc572010-09-29 21:39:45169 // Simplest use case.
[email protected]f21104d2010-10-08 20:57:57170 ScopedTempDir scratch_metafile_dir;
171 ASSERT_TRUE(scratch_metafile_dir.CreateUniqueTempDir());
[email protected]e6cddc572010-09-29 21:39:45172 FilePath metafile_path;
[email protected]f21104d2010-10-08 20:57:57173 EXPECT_TRUE(file_util::CreateTemporaryFileInDir(scratch_metafile_dir.path(),
174 &metafile_path));
[email protected]481edc52011-03-22 06:36:58175 uint32 size;
[email protected]e6cddc572010-09-29 21:39:45176 std::vector<BYTE> data;
[email protected]481edc52011-03-22 06:36:58177 {
178 printing::Emf emf;
179 EXPECT_TRUE(emf.InitToFile(metafile_path));
180 EXPECT_TRUE(emf.context() != NULL);
181 // An empty EMF is invalid, so we put at least a rectangle in it.
182 ::Rectangle(emf.context(), 10, 10, 190, 190);
183 EXPECT_TRUE(emf.FinishDocument());
184 size = emf.GetDataSize();
185 EXPECT_GT(size, EMF_HEADER_SIZE);
186 EXPECT_TRUE(emf.GetData(&data));
187 EXPECT_EQ(data.size(), size);
188 }
[email protected]e6cddc572010-09-29 21:39:45189 int64 file_size = 0;
190 file_util::GetFileSize(metafile_path, &file_size);
191 EXPECT_EQ(size, file_size);
[email protected]e6cddc572010-09-29 21:39:45192
193 // Playback the data.
[email protected]481edc52011-03-22 06:36:58194 HDC hdc = CreateCompatibleDC(NULL);
[email protected]e6cddc572010-09-29 21:39:45195 EXPECT_TRUE(hdc);
[email protected]481edc52011-03-22 06:36:58196 printing::Emf emf;
197 EXPECT_TRUE(emf.InitFromFile(metafile_path));
[email protected]e6cddc572010-09-29 21:39:45198 RECT output_rect = {0, 0, 10, 10};
199 EXPECT_TRUE(emf.Playback(hdc, &output_rect));
200 EXPECT_TRUE(DeleteDC(hdc));
201}
202
[email protected]5ad76172011-03-02 19:25:17203} // namespace printing