blob: dda46cad4a98a73c0be61f5ed0b45891cba08adf [file] [log] [blame]
// Copyright 2018 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 "pdf/pdfium/pdfium_print.h"
#include <memory>
#include "base/files/file_path.h"
#include "base/strings/string_piece.h"
#include "pdf/pdfium/pdfium_engine.h"
#include "pdf/pdfium/pdfium_engine_exports.h"
#include "pdf/pdfium/pdfium_test_base.h"
#include "pdf/test/test_client.h"
#include "pdf/test/test_helpers.h"
#include "printing/pdf_render_settings.h"
#include "printing/units.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/blink/public/web/web_print_params.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size_f.h"
#include "ui/gfx/geometry/skia_conversions.h"
namespace chrome_pdf {
using PDFiumPrintTest = PDFiumTestBase;
using ::testing::ElementsAre;
namespace {
constexpr gfx::Size kUSLetterSize = {612, 792};
constexpr gfx::Rect kUSLetterRect = {{0, 0}, kUSLetterSize};
constexpr gfx::Rect kPrintableAreaRect = {{18, 18}, {576, 733}};
using ExpectedDimensions = std::vector<gfx::SizeF>;
base::FilePath GetReferenceFilePath(base::StringPiece test_filename) {
return base::FilePath(FILE_PATH_LITERAL("pdfium_print"))
.AppendASCII(test_filename);
}
blink::WebPrintParams GetDefaultPrintParams() {
blink::WebPrintParams params;
params.print_content_area = kUSLetterRect;
params.printable_area = kUSLetterRect;
params.paper_size = kUSLetterSize;
params.print_scaling_option = printing::mojom::PrintScalingOption::kNone;
return params;
}
void CheckPdfDimensions(const std::vector<uint8_t>& pdf_data,
const ExpectedDimensions& expected_dimensions) {
PDFiumEngineExports exports;
int page_count;
ASSERT_TRUE(exports.GetPDFDocInfo(pdf_data, &page_count, nullptr));
ASSERT_GT(page_count, 0);
ASSERT_EQ(expected_dimensions.size(), static_cast<size_t>(page_count));
for (int i = 0; i < page_count; ++i) {
absl::optional<gfx::SizeF> page_size =
exports.GetPDFPageSizeByIndex(pdf_data, i);
ASSERT_TRUE(page_size.has_value());
EXPECT_EQ(expected_dimensions[i], page_size.value());
}
}
void CheckPdfRendering(const std::vector<uint8_t>& pdf_data,
int page_number,
const gfx::SizeF& size_in_points,
base::StringPiece expected_png_filename) {
int width_in_pixels =
printing::ConvertUnit(size_in_points.width(), printing::kPointsPerInch,
printing::kDefaultPdfDpi);
int height_in_pixels =
printing::ConvertUnit(size_in_points.height(), printing::kPointsPerInch,
printing::kDefaultPdfDpi);
const gfx::Rect page_rect(width_in_pixels, height_in_pixels);
SkBitmap page_bitmap;
page_bitmap.allocPixels(
SkImageInfo::Make(gfx::SizeToSkISize(page_rect.size()),
kBGRA_8888_SkColorType, kPremul_SkAlphaType));
PDFEngineExports::RenderingSettings settings(
gfx::Size(printing::kDefaultPdfDpi, printing::kDefaultPdfDpi), page_rect,
/*fit_to_bounds=*/true,
/*stretch_to_bounds=*/false,
/*keep_aspect_ratio=*/true,
/*center_in_bounds=*/true,
/*autorotate=*/false, /*use_color=*/true, /*render_for_printing=*/true);
PDFiumEngineExports exports;
ASSERT_TRUE(exports.RenderPDFPageToBitmap(pdf_data, page_number, settings,
page_bitmap.getPixels()));
EXPECT_TRUE(MatchesPngFile(page_bitmap.asImage().get(),
GetReferenceFilePath(expected_png_filename)));
}
} // namespace
TEST_F(PDFiumPrintTest, Basic) {
TestClient client;
std::unique_ptr<PDFiumEngine> engine =
InitializeEngine(&client, FILE_PATH_LITERAL("hello_world2.pdf"));
ASSERT_TRUE(engine);
PDFiumPrint print(engine.get());
blink::WebPrintParams print_params = GetDefaultPrintParams();
blink::WebPrintParams print_params_raster = print_params;
print_params_raster.rasterize_pdf = true;
{
// Print 2 pages.
const ExpectedDimensions kExpectedDimensions = {{612.0, 792.0},
{612.0, 792.0}};
const std::vector<int> pages = {0, 1};
std::vector<uint8_t> pdf_data = print.PrintPagesAsPdf(pages, print_params);
CheckPdfDimensions(pdf_data, kExpectedDimensions);
pdf_data = print.PrintPagesAsPdf(pages, print_params_raster);
CheckPdfDimensions(pdf_data, kExpectedDimensions);
}
{
// Print 1 page.
const ExpectedDimensions kExpectedDimensions = {{612.0, 792.0}};
const std::vector<int> pages = {0};
std::vector<uint8_t> pdf_data = print.PrintPagesAsPdf(pages, print_params);
CheckPdfDimensions(pdf_data, kExpectedDimensions);
pdf_data = print.PrintPagesAsPdf(pages, print_params_raster);
CheckPdfDimensions(pdf_data, kExpectedDimensions);
}
{
// Print the other page.
const ExpectedDimensions kExpectedDimensions = {{612.0, 792.0}};
const std::vector<int> pages = {1};
std::vector<uint8_t> pdf_data = print.PrintPagesAsPdf(pages, print_params);
CheckPdfDimensions(pdf_data, kExpectedDimensions);
pdf_data = print.PrintPagesAsPdf(pages, print_params_raster);
CheckPdfDimensions(pdf_data, kExpectedDimensions);
}
}
// Tests fail on mac11-arm-64-rel-tests (https://crbug.com/1291973)
#if BUILDFLAG(IS_MAC)
#define MAYBE_AlterScalingDefault DISABLED_AlterScalingDefault
#define MAYBE_AlterScalingFitPaper DISABLED_AlterScalingFitPaper
#define MAYBE_AlterScalingFitPrintable DISABLED_AlterScalingFitPrintable
#else
#define MAYBE_AlterScalingDefault AlterScalingDefault
#define MAYBE_AlterScalingFitPaper AlterScalingFitPaper
#define MAYBE_AlterScalingFitPrintable AlterScalingFitPrintable
#endif
TEST_F(PDFiumPrintTest, MAYBE_AlterScalingDefault) {
TestClient client;
std::unique_ptr<PDFiumEngine> engine =
InitializeEngine(&client, FILE_PATH_LITERAL("rectangles.pdf"));
ASSERT_TRUE(engine);
PDFiumPrint print(engine.get());
const ExpectedDimensions kExpectedDimensions = {{612.0, 792.0}};
const std::vector<int> pages = {0};
blink::WebPrintParams print_params = GetDefaultPrintParams();
print_params.printable_area = kPrintableAreaRect;
std::vector<uint8_t> pdf_data = print.PrintPagesAsPdf(pages, print_params);
CheckPdfDimensions(pdf_data, kExpectedDimensions);
CheckPdfRendering(pdf_data, 0, kExpectedDimensions[0],
"alter_scaling_default.png");
print_params.rasterize_pdf = true;
pdf_data = print.PrintPagesAsPdf(pages, print_params);
CheckPdfDimensions(pdf_data, kExpectedDimensions);
CheckPdfRendering(pdf_data, 0, kExpectedDimensions[0],
"alter_scaling_default_raster.png");
}
TEST_F(PDFiumPrintTest, MAYBE_AlterScalingFitPaper) {
TestClient client;
std::unique_ptr<PDFiumEngine> engine =
InitializeEngine(&client, FILE_PATH_LITERAL("rectangles.pdf"));
ASSERT_TRUE(engine);
PDFiumPrint print(engine.get());
const ExpectedDimensions kExpectedDimensions = {{612.0, 792.0}};
const std::vector<int> pages = {0};
blink::WebPrintParams print_params = GetDefaultPrintParams();
print_params.printable_area = kPrintableAreaRect;
print_params.print_scaling_option =
printing::mojom::PrintScalingOption::kFitToPaper;
std::vector<uint8_t> pdf_data = print.PrintPagesAsPdf(pages, print_params);
CheckPdfDimensions(pdf_data, kExpectedDimensions);
CheckPdfRendering(pdf_data, 0, kExpectedDimensions[0],
"alter_scaling_fit-paper.png");
print_params.rasterize_pdf = true;
pdf_data = print.PrintPagesAsPdf(pages, print_params);
CheckPdfDimensions(pdf_data, kExpectedDimensions);
CheckPdfRendering(pdf_data, 0, kExpectedDimensions[0],
"alter_scaling_fit-paper_raster.png");
}
TEST_F(PDFiumPrintTest, MAYBE_AlterScalingFitPrintable) {
TestClient client;
std::unique_ptr<PDFiumEngine> engine =
InitializeEngine(&client, FILE_PATH_LITERAL("rectangles.pdf"));
ASSERT_TRUE(engine);
PDFiumPrint print(engine.get());
const ExpectedDimensions kExpectedDimensions = {{612.0, 792.0}};
const std::vector<int> pages = {0};
blink::WebPrintParams print_params = GetDefaultPrintParams();
print_params.printable_area = kPrintableAreaRect;
print_params.print_scaling_option =
printing::mojom::PrintScalingOption::kFitToPrintableArea;
std::vector<uint8_t> pdf_data = print.PrintPagesAsPdf(pages, print_params);
CheckPdfDimensions(pdf_data, kExpectedDimensions);
CheckPdfRendering(pdf_data, 0, kExpectedDimensions[0],
"alter_scaling_fit-printable.png");
print_params.rasterize_pdf = true;
pdf_data = print.PrintPagesAsPdf(pages, print_params);
CheckPdfDimensions(pdf_data, kExpectedDimensions);
CheckPdfRendering(pdf_data, 0, kExpectedDimensions[0],
"alter_scaling_fit-printable_raster.png");
}
} // namespace chrome_pdf