
If the print scaling option is set to PP_PRINTSCALINGOPTION_FIT_TO_PAPER, scale the contents to fit the paper, regardless of the printable area of the paper for the specified printer. Bug: 989978 Change-Id: I033f70f60b3e2d05371785291016b21fe428d4ac Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1810078 Commit-Queue: Daniel Hosseinian <dhoss@chromium.org> Reviewed-by: Lei Zhang <thestig@chromium.org> Cr-Commit-Position: refs/heads/master@{#698533}
254 lines
9.9 KiB
C++
254 lines
9.9 KiB
C++
// 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/hash/md5.h"
|
|
#include "base/stl_util.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 "ppapi/c/dev/ppp_printing_dev.h"
|
|
#include "ppapi/c/private/ppp_pdf.h"
|
|
#include "printing/pdf_render_settings.h"
|
|
#include "printing/units.h"
|
|
#include "testing/gmock/include/gmock/gmock.h"
|
|
|
|
namespace chrome_pdf {
|
|
|
|
using PDFiumPrintTest = PDFiumTestBase;
|
|
using testing::ElementsAre;
|
|
|
|
namespace {
|
|
|
|
// Number of color channels in a BGRA bitmap.
|
|
constexpr int kColorChannels = 4;
|
|
|
|
constexpr PP_Size kUSLetterSize = {612, 792};
|
|
constexpr PP_Rect kUSLetterRect = {{0, 0}, kUSLetterSize};
|
|
constexpr PP_Rect kPrintableAreaRect = {{18, 18}, {576, 733}};
|
|
|
|
struct SizeDouble {
|
|
double width;
|
|
double height;
|
|
};
|
|
|
|
using ExpectedDimensions = std::vector<SizeDouble>;
|
|
|
|
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) {
|
|
double width;
|
|
double height;
|
|
ASSERT_TRUE(exports.GetPDFPageSizeByIndex(pdf_data, i, &width, &height));
|
|
EXPECT_DOUBLE_EQ(expected_dimensions[i].width, width);
|
|
EXPECT_DOUBLE_EQ(expected_dimensions[i].height, height);
|
|
}
|
|
}
|
|
|
|
void CheckPdfRendering(const std::vector<uint8_t>& pdf_data,
|
|
int page_number,
|
|
const SizeDouble& size_in_points,
|
|
const char* expected_md5_hash) {
|
|
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 pp::Rect page_rect(width_in_pixels, height_in_pixels);
|
|
std::vector<uint8_t> page_bitmap_data(kColorChannels * page_rect.width() *
|
|
page_rect.height());
|
|
|
|
PDFEngineExports::RenderingSettings settings(
|
|
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);
|
|
|
|
PDFiumEngineExports exports;
|
|
ASSERT_TRUE(exports.RenderPDFPageToBitmap(pdf_data, page_number, settings,
|
|
page_bitmap_data.data()));
|
|
|
|
base::MD5Digest hash;
|
|
base::MD5Sum(page_bitmap_data.data(), page_bitmap_data.size(), &hash);
|
|
EXPECT_STREQ(expected_md5_hash, base::MD5DigestToBase16(hash).c_str());
|
|
}
|
|
|
|
} // namespace
|
|
|
|
TEST_F(PDFiumPrintTest, GetPageNumbersFromPrintPageNumberRange) {
|
|
std::vector<uint32_t> page_numbers;
|
|
|
|
{
|
|
const PP_PrintPageNumberRange_Dev page_ranges[] = {{0, 2}};
|
|
page_numbers = PDFiumPrint::GetPageNumbersFromPrintPageNumberRange(
|
|
&page_ranges[0], base::size(page_ranges));
|
|
EXPECT_THAT(page_numbers, ElementsAre(0, 1, 2));
|
|
}
|
|
{
|
|
const PP_PrintPageNumberRange_Dev page_ranges[] = {{0, 0}, {2, 2}, {4, 5}};
|
|
page_numbers = PDFiumPrint::GetPageNumbersFromPrintPageNumberRange(
|
|
&page_ranges[0], base::size(page_ranges));
|
|
EXPECT_THAT(page_numbers, ElementsAre(0, 2, 4, 5));
|
|
}
|
|
}
|
|
|
|
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());
|
|
|
|
constexpr PP_PrintSettings_Dev print_settings = {kUSLetterRect,
|
|
kUSLetterRect,
|
|
kUSLetterSize,
|
|
72,
|
|
PP_PRINTORIENTATION_NORMAL,
|
|
PP_PRINTSCALINGOPTION_NONE,
|
|
PP_FALSE,
|
|
PP_PRINTOUTPUTFORMAT_PDF};
|
|
constexpr PP_PdfPrintSettings_Dev pdf_print_settings = {1, 100};
|
|
|
|
{
|
|
// Print 2 pages.
|
|
const ExpectedDimensions kExpectedDimensions = {{612.0, 792.0},
|
|
{612.0, 792.0}};
|
|
const PP_PrintPageNumberRange_Dev page_ranges[] = {{0, 1}};
|
|
std::vector<uint8_t> pdf_data =
|
|
print.PrintPagesAsPdf(&page_ranges[0], base::size(page_ranges),
|
|
print_settings, pdf_print_settings,
|
|
/*raster=*/false);
|
|
CheckPdfDimensions(pdf_data, kExpectedDimensions);
|
|
|
|
pdf_data = print.PrintPagesAsPdf(&page_ranges[0], base::size(page_ranges),
|
|
print_settings, pdf_print_settings,
|
|
/*raster=*/true);
|
|
CheckPdfDimensions(pdf_data, kExpectedDimensions);
|
|
}
|
|
{
|
|
// Print 1 page.
|
|
const ExpectedDimensions kExpectedDimensions = {{612.0, 792.0}};
|
|
const PP_PrintPageNumberRange_Dev page_ranges[] = {{0, 0}};
|
|
std::vector<uint8_t> pdf_data =
|
|
print.PrintPagesAsPdf(&page_ranges[0], base::size(page_ranges),
|
|
print_settings, pdf_print_settings,
|
|
/*raster=*/false);
|
|
CheckPdfDimensions(pdf_data, kExpectedDimensions);
|
|
|
|
pdf_data = print.PrintPagesAsPdf(&page_ranges[0], base::size(page_ranges),
|
|
print_settings, pdf_print_settings,
|
|
/*raster=*/true);
|
|
CheckPdfDimensions(pdf_data, kExpectedDimensions);
|
|
}
|
|
{
|
|
// Print the other page.
|
|
const ExpectedDimensions kExpectedDimensions = {{612.0, 792.0}};
|
|
const PP_PrintPageNumberRange_Dev page_ranges[] = {{1, 1}};
|
|
std::vector<uint8_t> pdf_data =
|
|
print.PrintPagesAsPdf(&page_ranges[0], base::size(page_ranges),
|
|
print_settings, pdf_print_settings,
|
|
/*raster=*/false);
|
|
CheckPdfDimensions(pdf_data, kExpectedDimensions);
|
|
|
|
pdf_data = print.PrintPagesAsPdf(&page_ranges[0], base::size(page_ranges),
|
|
print_settings, pdf_print_settings,
|
|
/*raster=*/true);
|
|
CheckPdfDimensions(pdf_data, kExpectedDimensions);
|
|
}
|
|
}
|
|
|
|
TEST_F(PDFiumPrintTest, AlterScaling) {
|
|
TestClient client;
|
|
std::unique_ptr<PDFiumEngine> engine =
|
|
InitializeEngine(&client, FILE_PATH_LITERAL("rectangles.pdf"));
|
|
ASSERT_TRUE(engine);
|
|
|
|
PDFiumPrint print(engine.get());
|
|
|
|
PP_PrintSettings_Dev print_settings = {kPrintableAreaRect,
|
|
kUSLetterRect,
|
|
kUSLetterSize,
|
|
72,
|
|
PP_PRINTORIENTATION_NORMAL,
|
|
PP_PRINTSCALINGOPTION_NONE,
|
|
PP_FALSE,
|
|
PP_PRINTOUTPUTFORMAT_PDF};
|
|
constexpr PP_PdfPrintSettings_Dev pdf_print_settings = {1, 100};
|
|
const ExpectedDimensions kExpectedDimensions = {{612.0, 792.0}};
|
|
constexpr PP_PrintPageNumberRange_Dev page_range = {0, 0};
|
|
|
|
{
|
|
// Default scaling
|
|
static const char md5_hash[] = "40e2e16416015cdde5c6e5735c1d06ac";
|
|
static const char md5_hash_raster[] = "c29b9ed661143ea7f177d7af8a336ef7";
|
|
|
|
std::vector<uint8_t> pdf_data = print.PrintPagesAsPdf(
|
|
&page_range, 1, print_settings, pdf_print_settings,
|
|
/*raster=*/false);
|
|
CheckPdfDimensions(pdf_data, kExpectedDimensions);
|
|
CheckPdfRendering(pdf_data, 0, kExpectedDimensions[0], md5_hash);
|
|
|
|
pdf_data = print.PrintPagesAsPdf(&page_range, 1, print_settings,
|
|
pdf_print_settings,
|
|
/*raster=*/true);
|
|
CheckPdfDimensions(pdf_data, kExpectedDimensions);
|
|
CheckPdfRendering(pdf_data, 0, kExpectedDimensions[0], md5_hash_raster);
|
|
}
|
|
{
|
|
// "Fit to Page" scaling
|
|
print_settings.print_scaling_option =
|
|
PP_PRINTSCALINGOPTION_FIT_TO_PRINTABLE_AREA;
|
|
|
|
static const char md5_hash[] = "41847e1f0c581150a84794482528f790";
|
|
static const char md5_hash_raster[] = "436354693512c8144ae51837ff9f951e";
|
|
|
|
std::vector<uint8_t> pdf_data = print.PrintPagesAsPdf(
|
|
&page_range, 1, print_settings, pdf_print_settings,
|
|
/*raster=*/false);
|
|
CheckPdfDimensions(pdf_data, kExpectedDimensions);
|
|
CheckPdfRendering(pdf_data, 0, kExpectedDimensions[0], md5_hash);
|
|
|
|
pdf_data = print.PrintPagesAsPdf(&page_range, 1, print_settings,
|
|
pdf_print_settings,
|
|
/*raster=*/true);
|
|
CheckPdfDimensions(pdf_data, kExpectedDimensions);
|
|
CheckPdfRendering(pdf_data, 0, kExpectedDimensions[0], md5_hash_raster);
|
|
}
|
|
{
|
|
// "Fit to Paper" scaling
|
|
print_settings.print_scaling_option = PP_PRINTSCALINGOPTION_FIT_TO_PAPER;
|
|
|
|
static const char md5_hash[] = "3a4828228bcbae230574c057b7a0669e";
|
|
static const char md5_hash_raster[] = "8834ddfb3ef4483acf8da9d27d43cf1f";
|
|
|
|
std::vector<uint8_t> pdf_data = print.PrintPagesAsPdf(
|
|
&page_range, 1, print_settings, pdf_print_settings,
|
|
/*raster=*/false);
|
|
CheckPdfDimensions(pdf_data, kExpectedDimensions);
|
|
CheckPdfRendering(pdf_data, 0, kExpectedDimensions[0], md5_hash);
|
|
|
|
pdf_data = print.PrintPagesAsPdf(&page_range, 1, print_settings,
|
|
pdf_print_settings,
|
|
/*raster=*/true);
|
|
CheckPdfDimensions(pdf_data, kExpectedDimensions);
|
|
CheckPdfRendering(pdf_data, 0, kExpectedDimensions[0], md5_hash_raster);
|
|
}
|
|
}
|
|
|
|
} // namespace chrome_pdf
|