Add PrintWithReducedRasterization feature.
Add an off by default base::Feature for controlling how much rasterization to do when printing in EMF mode on Windows. This will reduce print job sizes in some cases. Since the feature caused printing regressions in the past, having a base::Feature toggle will allow the feature to be rolled out in a controlled manner. This CL includes: - Plumbing for the browser to tell the PdfToEmfConverter service to use the new printing modes. - New Printing.ConversionSize metrics to see how the new printing modes perform size-wise. Along the way, all Printing.ConversionSize metrics have been updated with secondary owners and actual expiration dates. - A very basic sanity test. Bug: 674771 Change-Id: I7ccd8d4c9320eb1c42f3c3040814ed41027f36bc Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2194797 Commit-Queue: Lei Zhang <thestig@chromium.org> Reviewed-by: Rebekah Potter <rbpotter@chromium.org> Reviewed-by: Tom Sepez <tsepez@chromium.org> Reviewed-by: Alexei Svitkine <asvitkine@chromium.org> Cr-Commit-Position: refs/heads/master@{#768459}
This commit is contained in:
chrome
browser
services
pdf
printing
tools/metrics/histograms
@ -408,6 +408,16 @@ void PdfConverterImpl::RecordConversionMetrics() {
|
||||
UMA_HISTOGRAM_MEMORY_KB("Printing.ConversionSize.PostScript3",
|
||||
average_page_size_in_kb);
|
||||
return;
|
||||
case PdfRenderSettings::Mode::EMF_WITH_REDUCED_RASTERIZATION:
|
||||
UMA_HISTOGRAM_MEMORY_KB(
|
||||
"Printing.ConversionSize.EmfWithReducedRasterization",
|
||||
average_page_size_in_kb);
|
||||
return;
|
||||
case PdfRenderSettings::Mode::EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT:
|
||||
UMA_HISTOGRAM_MEMORY_KB(
|
||||
"Printing.ConversionSize.EmfWithReducedRasterizationAndGdiText",
|
||||
average_page_size_in_kb);
|
||||
return;
|
||||
default:
|
||||
NOTREACHED();
|
||||
return;
|
||||
|
@ -266,6 +266,26 @@ IN_PROC_BROWSER_TEST_F(PdfToEmfConverterBrowserTest, EmfBasic) {
|
||||
}
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(PdfToEmfConverterBrowserTest,
|
||||
EmfWithReducedRasterizationBasic) {
|
||||
const PdfRenderSettings pdf_settings(
|
||||
kLetter200DpiRect, gfx::Point(0, 0), k200DpiSize,
|
||||
/*autorotate=*/false,
|
||||
/*use_color=*/true,
|
||||
PdfRenderSettings::Mode::EMF_WITH_REDUCED_RASTERIZATION);
|
||||
constexpr int kNumberOfPages = 3;
|
||||
|
||||
ASSERT_TRUE(GetTestInput("pdf_converter_basic.pdf"));
|
||||
ASSERT_TRUE(StartPdfConverter(pdf_settings, kNumberOfPages));
|
||||
for (int i = 0; i < kNumberOfPages; ++i) {
|
||||
ASSERT_TRUE(GetPage(i));
|
||||
ASSERT_TRUE(GetPageExpectedEmfData(
|
||||
GetFileNameForPageNumber("pdf_converter_basic_emf_page_", i)));
|
||||
ComparePageEmfHeader();
|
||||
// TODO(thestig): Check if ComparePageEmfPayload() works on bots.
|
||||
}
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(PdfToEmfConverterBrowserTest, PostScriptLevel2Basic) {
|
||||
const PdfRenderSettings pdf_settings(
|
||||
kLetter200DpiRect, gfx::Point(0, 0), k200DpiSize,
|
||||
|
@ -29,17 +29,29 @@
|
||||
#include "chrome/common/chrome_features.h"
|
||||
#include "printing/pdf_render_settings.h"
|
||||
#include "printing/printed_page_win.h"
|
||||
#include "printing/printing_features.h"
|
||||
#endif
|
||||
|
||||
using base::TimeDelta;
|
||||
|
||||
namespace printing {
|
||||
|
||||
namespace {
|
||||
|
||||
// Helper function to ensure |job| is valid until at least |callback| returns.
|
||||
void HoldRefCallback(scoped_refptr<PrintJob> job, base::OnceClosure callback) {
|
||||
std::move(callback).Run();
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
bool PrintWithReducedRasterization() {
|
||||
// TODO(crbug.com/674771): Support setting via policy.
|
||||
return base::FeatureList::IsEnabled(features::kPrintWithReducedRasterization);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
PrintJob::PrintJob() {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
}
|
||||
@ -319,11 +331,21 @@ void PrintJob::StartPdfToEmfConversion(
|
||||
bool print_text_with_gdi =
|
||||
settings.print_text_with_gdi() && !settings.printer_is_xps() &&
|
||||
base::FeatureList::IsEnabled(::features::kGdiTextPrinting);
|
||||
bool print_with_reduced_rasterization = PrintWithReducedRasterization();
|
||||
|
||||
using RenderMode = PdfRenderSettings::Mode;
|
||||
RenderMode mode;
|
||||
if (print_with_reduced_rasterization) {
|
||||
mode = print_text_with_gdi
|
||||
? RenderMode::EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT
|
||||
: RenderMode::EMF_WITH_REDUCED_RASTERIZATION;
|
||||
} else {
|
||||
mode = print_text_with_gdi ? RenderMode::GDI_TEXT : RenderMode::NORMAL;
|
||||
}
|
||||
|
||||
PdfRenderSettings render_settings(
|
||||
content_area, gfx::Point(0, 0), settings.dpi_size(),
|
||||
/*autorotate=*/true, settings.color() == COLOR,
|
||||
print_text_with_gdi ? PdfRenderSettings::Mode::GDI_TEXT
|
||||
: PdfRenderSettings::Mode::NORMAL);
|
||||
/*autorotate=*/true, settings.color() == COLOR, mode);
|
||||
pdf_conversion_state_->Start(
|
||||
bytes, render_settings,
|
||||
base::BindOnce(&PrintJob::OnPdfConversionStarted, this));
|
||||
@ -581,4 +603,5 @@ PrintedDocument* JobEventDetails::document() const { return document_.get(); }
|
||||
#if defined(OS_WIN)
|
||||
PrintedPage* JobEventDetails::page() const { return page_.get(); }
|
||||
#endif
|
||||
|
||||
} // namespace printing
|
||||
|
@ -80,8 +80,12 @@ PdfToEmfConverter::PdfToEmfConverter(
|
||||
PdfToEmfConverter::~PdfToEmfConverter() = default;
|
||||
|
||||
void PdfToEmfConverter::SetPrintMode() {
|
||||
chrome_pdf::SetPDFUseGDIPrinting(pdf_render_settings_.mode ==
|
||||
PdfRenderSettings::Mode::GDI_TEXT);
|
||||
bool use_gdi_printing =
|
||||
pdf_render_settings_.mode == PdfRenderSettings::Mode::GDI_TEXT ||
|
||||
pdf_render_settings_.mode ==
|
||||
PdfRenderSettings::Mode::EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT;
|
||||
chrome_pdf::SetPDFUseGDIPrinting(use_gdi_printing);
|
||||
|
||||
int printing_mode;
|
||||
switch (pdf_render_settings_.mode) {
|
||||
case PdfRenderSettings::Mode::TEXTONLY:
|
||||
@ -93,8 +97,11 @@ void PdfToEmfConverter::SetPrintMode() {
|
||||
case PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3:
|
||||
printing_mode = chrome_pdf::PrintingMode::kPostScript3;
|
||||
break;
|
||||
case PdfRenderSettings::Mode::EMF_WITH_REDUCED_RASTERIZATION:
|
||||
case PdfRenderSettings::Mode::EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT:
|
||||
printing_mode = chrome_pdf::PrintingMode::kEmfWithReducedRasterization;
|
||||
break;
|
||||
default:
|
||||
// Not using postscript or text only.
|
||||
printing_mode = chrome_pdf::PrintingMode::kEmf;
|
||||
}
|
||||
chrome_pdf::SetPDFUsePrintMode(printing_mode);
|
||||
|
@ -17,7 +17,11 @@ struct PdfRenderSettings {
|
||||
[EnableIf=is_win]
|
||||
POSTSCRIPT_LEVEL2,
|
||||
[EnableIf=is_win]
|
||||
POSTSCRIPT_LEVEL3
|
||||
POSTSCRIPT_LEVEL3,
|
||||
[EnableIf=is_win]
|
||||
EMF_WITH_REDUCED_RASTERIZATION,
|
||||
[EnableIf=is_win]
|
||||
EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT
|
||||
};
|
||||
|
||||
gfx.mojom.Rect area;
|
||||
|
@ -16,18 +16,24 @@ struct EnumTraits<printing::mojom::PdfRenderSettings::Mode,
|
||||
printing::PdfRenderSettings::Mode> {
|
||||
static printing::mojom::PdfRenderSettings::Mode ToMojom(
|
||||
printing::PdfRenderSettings::Mode mode) {
|
||||
using MojomMode = printing::mojom::PdfRenderSettings::Mode;
|
||||
using PrintMode = printing::PdfRenderSettings::Mode;
|
||||
switch (mode) {
|
||||
case printing::PdfRenderSettings::Mode::NORMAL:
|
||||
return printing::mojom::PdfRenderSettings::Mode::NORMAL;
|
||||
case PrintMode::NORMAL:
|
||||
return MojomMode::NORMAL;
|
||||
#if defined(OS_WIN)
|
||||
case printing::PdfRenderSettings::Mode::TEXTONLY:
|
||||
return printing::mojom::PdfRenderSettings::Mode::TEXTONLY;
|
||||
case printing::PdfRenderSettings::Mode::GDI_TEXT:
|
||||
return printing::mojom::PdfRenderSettings::Mode::GDI_TEXT;
|
||||
case printing::PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2:
|
||||
return printing::mojom::PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2;
|
||||
case printing::PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3:
|
||||
return printing::mojom::PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3;
|
||||
case PrintMode::TEXTONLY:
|
||||
return MojomMode::TEXTONLY;
|
||||
case PrintMode::GDI_TEXT:
|
||||
return MojomMode::GDI_TEXT;
|
||||
case PrintMode::POSTSCRIPT_LEVEL2:
|
||||
return MojomMode::POSTSCRIPT_LEVEL2;
|
||||
case PrintMode::POSTSCRIPT_LEVEL3:
|
||||
return MojomMode::POSTSCRIPT_LEVEL3;
|
||||
case PrintMode::EMF_WITH_REDUCED_RASTERIZATION:
|
||||
return MojomMode::EMF_WITH_REDUCED_RASTERIZATION;
|
||||
case PrintMode::EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT:
|
||||
return MojomMode::EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT;
|
||||
#endif
|
||||
}
|
||||
NOTREACHED() << "Unknown mode " << static_cast<int>(mode);
|
||||
@ -36,22 +42,30 @@ struct EnumTraits<printing::mojom::PdfRenderSettings::Mode,
|
||||
|
||||
static bool FromMojom(printing::mojom::PdfRenderSettings::Mode input,
|
||||
printing::PdfRenderSettings::Mode* output) {
|
||||
using MojomMode = printing::mojom::PdfRenderSettings::Mode;
|
||||
using PrintMode = printing::PdfRenderSettings::Mode;
|
||||
switch (input) {
|
||||
case printing::mojom::PdfRenderSettings::Mode::NORMAL:
|
||||
*output = printing::PdfRenderSettings::Mode::NORMAL;
|
||||
case MojomMode::NORMAL:
|
||||
*output = PrintMode::NORMAL;
|
||||
return true;
|
||||
#if defined(OS_WIN)
|
||||
case printing::mojom::PdfRenderSettings::Mode::TEXTONLY:
|
||||
*output = printing::PdfRenderSettings::Mode::TEXTONLY;
|
||||
case MojomMode::TEXTONLY:
|
||||
*output = PrintMode::TEXTONLY;
|
||||
return true;
|
||||
case printing::mojom::PdfRenderSettings::Mode::GDI_TEXT:
|
||||
*output = printing::PdfRenderSettings::Mode::GDI_TEXT;
|
||||
case MojomMode::GDI_TEXT:
|
||||
*output = PrintMode::GDI_TEXT;
|
||||
return true;
|
||||
case printing::mojom::PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2:
|
||||
*output = printing::PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2;
|
||||
case MojomMode::POSTSCRIPT_LEVEL2:
|
||||
*output = PrintMode::POSTSCRIPT_LEVEL2;
|
||||
return true;
|
||||
case printing::mojom::PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3:
|
||||
*output = printing::PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3;
|
||||
case MojomMode::POSTSCRIPT_LEVEL3:
|
||||
*output = PrintMode::POSTSCRIPT_LEVEL3;
|
||||
return true;
|
||||
case MojomMode::EMF_WITH_REDUCED_RASTERIZATION:
|
||||
*output = PrintMode::EMF_WITH_REDUCED_RASTERIZATION;
|
||||
return true;
|
||||
case MojomMode::EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT:
|
||||
*output = PrintMode::EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
@ -37,12 +37,16 @@ std::vector<uint8_t> CreateFlattenedPdf(base::span<const uint8_t> input_buffer);
|
||||
#endif // defined(OS_CHROMEOS)
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Printing modes - type to convert PDF to for printing
|
||||
// Printing modes - type to convert PDF to for printing. See PDFium's
|
||||
// FPDF_SetPrintMode() for details.
|
||||
enum PrintingMode {
|
||||
kEmf = 0,
|
||||
kTextOnly = 1,
|
||||
kPostScript2 = 2,
|
||||
kPostScript3 = 3,
|
||||
// Values 4 and 5 are similar to |kPostScript2| and |kPostScript3|, but are
|
||||
// not intended for use in sandboxed environments like Chromium's.
|
||||
kEmfWithReducedRasterization = 6,
|
||||
};
|
||||
|
||||
// |pdf_buffer| is the buffer that contains the entire PDF document to be
|
||||
|
@ -234,4 +234,6 @@ STATIC_ASSERT_ENUM(chrome_pdf::kEmf, FPDF_PRINTMODE_EMF);
|
||||
STATIC_ASSERT_ENUM(chrome_pdf::kTextOnly, FPDF_PRINTMODE_TEXTONLY);
|
||||
STATIC_ASSERT_ENUM(chrome_pdf::kPostScript2, FPDF_PRINTMODE_POSTSCRIPT2);
|
||||
STATIC_ASSERT_ENUM(chrome_pdf::kPostScript3, FPDF_PRINTMODE_POSTSCRIPT3);
|
||||
STATIC_ASSERT_ENUM(chrome_pdf::kEmfWithReducedRasterization,
|
||||
FPDF_PRINTMODE_EMF_IMAGE_MASKS);
|
||||
#endif
|
||||
|
@ -21,9 +21,11 @@ struct PdfRenderSettings {
|
||||
GDI_TEXT,
|
||||
POSTSCRIPT_LEVEL2,
|
||||
POSTSCRIPT_LEVEL3,
|
||||
LAST = POSTSCRIPT_LEVEL3,
|
||||
EMF_WITH_REDUCED_RASTERIZATION,
|
||||
EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT,
|
||||
LAST = EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT
|
||||
#else
|
||||
LAST = NORMAL,
|
||||
LAST = NORMAL
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -24,6 +24,10 @@ const base::Feature kEnableCustomMacPaperSizes{
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// When using GDI printing, avoid rasterization if possible.
|
||||
const base::Feature kPrintWithReducedRasterization{
|
||||
"PrintWithReducedRasterization", base::FEATURE_DISABLED_BY_DEFAULT};
|
||||
|
||||
// Use XPS for printing instead of GDI.
|
||||
const base::Feature kUseXpsForPrinting{"UseXpsForPrinting",
|
||||
base::FEATURE_DISABLED_BY_DEFAULT};
|
||||
|
@ -25,6 +25,7 @@ PRINTING_EXPORT extern const base::Feature kEnableCustomMacPaperSizes;
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
||||
#if defined(OS_WIN)
|
||||
PRINTING_EXPORT extern const base::Feature kPrintWithReducedRasterization;
|
||||
PRINTING_EXPORT extern const base::Feature kUseXpsForPrinting;
|
||||
PRINTING_EXPORT extern const base::Feature kUseXpsForPrintingFromPdf;
|
||||
|
||||
|
@ -130821,25 +130821,50 @@ reviews. Googlers can read more about this at go/gwsq-gerrit.
|
||||
</summary>
|
||||
</histogram>
|
||||
|
||||
<histogram name="Printing.ConversionSize.Emf" units="KB" expires_after="M90">
|
||||
<histogram name="Printing.ConversionSize.Emf" units="KB"
|
||||
expires_after="2021-04-30">
|
||||
<owner>thestig@chromium.org</owner>
|
||||
<owner>awscreen@chromium.org</owner>
|
||||
<summary>
|
||||
On Windows, the average size of a printed page after converting to EMF.
|
||||
</summary>
|
||||
</histogram>
|
||||
|
||||
<histogram name="Printing.ConversionSize.EmfWithGdiText" units="KB"
|
||||
expires_after="M90">
|
||||
expires_after="2021-04-30">
|
||||
<owner>thestig@chromium.org</owner>
|
||||
<owner>awscreen@chromium.org</owner>
|
||||
<summary>
|
||||
On Windows, the average size of a printed page after converting to EMF with
|
||||
the GDI Text experiment turned on.
|
||||
</summary>
|
||||
</histogram>
|
||||
|
||||
<histogram name="Printing.ConversionSize.PostScript2" units="KB"
|
||||
expires_after="M90">
|
||||
<histogram name="Printing.ConversionSize.EmfWithReducedRasterization"
|
||||
units="KB" expires_after="2021-04-30">
|
||||
<owner>thestig@chromium.org</owner>
|
||||
<owner>awscreen@chromium.org</owner>
|
||||
<summary>
|
||||
On Windows, the average size of a printed page after converting to EMF with
|
||||
the reduced rasterization feature turned on.
|
||||
</summary>
|
||||
</histogram>
|
||||
|
||||
<histogram name="Printing.ConversionSize.EmfWithReducedRasterizationAndGdiText"
|
||||
units="KB" expires_after="2021-04-30">
|
||||
<owner>thestig@chromium.org</owner>
|
||||
<owner>awscreen@chromium.org</owner>
|
||||
<summary>
|
||||
On Windows, the average size of a printed page after converting to EMF with
|
||||
the reduced rasterization feature turned on and the GDI Text experiment
|
||||
turned on.
|
||||
</summary>
|
||||
</histogram>
|
||||
|
||||
<histogram name="Printing.ConversionSize.PostScript2" units="KB"
|
||||
expires_after="2021-04-30">
|
||||
<owner>thestig@chromium.org</owner>
|
||||
<owner>awscreen@chromium.org</owner>
|
||||
<summary>
|
||||
On Windows, the average size of a printed page after converting to level 2
|
||||
PostScript.
|
||||
@ -130847,16 +130872,19 @@ reviews. Googlers can read more about this at go/gwsq-gerrit.
|
||||
</histogram>
|
||||
|
||||
<histogram name="Printing.ConversionSize.PostScript3" units="KB"
|
||||
expires_after="M90">
|
||||
expires_after="2021-04-30">
|
||||
<owner>thestig@chromium.org</owner>
|
||||
<owner>awscreen@chromium.org</owner>
|
||||
<summary>
|
||||
On Windows, the average size of a printed page after converting to level 3
|
||||
PostScript.
|
||||
</summary>
|
||||
</histogram>
|
||||
|
||||
<histogram name="Printing.ConversionSize.Pwg" units="KB" expires_after="M90">
|
||||
<histogram name="Printing.ConversionSize.Pwg" units="KB"
|
||||
expires_after="2021-04-30">
|
||||
<owner>thestig@chromium.org</owner>
|
||||
<owner>awscreen@chromium.org</owner>
|
||||
<summary>
|
||||
On desktop, the average size of a printed page after converting to PWG
|
||||
Raster format.
|
||||
|
Reference in New Issue
Block a user