Commit b479a140 authored by Lei Zhang's avatar Lei Zhang Committed by Commit Bot

Merge two PDF N-up paths.

PDFiumPrint and PDFiumEngineExports both have code to create N-up PDFs.
Merge the two since they are nearly identical.

For the PDFiumPrint caller, make it do fit the page into a symmetrical
printable area, so N-up printing is consistent for PDF content and web
content.

BUG=890058

Change-Id: I933b899434f3a3cd2d853529696629aed18461e7
Reviewed-on: https://chromium-review.googlesource.com/1250162
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: default avatarRebekah Potter <rbpotter@chromium.org>
Cr-Commit-Position: refs/heads/master@{#595303}
parent 83f170eb
......@@ -3,6 +3,7 @@ include_rules = [
"+gin/public",
"+gin/v8_initializer.h",
"+printing/nup_parameters.h",
"+printing/page_setup.h",
"+third_party/pdfium/public",
"+ui/gfx/codec/jpeg_codec.h",
]
......@@ -120,37 +120,6 @@ ScopedFPDFDocument CreatePdfDoc(
return doc;
}
std::vector<uint8_t> CreateNupPdfDocument(FPDF_DOCUMENT doc,
size_t pages_per_sheet,
const gfx::Size& page_size,
const gfx::Rect& printable_area) {
int page_size_width = page_size.width();
int page_size_height = page_size.height();
printing::NupParameters nup_params;
bool is_landscape = PDFiumPrint::IsSourcePdfLandscape(doc);
nup_params.SetParameters(pages_per_sheet, is_landscape);
bool paper_is_landscape = page_size_width > page_size_height;
if (nup_params.landscape() != paper_is_landscape)
std::swap(page_size_width, page_size_height);
ScopedFPDFDocument output_doc_nup(FPDF_ImportNPagesToOne(
doc, page_size_width, page_size_height, nup_params.num_pages_on_x_axis(),
nup_params.num_pages_on_y_axis()));
if (!output_doc_nup)
return std::vector<uint8_t>();
PDFiumPrint::FitContentsToPrintableArea(output_doc_nup.get(), page_size,
printable_area);
PDFiumMemBufferFileWrite output_file_write;
if (!FPDF_SaveAsCopy(output_doc_nup.get(), &output_file_write, 0))
return std::vector<uint8_t>();
return output_file_write.TakeBuffer();
}
bool IsValidPrintableArea(const gfx::Size& page_size,
const gfx::Rect& printable_area) {
return !printable_area.IsEmpty() && printable_area.x() >= 0 &&
......@@ -324,8 +293,8 @@ std::vector<uint8_t> PDFiumEngineExports::ConvertPdfPagesToNupPdf(
if (!doc)
return std::vector<uint8_t>();
return CreateNupPdfDocument(doc.get(), pages_per_sheet, page_size,
printable_area);
return PDFiumPrint::CreateNupPdf(std::move(doc), pages_per_sheet, page_size,
printable_area);
}
std::vector<uint8_t> PDFiumEngineExports::ConvertPdfDocumentToNupPdf(
......@@ -340,8 +309,8 @@ std::vector<uint8_t> PDFiumEngineExports::ConvertPdfDocumentToNupPdf(
if (!doc)
return std::vector<uint8_t>();
return CreateNupPdfDocument(doc.get(), pages_per_sheet, page_size,
printable_area);
return PDFiumPrint::CreateNupPdf(std::move(doc), pages_per_sheet, page_size,
printable_area);
}
bool PDFiumEngineExports::GetPDFDocInfo(base::span<const uint8_t> pdf_buffer,
......
......@@ -8,7 +8,6 @@
#include <stddef.h>
#include <stdint.h>
#include "base/containers/span.h"
#include "build/build_config.h"
#include "pdf/pdf_engine.h"
......
......@@ -16,6 +16,7 @@
#include "ppapi/c/dev/ppp_printing_dev.h"
#include "ppapi/c/private/ppp_pdf.h"
#include "printing/nup_parameters.h"
#include "printing/page_setup.h"
#include "printing/units.h"
#include "third_party/pdfium/public/fpdf_flatten.h"
#include "third_party/pdfium/public/fpdf_ppo.h"
......@@ -171,32 +172,45 @@ void FitContentsToPrintableAreaIfRequired(
}
}
// Performs N-up PDF generation for |doc| based on |pages_per_sheet| and
// the parameters in |print_settings|.
// Takes the same parameters as PDFiumPrint::CreateNupPdf().
// On success, returns the N-up version of |doc|. On failure, returns nullptr.
ScopedFPDFDocument NupPdfToPdf(ScopedFPDFDocument doc,
uint32_t pages_per_sheet,
const PP_PrintSettings_Dev& print_settings) {
ScopedFPDFDocument CreateNupPdfDocument(ScopedFPDFDocument doc,
size_t pages_per_sheet,
const gfx::Size& page_size,
const gfx::Rect& printable_area) {
DCHECK(doc);
DCHECK(ShouldDoNup(pages_per_sheet));
int page_size_width = page_size.width();
int page_size_height = page_size.height();
printing::NupParameters nup_params;
bool is_landscape = PDFiumPrint::IsSourcePdfLandscape(doc.get());
nup_params.SetParameters(pages_per_sheet, is_landscape);
PP_Size page_size = print_settings.paper_size;
bool paper_is_landscape = page_size.width > page_size.height;
bool paper_is_landscape = page_size_width > page_size_height;
if (nup_params.landscape() != paper_is_landscape)
std::swap(page_size.width, page_size.height);
std::swap(page_size_width, page_size_height);
ScopedFPDFDocument nup_doc(FPDF_ImportNPagesToOne(
doc.get(), page_size.width, page_size.height,
doc.get(), page_size_width, page_size_height,
nup_params.num_pages_on_x_axis(), nup_params.num_pages_on_y_axis()));
if (nup_doc)
FitContentsToPrintableAreaIfRequired(nup_doc.get(), 1.0f, print_settings);
if (nup_doc) {
PDFiumPrint::FitContentsToPrintableArea(nup_doc.get(), page_size,
printable_area);
}
return nup_doc;
}
std::vector<uint8_t> ConvertDocToBuffer(ScopedFPDFDocument doc) {
DCHECK(doc);
std::vector<uint8_t> buffer;
PDFiumMemBufferFileWrite output_file_write;
if (FPDF_SaveAsCopy(doc.get(), &output_file_write, 0))
buffer = output_file_write.TakeBuffer();
return buffer;
}
int GetBlockForJpeg(void* param,
unsigned long pos,
unsigned char* buf,
......@@ -249,6 +263,19 @@ std::vector<uint32_t> PDFiumPrint::GetPageNumbersFromPrintPageNumberRange(
return page_numbers;
}
// static
std::vector<uint8_t> PDFiumPrint::CreateNupPdf(
ScopedFPDFDocument doc,
size_t pages_per_sheet,
const gfx::Size& page_size,
const gfx::Rect& printable_area) {
ScopedFPDFDocument nup_doc = CreateNupPdfDocument(
std::move(doc), pages_per_sheet, page_size, printable_area);
if (!nup_doc)
return std::vector<uint8_t>();
return ConvertDocToBuffer(std::move(nup_doc));
}
// static
bool PDFiumPrint::IsSourcePdfLandscape(FPDF_DOCUMENT doc) {
DCHECK(doc);
......@@ -317,7 +344,19 @@ ScopedFPDFDocument PDFiumPrint::CreatePrintPdf(
if (!ShouldDoNup(pages_per_sheet))
return output_doc;
return NupPdfToPdf(std::move(output_doc), pages_per_sheet, print_settings);
gfx::Size page_size(print_settings.paper_size.width,
print_settings.paper_size.height);
gfx::Rect printable_area(print_settings.printable_area.point.x,
print_settings.printable_area.point.y,
print_settings.printable_area.size.width,
print_settings.printable_area.size.height);
gfx::Rect symmetrical_printable_area =
printing::PageSetup::GetSymmetricalPrintableArea(page_size,
printable_area);
if (symmetrical_printable_area.IsEmpty())
return nullptr;
return CreateNupPdfDocument(std::move(output_doc), pages_per_sheet, page_size,
symmetrical_printable_area);
}
ScopedFPDFDocument PDFiumPrint::CreateRasterPdf(
......@@ -439,15 +478,4 @@ bool PDFiumPrint::FlattenPrintData(FPDF_DOCUMENT doc) const {
return true;
}
std::vector<uint8_t> PDFiumPrint::ConvertDocToBuffer(
ScopedFPDFDocument doc) const {
DCHECK(doc);
std::vector<uint8_t> buffer;
PDFiumMemBufferFileWrite output_file_write;
if (FPDF_SaveAsCopy(doc.get(), &output_file_write, 0))
buffer = output_file_write.TakeBuffer();
return buffer;
}
} // namespace chrome_pdf
......@@ -33,6 +33,15 @@ class PDFiumPrint {
const PP_PrintPageNumberRange_Dev* page_ranges,
uint32_t page_range_count);
// Performs N-up PDF generation for |doc| based on |pages_per_sheet|,
// |page_size|, and |printable_area|.
// On success, returns the N-up version of |doc| as a vector.
// On failure, returns an empty vector.
static std::vector<uint8_t> CreateNupPdf(ScopedFPDFDocument doc,
size_t pages_per_sheet,
const gfx::Size& page_size,
const gfx::Rect& printable_area);
// Check the source doc orientation. Returns true if the doc is landscape.
// For now the orientation of the doc is determined by its first page's
// orientation. Improvement can be added in the future to better determine
......@@ -69,7 +78,6 @@ class PDFiumPrint {
const PP_PrintSettings_Dev& print_settings);
bool FlattenPrintData(FPDF_DOCUMENT doc) const;
std::vector<uint8_t> ConvertDocToBuffer(ScopedFPDFDocument doc) const;
PDFiumEngine* const engine_;
......
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