Commit 95653802 authored by Bo Majewski's avatar Bo Majewski Committed by Commit Bot

Exposes more parameters in RenderPDFPageToBitmap().

Exposes stretch_to_bounds parameter in the PDF to bitmap conversion,
which allows thumbnails generated at low DPIs to be stretched to fill
the supplied width and height.

Exposes keep_aspect parameter to allow scaled up thumbnails preserve the
original aspect ratio. As PDF is often in Letter or A4 format this helps
with more natural looking thumbnails.

Exposes dpi parameters that allow us to specify the resolution of the
generated thumbnail.

Bug: 903742
Change-Id: I9e526707f18c3d5fed84c32873d8c44573170e02
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2336335Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Reviewed-by: default avatarSam McNally <sammc@chromium.org>
Reviewed-by: default avatarNoel Gordon <noel@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Commit-Queue: Noel Gordon <noel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#797216}
parent 0b91542b
...@@ -389,7 +389,8 @@ class PrintPreviewPdfGeneratedBrowserTest : public InProcessBrowserTest { ...@@ -389,7 +389,8 @@ class PrintPreviewPdfGeneratedBrowserTest : public InProcessBrowserTest {
ASSERT_TRUE(chrome_pdf::RenderPDFPageToBitmap( ASSERT_TRUE(chrome_pdf::RenderPDFPageToBitmap(
pdf_span, i, page_bitmap_data.data(), settings.area.size().width(), pdf_span, i, page_bitmap_data.data(), settings.area.size().width(),
settings.area.size().height(), settings.dpi.width(), settings.area.size().height(), settings.dpi.width(),
settings.dpi.height(), settings.autorotate, settings.use_color)); settings.dpi.height(), false, true, settings.autorotate,
settings.use_color));
FillPng(&page_bitmap_data, width_in_pixels, max_width_in_pixels, FillPng(&page_bitmap_data, width_in_pixels, max_width_in_pixels,
settings.area.size().height()); settings.area.size().height());
bitmap_data.insert(bitmap_data.end(), bitmap_data.insert(bitmap_data.end(),
......
...@@ -17,9 +17,6 @@ namespace printing { ...@@ -17,9 +17,6 @@ namespace printing {
namespace { namespace {
// The resolution of the bitmap in dots per inch; always 300.
constexpr int kDpi = 300;
// Whether or not to rotate PDF to fit the given size; always no. // Whether or not to rotate PDF to fit the given size; always no.
constexpr bool kAutorotate = false; constexpr bool kAutorotate = false;
...@@ -66,9 +63,10 @@ void PdfThumbnailer::GetThumbnail(printing::mojom::ThumbParamsPtr params, ...@@ -66,9 +63,10 @@ void PdfThumbnailer::GetThumbnail(printing::mojom::ThumbParamsPtr params,
} }
// Convert PDF bytes into a bitmap thumbnail. // Convert PDF bytes into a bitmap thumbnail.
if (!chrome_pdf::RenderPDFPageToBitmap(pdf_buffer, 0, result.getPixels(), if (!chrome_pdf::RenderPDFPageToBitmap(
width_px, height_px, kDpi, kDpi, pdf_buffer, 0, result.getPixels(), width_px, height_px,
kAutorotate, kUseColor)) { params->dpi.width(), params->dpi.height(), params->stretch,
params->keep_aspect, kAutorotate, kUseColor)) {
DLOG(ERROR) << "Failed to render PDF buffer as bitmap image"; DLOG(ERROR) << "Failed to render PDF buffer as bitmap image";
std::move(callback).Run(SkBitmap()); std::move(callback).Run(SkBitmap());
return; return;
......
...@@ -19,8 +19,12 @@ namespace printing { ...@@ -19,8 +19,12 @@ namespace printing {
namespace { namespace {
constexpr int kThumbWidth = 96; constexpr int kThumbWidth = 256;
constexpr int kThumbHeight = 64; constexpr int kThumbHeight = 192;
constexpr int kHorizontalDpi = 300;
constexpr int kVerticalDpi = 300;
constexpr bool kStretch = true;
constexpr bool kKeepRatio = true;
const char kPdfContent[] = R"(%PDF-1.2 const char kPdfContent[] = R"(%PDF-1.2
9 0 obj 9 0 obj
...@@ -62,7 +66,9 @@ trailer ...@@ -62,7 +66,9 @@ trailer
class PdfThumbnailerTest : public testing::Test { class PdfThumbnailerTest : public testing::Test {
public: public:
void SetUp() override { void SetUp() override {
params_ = mojom::ThumbParams::New(gfx::Size(kThumbWidth, kThumbHeight)); params_ = mojom::ThumbParams::New(gfx::Size(kThumbWidth, kThumbHeight),
gfx::Size(kHorizontalDpi, kVerticalDpi),
kStretch, kKeepRatio);
} }
// Copies bytes from |bitmap| into |bitmap_|. This method is here due // Copies bytes from |bitmap| into |bitmap_|. This method is here due
...@@ -104,6 +110,25 @@ TEST_F(PdfThumbnailerTest, CreatePdfThumbnail) { ...@@ -104,6 +110,25 @@ TEST_F(PdfThumbnailerTest, CreatePdfThumbnail) {
EXPECT_EQ(kThumbHeight, bitmap_.height()); EXPECT_EQ(kThumbHeight, bitmap_.height());
} }
// A low DPI, non-stretched thumbnail.
TEST_F(PdfThumbnailerTest, CreateLowResUnstretchedPdfThumbnail) {
base::RunLoop run_loop;
auto pdf_region = CreatePdfRegion(kPdfContent);
auto params = mojom::ThumbParams::New(gfx::Size(kThumbWidth, kThumbHeight),
gfx::Size(15, 15), false, kKeepRatio);
thumbnailer_.GetThumbnail(
std::move(params), std::move(pdf_region),
base::BindOnce(&PdfThumbnailerTest::StoreResult,
weak_factory_.GetWeakPtr(), run_loop.QuitClosure()));
run_loop.Run();
EXPECT_FALSE(bitmap_.isNull());
// The bitmap size is still the requested size, even though the thumbnail
// itself does not fill the entire bitmap.
EXPECT_EQ(kThumbWidth, bitmap_.width());
EXPECT_EQ(kThumbHeight, bitmap_.height());
}
// An invalid PDF should cause failure (null bitmap returned). // An invalid PDF should cause failure (null bitmap returned).
TEST_F(PdfThumbnailerTest, CreatePdfThumbnailFailure) { TEST_F(PdfThumbnailerTest, CreatePdfThumbnailFailure) {
base::RunLoop run_loop; base::RunLoop run_loop;
...@@ -122,7 +147,9 @@ TEST_F(PdfThumbnailerTest, InvalidThumbnailSize) { ...@@ -122,7 +147,9 @@ TEST_F(PdfThumbnailerTest, InvalidThumbnailSize) {
base::RunLoop run_loop; base::RunLoop run_loop;
auto pdf_region = CreatePdfRegion(kPdfContent); auto pdf_region = CreatePdfRegion(kPdfContent);
auto params = mojom::ThumbParams::New(gfx::Size(0, 0)); auto params = mojom::ThumbParams::New(gfx::Size(0, 0),
gfx::Size(kHorizontalDpi, kVerticalDpi),
kStretch, kKeepRatio);
thumbnailer_.GetThumbnail( thumbnailer_.GetThumbnail(
std::move(params), std::move(pdf_region), std::move(params), std::move(pdf_region),
base::BindOnce(&PdfThumbnailerTest::StoreResult, base::BindOnce(&PdfThumbnailerTest::StoreResult,
...@@ -138,7 +165,8 @@ TEST_F(PdfThumbnailerTest, TooLargeThumbnailSize) { ...@@ -138,7 +165,8 @@ TEST_F(PdfThumbnailerTest, TooLargeThumbnailSize) {
auto pdf_region = CreatePdfRegion(kPdfContent); auto pdf_region = CreatePdfRegion(kPdfContent);
auto params = mojom::ThumbParams::New( auto params = mojom::ThumbParams::New(
gfx::Size(PdfThumbnailer::kMaxWidth + 1, PdfThumbnailer::kMaxHeight + 1)); gfx::Size(PdfThumbnailer::kMaxWidth + 1, PdfThumbnailer::kMaxHeight + 1),
gfx::Size(kHorizontalDpi, kVerticalDpi), kStretch, kKeepRatio);
thumbnailer_.GetThumbnail( thumbnailer_.GetThumbnail(
std::move(params), std::move(pdf_region), std::move(params), std::move(pdf_region),
base::BindOnce(&PdfThumbnailerTest::StoreResult, base::BindOnce(&PdfThumbnailerTest::StoreResult,
......
...@@ -57,7 +57,7 @@ base::ReadOnlySharedMemoryRegion RenderPdfPagesToPwgRaster( ...@@ -57,7 +57,7 @@ base::ReadOnlySharedMemoryRegion RenderPdfPagesToPwgRaster(
if (!chrome_pdf::RenderPDFPageToBitmap( if (!chrome_pdf::RenderPDFPageToBitmap(
pdf_data, page_number, image.pixel_data(), image.size().width(), pdf_data, page_number, image.pixel_data(), image.size().width(),
image.size().height(), settings.dpi.width(), settings.dpi.height(), image.size().height(), settings.dpi.width(), settings.dpi.height(),
settings.autorotate, settings.use_color)) { false, true, settings.autorotate, settings.use_color)) {
return invalid_pwg_region; return invalid_pwg_region;
} }
......
...@@ -12,6 +12,15 @@ import "ui/gfx/geometry/mojom/geometry.mojom"; ...@@ -12,6 +12,15 @@ import "ui/gfx/geometry/mojom/geometry.mojom";
struct ThumbParams { struct ThumbParams {
// The dimensions of the thumbnail. // The dimensions of the thumbnail.
gfx.mojom.Size size_px; gfx.mojom.Size size_px;
// The resolution, in dots per inch, of the thumbnail.
gfx.mojom.Size dpi;
// Whether or not to stretch the thumbnail to fill the supplied size.
bool stretch;
// Whether or not to preserve the aspect ratio.
bool keep_aspect;
}; };
// Interface used to generate a thumbnail for a PDF contents given as a set of // Interface used to generate a thumbnail for a PDF contents given as a set of
......
...@@ -370,7 +370,8 @@ class HeadlessWebContentsPDFTest : public HeadlessAsyncDevTooledBrowserTest { ...@@ -370,7 +370,8 @@ class HeadlessWebContentsPDFTest : public HeadlessAsyncDevTooledBrowserTest {
EXPECT_TRUE(chrome_pdf::RenderPDFPageToBitmap( EXPECT_TRUE(chrome_pdf::RenderPDFPageToBitmap(
pdf_span, i, page_bitmap_data.data(), settings.area.size().width(), pdf_span, i, page_bitmap_data.data(), settings.area.size().width(),
settings.area.size().height(), settings.dpi.width(), settings.area.size().height(), settings.dpi.width(),
settings.dpi.height(), settings.autorotate, settings.use_color)); settings.dpi.height(), /*stretch_to_bounds=*/false,
/*keep_aspect_ratio=*/true, settings.autorotate, settings.use_color));
EXPECT_EQ(0x56, page_bitmap_data[0]); // B EXPECT_EQ(0x56, page_bitmap_data[0]); // B
EXPECT_EQ(0x34, page_bitmap_data[1]); // G EXPECT_EQ(0x34, page_bitmap_data[1]); // G
EXPECT_EQ(0x12, page_bitmap_data[2]); // R EXPECT_EQ(0x12, page_bitmap_data[2]); // R
......
...@@ -121,13 +121,16 @@ bool RenderPDFPageToBitmap(base::span<const uint8_t> pdf_buffer, ...@@ -121,13 +121,16 @@ bool RenderPDFPageToBitmap(base::span<const uint8_t> pdf_buffer,
int bitmap_height, int bitmap_height,
int dpi_x, int dpi_x,
int dpi_y, int dpi_y,
bool stretch_to_bounds,
bool keep_aspect_ratio,
bool autorotate, bool autorotate,
bool use_color) { bool use_color) {
ScopedSdkInitializer scoped_sdk_initializer(/*enable_v8=*/true); ScopedSdkInitializer scoped_sdk_initializer(/*enable_v8=*/true);
PDFEngineExports* engine_exports = PDFEngineExports::Get(); PDFEngineExports* engine_exports = PDFEngineExports::Get();
PDFEngineExports::RenderingSettings settings( PDFEngineExports::RenderingSettings settings(
dpi_x, dpi_y, pp::Rect(bitmap_width, bitmap_height), true, false, true, dpi_x, dpi_y, pp::Rect(bitmap_width, bitmap_height),
true, autorotate, use_color); /*fit_to_bounds=*/true, stretch_to_bounds, keep_aspect_ratio,
/*center_in_bounds=*/true, autorotate, use_color);
return engine_exports->RenderPDFPageToBitmap(pdf_buffer, page_number, return engine_exports->RenderPDFPageToBitmap(pdf_buffer, page_number,
settings, bitmap_buffer); settings, bitmap_buffer);
} }
......
...@@ -136,6 +136,10 @@ bool GetPDFPageSizeByIndex(base::span<const uint8_t> pdf_buffer, ...@@ -136,6 +136,10 @@ bool GetPDFPageSizeByIndex(base::span<const uint8_t> pdf_buffer,
// |bitmap_width| is the width of the output bitmap. // |bitmap_width| is the width of the output bitmap.
// |bitmap_height| is the height of the output bitmap. // |bitmap_height| is the height of the output bitmap.
// |dpi_x| and |dpi_y| is the resolution. // |dpi_x| and |dpi_y| is the resolution.
// |stretch_to_bounds| specifies whether the output should be stretched to fit
// the supplied |bitmap_width| and |bitmap_height|.
// |keep_aspect_ratio| If any scaling is needed, this parameter specifies
// whether the original aspect ratio of the page is preserved while scaling.
// |autorotate| specifies whether the final image should be rotated to match // |autorotate| specifies whether the final image should be rotated to match
// the output bound. // the output bound.
// |use_color| specifies color or grayscale. // |use_color| specifies color or grayscale.
...@@ -147,6 +151,8 @@ bool RenderPDFPageToBitmap(base::span<const uint8_t> pdf_buffer, ...@@ -147,6 +151,8 @@ bool RenderPDFPageToBitmap(base::span<const uint8_t> pdf_buffer,
int bitmap_height, int bitmap_height,
int dpi_x, int dpi_x,
int dpi_y, int dpi_y,
bool stretch_to_bounds,
bool keep_aspect_ratio,
bool autorotate, bool autorotate,
bool use_color); bool use_color);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment