0

Add "fit to paper" functionality to handle new enum value

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}
This commit is contained in:
Daniel Hosseinian
2019-09-20 17:39:28 +00:00
committed by Commit Bot
parent bd1d82167d
commit 12c1bd6c1a
3 changed files with 138 additions and 8 deletions

@ -4,6 +4,7 @@ include_rules = [
"+gin/v8_initializer.h",
"+printing/nup_parameters.h",
"+printing/page_setup.h",
"+printing/pdf_render_settings.h",
"+third_party/pdfium/public",
"+ui/gfx/codec/jpeg_codec.h",
]

@ -74,10 +74,7 @@ void TransformPDFPageForPrinting(FPDF_PAGE page,
// Get the source page width and height in points.
const double src_page_width = FPDF_GetPageWidth(page);
const double src_page_height = FPDF_GetPageHeight(page);
const int src_page_rotation = FPDFPage_GetRotation(page);
const bool fit_to_page = print_settings.print_scaling_option ==
PP_PRINTSCALINGOPTION_FIT_TO_PRINTABLE_AREA;
pp::Size page_size(print_settings.paper_size);
pp::Rect content_rect(print_settings.printable_area);
@ -91,10 +88,25 @@ void TransformPDFPageForPrinting(FPDF_PAGE page,
const int actual_page_height =
rotated ? page_size.width() : page_size.height();
const gfx::Rect gfx_content_rect(content_rect.x(), content_rect.y(),
gfx::Rect gfx_printed_rect;
bool fitted_scaling;
switch (print_settings.print_scaling_option) {
case PP_PRINTSCALINGOPTION_FIT_TO_PRINTABLE_AREA:
gfx_printed_rect = gfx::Rect(content_rect.x(), content_rect.y(),
content_rect.width(), content_rect.height());
if (fit_to_page) {
scale_factor = CalculateScaleFactor(gfx_content_rect, src_page_width,
fitted_scaling = true;
break;
case PP_PRINTSCALINGOPTION_FIT_TO_PAPER:
gfx_printed_rect = gfx::Rect(page_size.width(), page_size.height());
fitted_scaling = true;
break;
default:
fitted_scaling = false;
break;
}
if (fitted_scaling) {
scale_factor = CalculateScaleFactor(gfx_printed_rect, src_page_width,
src_page_height, rotated);
}
@ -114,8 +126,9 @@ void TransformPDFPageForPrinting(FPDF_PAGE page,
// Calculate the translation offset values.
double offset_x = 0;
double offset_y = 0;
if (fit_to_page) {
CalculateScaledClipBoxOffset(gfx_content_rect, source_clip_box, &offset_x,
if (fitted_scaling) {
CalculateScaledClipBoxOffset(gfx_printed_rect, source_clip_box, &offset_x,
&offset_y);
} else {
CalculateNonScaledClipBoxOffset(src_page_rotation, actual_page_width,

@ -6,6 +6,7 @@
#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"
@ -13,6 +14,8 @@
#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 {
@ -22,8 +25,12 @@ 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;
@ -49,6 +56,37 @@ void CheckPdfDimensions(const std::vector<uint8_t>& pdf_data,
}
}
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) {
@ -134,4 +172,82 @@ TEST_F(PDFiumPrintTest, Basic) {
}
}
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