blob: bcd515a4e017146dbd7c0a3d8504f568e30bd55c [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/test/base/in_process_browser_test.h"
#include <Windows.h>
#include "base/files/file_util.h"
#include "base/memory/ref_counted_memory.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/sha1.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "chrome/browser/printing/pdf_to_emf_converter.h"
#include "chrome/common/chrome_paths.h"
#include "printing/emf_win.h"
#include "printing/metafile.h"
#include "printing/pdf_render_settings.h"
namespace printing {
namespace {
using PDFToEMFConverterBrowserTest = InProcessBrowserTest;
void StartCallbackImpl(base::Closure quit_closure,
int* page_count_out,
int page_count_in) {
*page_count_out = page_count_in;
quit_closure.Run();
}
void GetPageCallbackImpl(base::Closure quit_closure,
int* page_number_out,
std::unique_ptr<MetafilePlayer>* file_out,
int page_number_in,
float scale_factor,
std::unique_ptr<MetafilePlayer> file_in) {
*page_number_out = page_number_in;
*file_out = std::move(file_in);
quit_closure.Run();
}
std::unique_ptr<ENHMETAHEADER> GetEMFHeader(const std::string& emf_data) {
Emf emf;
if (!emf.InitFromData(emf_data.data(), emf_data.length()))
return nullptr;
auto meta_header = std::make_unique<ENHMETAHEADER>();
size_t header_size = sizeof(ENHMETAHEADER);
if (GetEnhMetaFileHeader(emf.emf(), header_size, meta_header.get()) !=
header_size) {
return nullptr;
}
return meta_header;
}
void CompareEMFHeaders(const ENHMETAHEADER& expected_header,
const ENHMETAHEADER& actual_header) {
// TODO(crbug.com/781403): once the EMF generation is fixed, also compare:
// rclBounds, rclFrame, szlDevice, szlMillimeters and szlMicrometers.
EXPECT_EQ(expected_header.iType, actual_header.iType);
EXPECT_EQ(expected_header.nSize, actual_header.nSize);
EXPECT_EQ(expected_header.dSignature, actual_header.dSignature);
EXPECT_EQ(expected_header.nVersion, actual_header.nVersion);
EXPECT_EQ(expected_header.nBytes, actual_header.nBytes);
EXPECT_EQ(expected_header.nRecords, actual_header.nRecords);
EXPECT_EQ(expected_header.nHandles, actual_header.nHandles);
EXPECT_EQ(expected_header.sReserved, actual_header.sReserved);
EXPECT_EQ(expected_header.nDescription, actual_header.nDescription);
EXPECT_EQ(expected_header.offDescription, actual_header.offDescription);
EXPECT_EQ(expected_header.nPalEntries, actual_header.nPalEntries);
EXPECT_EQ(expected_header.cbPixelFormat, actual_header.cbPixelFormat);
EXPECT_EQ(expected_header.offPixelFormat, actual_header.offPixelFormat);
EXPECT_EQ(expected_header.bOpenGL, actual_header.bOpenGL);
}
} // namespace
IN_PROC_BROWSER_TEST_F(PDFToEMFConverterBrowserTest, TestFailure) {
scoped_refptr<base::RefCountedStaticMemory> bad_pdf_data =
base::MakeRefCounted<base::RefCountedStaticMemory>("0123456789", 10);
base::RunLoop run_loop;
int page_count = -1;
std::unique_ptr<PdfConverter> pdf_converter = PdfConverter::StartPdfConverter(
bad_pdf_data, PdfRenderSettings(),
base::Bind(&StartCallbackImpl, run_loop.QuitClosure(), &page_count));
run_loop.Run();
EXPECT_EQ(0, page_count);
}
IN_PROC_BROWSER_TEST_F(PDFToEMFConverterBrowserTest, TestSuccess) {
base::ScopedAllowBlockingForTesting allow_blocking;
base::FilePath test_data_dir;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir));
test_data_dir = test_data_dir.AppendASCII("printing");
base::FilePath pdf_file = test_data_dir.AppendASCII("pdf_to_emf_test.pdf");
std::string pdf_data_str;
ASSERT_TRUE(base::ReadFileToString(pdf_file, &pdf_data_str));
ASSERT_GT(pdf_data_str.length(), 0U);
scoped_refptr<base::RefCountedString> pdf_data(
base::RefCountedString::TakeString(&pdf_data_str));
// A4 page format.
PdfRenderSettings pdf_settings(gfx::Rect(0, 0, 1700, 2200), gfx::Point(0, 0),
/*dpi=*/200, /*autorotate=*/false,
PdfRenderSettings::Mode::NORMAL);
constexpr int kNumberOfPages = 3;
std::unique_ptr<PdfConverter> pdf_converter;
{
base::RunLoop run_loop;
int page_count = -1;
pdf_converter = PdfConverter::StartPdfConverter(
pdf_data, pdf_settings,
base::Bind(&StartCallbackImpl, run_loop.QuitClosure(), &page_count));
run_loop.Run();
ASSERT_EQ(kNumberOfPages, page_count);
}
for (int i = 0; i < kNumberOfPages; i++) {
int page_number = -1;
std::unique_ptr<MetafilePlayer> emf_file;
base::RunLoop run_loop;
pdf_converter->GetPage(
i, base::Bind(&GetPageCallbackImpl, run_loop.QuitClosure(),
&page_number, &emf_file));
run_loop.Run();
ASSERT_EQ(i, page_number);
// We have to save the EMF to a file as LazyEmf::GetDataAsVector() is not
// implemented.
base::FilePath actual_emf_file_path;
ASSERT_TRUE(base::CreateTemporaryFile(&actual_emf_file_path));
base::File actual_emf_file(
actual_emf_file_path,
base::File::Flags::FLAG_CREATE_ALWAYS | base::File::Flags::FLAG_WRITE);
ASSERT_TRUE(emf_file->SaveTo(&actual_emf_file));
actual_emf_file.Close();
std::string actual_emf_data;
ASSERT_TRUE(base::ReadFileToString(actual_emf_file_path, &actual_emf_data));
ASSERT_GT(actual_emf_data.length(), 0U);
base::FilePath expected_emf_file = test_data_dir.AppendASCII(
"pdf_to_emf_test_page_" +
std::to_string(i + 1 /* page numbers start at 1 */) + ".emf");
std::string expected_emf_data;
ASSERT_TRUE(base::ReadFileToString(expected_emf_file, &expected_emf_data));
ASSERT_GT(expected_emf_data.length(), 0U);
// TODO(crbug.com/781403): the generated data can differ visually. Until
// this is fixed only checking the output size and parts of the EMF header.
ASSERT_EQ(expected_emf_data.length(), actual_emf_data.length());
std::unique_ptr<ENHMETAHEADER> expected_header =
GetEMFHeader(expected_emf_data);
ASSERT_TRUE(expected_header);
std::unique_ptr<ENHMETAHEADER> actual_header =
GetEMFHeader(actual_emf_data);
ASSERT_TRUE(actual_header);
CompareEMFHeaders(*expected_header, *actual_header);
}
}
} // namespace printing