Print Preview: Add option to rasterize PDFs and add JPEG compression.
Add checkbox to print preview to select rasterized PDF output. When selected, PDF will be rasterized and printed as a series of images. Images will be JPEG encoded. Preliminary design doc: https://docs.google.com/a/google.com/document/d/1UTzurMuPeRgx2PcnTMuAq5iM5_R2QBNGp-9lzgtwT2k/edit?usp=sharing Depends on http://crrev.com/2529543003 Linked to launch bug, should also resolve 534945,550205,480628 BUG=675798 CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:closure_compilation Review-Url: https://codereview.chromium.org/2524143003 Cr-Commit-Position: refs/heads/master@{#440897}
This commit is contained in:
chrome
components/printing
browser
common
renderer
content/renderer/pepper
pdf/pdfium
printing
print_job_constants.ccprint_job_constants.hprint_settings.hprint_settings_conversion.ccprinting_context.cc
testing/variations
third_party/WebKit/public/web
tools/metrics/histograms
@ -5155,7 +5155,13 @@ Keep your key file in a safe place. You will need it to create new versions of y
|
||||
"No-State Prefetch" pre-downloads resources to improve load times. "Prerender" does a full pre-rendering of the page, to improve load times even more. "Simple Load" does nothing and is similar to disabling the feature, but collects more metrics for comparison purposes.
|
||||
</message>
|
||||
|
||||
<!-- Print scaling feature -->
|
||||
<!-- Print Preview features -->
|
||||
<message name="IDS_FLAGS_PRINT_PDF_AS_IMAGE_NAME" desc="Name for the flag to add the option to print PDFs as images to print preview.">
|
||||
Print Pdf as Image
|
||||
</message>
|
||||
<message name="IDS_FLAGS_PRINT_PDF_AS_IMAGE_DESCRIPTION" desc="Description for the flag to add the option to print PDFs as images in print preview.">
|
||||
If enabled, an option to print PDF files as images will be available in print preview.
|
||||
</message>
|
||||
<message name="IDS_FLAGS_PRINT_SCALING_NAME" desc="Name for the flag to add the print scaling feature to print preview.">
|
||||
Print Scaling.
|
||||
</message>
|
||||
@ -8639,6 +8645,9 @@ I don't think this site should be blocked!
|
||||
<message name="IDS_PRINT_PREVIEW_OPTION_SELECTION_ONLY" desc="Checkbox label shown in print preview page to print only selected content.">
|
||||
Selection only
|
||||
</message>
|
||||
<message name="IDS_PRINT_PREVIEW_OPTION_RASTERIZE" desc="Checkbox label shown in print preview page to print PDF as an image (rasterize PDF).">
|
||||
Print as image
|
||||
</message>
|
||||
<message name="IDS_PRINT_PREVIEW_MARGINS_LABEL" desc="Margins option label. Provides user the option to change the margins of the printed page.">
|
||||
Margins
|
||||
</message>
|
||||
|
@ -2074,6 +2074,9 @@ const FeatureEntry kFeatureEntries[] = {
|
||||
features::kDisplayPersistenceToggleInPermissionPrompts)},
|
||||
#endif
|
||||
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||
{"print-pdf-as-image", IDS_FLAGS_PRINT_PDF_AS_IMAGE_NAME,
|
||||
IDS_FLAGS_PRINT_PDF_AS_IMAGE_DESCRIPTION, kOsDesktop,
|
||||
FEATURE_VALUE_TYPE(features::kPrintPdfAsImage)},
|
||||
{"print-scaling", IDS_FLAGS_PRINT_SCALING_NAME,
|
||||
IDS_FLAGS_PRINT_SCALING_DESCRIPTION, kOsDesktop,
|
||||
FEATURE_VALUE_TYPE(features::kPrintScaling)},
|
||||
|
@ -109,6 +109,14 @@ cr.define('print_preview', function() {
|
||||
this.pageRange_ =
|
||||
new print_preview.ticket_items.PageRange(this.documentInfo_);
|
||||
|
||||
/**
|
||||
* Rasterize PDF ticket item.
|
||||
* @type {!print_preview.ticket_items.Rasterize}
|
||||
* @private
|
||||
*/
|
||||
this.rasterize_ = new print_preview.ticket_items.Rasterize(
|
||||
this.destinationStore_, this.documentInfo_);
|
||||
|
||||
/**
|
||||
* Scaling ticket item.
|
||||
* @type {!print_preview.ticket_items.Scaling}
|
||||
@ -291,6 +299,10 @@ cr.define('print_preview', function() {
|
||||
return this.pageRange_;
|
||||
},
|
||||
|
||||
get rasterize() {
|
||||
return this.rasterize_;
|
||||
},
|
||||
|
||||
get scaling() {
|
||||
return this.scaling_;
|
||||
},
|
||||
|
@ -0,0 +1,50 @@
|
||||
// Copyright (c) 2016 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.
|
||||
|
||||
cr.define('print_preview.ticket_items', function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Rasterize ticket item whose value is a {@code boolean} that indicates
|
||||
* whether the PDF document should be rendered as images.
|
||||
* @constructor
|
||||
* @param {!print_preview.DocumentInfo} documentInfo Information about the
|
||||
* document to print, used to determine if document is a PDF.
|
||||
* @extends {print_preview.ticket_items.TicketItem}
|
||||
*/
|
||||
function Rasterize(destinationStore, documentInfo) {
|
||||
print_preview.ticket_items.TicketItem.call(
|
||||
this, null /* appState */, null /* field */,
|
||||
null /* destinationStore */, documentInfo);
|
||||
};
|
||||
|
||||
Rasterize.prototype = {
|
||||
__proto__: print_preview.ticket_items.TicketItem.prototype,
|
||||
|
||||
/** @override */
|
||||
wouldValueBeValid: function(value) {
|
||||
return true;
|
||||
},
|
||||
|
||||
/** @override */
|
||||
isCapabilityAvailable: function() {
|
||||
return !this.getDocumentInfoInternal().isModifiable;
|
||||
},
|
||||
|
||||
/** @override */
|
||||
getDefaultValueInternal: function() {
|
||||
return false;
|
||||
},
|
||||
|
||||
/** @override */
|
||||
getCapabilityNotAvailableValueInternal: function() {
|
||||
return this.getDefaultValueInternal();
|
||||
}
|
||||
};
|
||||
|
||||
// Export
|
||||
return {
|
||||
Rasterize: Rasterize
|
||||
};
|
||||
});
|
@ -288,6 +288,7 @@ cr.define('print_preview', function() {
|
||||
'generateDraftData': documentInfo.isModifiable,
|
||||
'fitToPageEnabled': printTicketStore.fitToPage.getValue(),
|
||||
'scaleFactor': printTicketStore.scaling.getValueAsNumber(),
|
||||
'rasterizePDF': printTicketStore.rasterize.getValue(),
|
||||
// NOTE: Even though the following fields don't directly relate to the
|
||||
// preview, they still need to be included.
|
||||
'duplex': printTicketStore.duplex.getValue() ?
|
||||
@ -367,6 +368,7 @@ cr.define('print_preview', function() {
|
||||
'printWithCloudPrint': !destination.isLocal,
|
||||
'printWithPrivet': destination.isPrivet,
|
||||
'printWithExtension': destination.isExtension,
|
||||
'rasterizePDF': printTicketStore.rasterize.getValue(),
|
||||
'scaleFactor': printTicketStore.scaling.getValueAsNumber(),
|
||||
'deviceName': destination.id,
|
||||
'isFirstRequest': false,
|
||||
|
@ -85,6 +85,13 @@ cr.define('print_preview', function() {
|
||||
*/
|
||||
this.colorValue_ = false;
|
||||
|
||||
/**
|
||||
* Whether the document should be printed as a raster PDF.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
this.rasterizeValue_ = false;
|
||||
|
||||
/**
|
||||
* Whether the document should be fitted to the page.
|
||||
* @type {boolean}
|
||||
@ -184,6 +191,7 @@ cr.define('print_preview', function() {
|
||||
this.isHeaderFooterEnabled_ =
|
||||
this.printTicketStore_.headerFooter.getValue();
|
||||
this.colorValue_ = this.printTicketStore_.color.getValue();
|
||||
this.rasterizeValue_ = this.printTicketStore_.rasterize.getValue();
|
||||
this.isFitToPageEnabled_ = this.printTicketStore_.fitToPage.getValue();
|
||||
this.scalingValue_ = this.printTicketStore_.scaling.getValueAsNumber();
|
||||
this.pageRanges_ = this.printTicketStore_.pageRange.getPageRanges();
|
||||
@ -284,6 +292,7 @@ cr.define('print_preview', function() {
|
||||
!ticketStore.landscape.isValueEqual(this.isLandscapeEnabled_) ||
|
||||
!ticketStore.headerFooter.isValueEqual(this.isHeaderFooterEnabled_) ||
|
||||
!ticketStore.color.isValueEqual(this.colorValue_) ||
|
||||
!ticketStore.rasterize.isValueEqual(this.rasterizeValue_) ||
|
||||
!ticketStore.scaling.isValueEqual(this.scalingValue_) ||
|
||||
!ticketStore.fitToPage.isValueEqual(this.isFitToPageEnabled_) ||
|
||||
this.pageRanges_ == null ||
|
||||
|
@ -337,6 +337,7 @@ cr.define('print_preview', function() {
|
||||
this.printTicketStore_.landscape,
|
||||
this.printTicketStore_.marginsType,
|
||||
this.printTicketStore_.pageRange,
|
||||
this.printTicketStore_.rasterize,
|
||||
this.printTicketStore_.selectionOnly,
|
||||
this.printTicketStore_.scaling
|
||||
].forEach(function(setting) {
|
||||
|
@ -188,7 +188,8 @@ cr.define('print_preview', function() {
|
||||
this.printTicketStore_.fitToPage,
|
||||
this.printTicketStore_.cssBackground,
|
||||
this.printTicketStore_.selectionOnly,
|
||||
this.printTicketStore_.headerFooter);
|
||||
this.printTicketStore_.headerFooter,
|
||||
this.printTicketStore_.rasterize);
|
||||
this.addChild(this.otherOptionsSettings_);
|
||||
|
||||
/**
|
||||
@ -1322,6 +1323,7 @@ cr.define('print_preview', function() {
|
||||
<include src="data/ticket_items/fit_to_page.js">
|
||||
<include src="data/ticket_items/css_background.js">
|
||||
<include src="data/ticket_items/selection_only.js">
|
||||
<include src="data/ticket_items/rasterize.js">
|
||||
<include src="data/ticket_items/vendor_items.js">
|
||||
|
||||
<include src="native_layer.js">
|
||||
|
@ -29,6 +29,12 @@
|
||||
<span>$i18n{optionBackgroundColorsAndImages}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div id="rasterize-container">
|
||||
<label aria-live="polite">
|
||||
<input class="checkbox" type="checkbox">
|
||||
<span>$i18n{optionRasterize}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div id="selection-only-container">
|
||||
<label aria-live="polite">
|
||||
<input class="checkbox" type="checkbox">
|
||||
|
@ -127,30 +127,42 @@ cr.define('print_preview', function() {
|
||||
* only ticket item.
|
||||
* @param {!print_preview.ticket_items.HeaderFooter} headerFooter Header
|
||||
* footer ticket item.
|
||||
* @param {!print_preview.ticket_items.Rasterize} rasterize Rasterize ticket
|
||||
* item.
|
||||
* @constructor
|
||||
* @extends {print_preview.SettingsSection}
|
||||
*/
|
||||
function OtherOptionsSettings(
|
||||
duplex, fitToPage, cssBackground, selectionOnly, headerFooter) {
|
||||
duplex, fitToPage, cssBackground, selectionOnly, headerFooter,
|
||||
rasterize) {
|
||||
print_preview.SettingsSection.call(this);
|
||||
/**
|
||||
* @private {boolean} rasterizeEnabled Whether the print as image feature is
|
||||
* enabled.
|
||||
*/
|
||||
this.rasterizeEnabled_ = loadTimeData.getBoolean('printPdfAsImageEnabled');
|
||||
|
||||
/*
|
||||
/**
|
||||
* @private {!Array<!CheckboxTicketItemElement>} checkbox ticket item
|
||||
* elements representing the different options in the section.
|
||||
* Selection only must always be the last element in the array.
|
||||
*/
|
||||
this.elements_ = [
|
||||
new CheckboxTicketItemElement(headerFooter, true,
|
||||
'header-footer-container'),
|
||||
new CheckboxTicketItemElement(fitToPage, false,
|
||||
'fit-to-page-container'),
|
||||
new CheckboxTicketItemElement(duplex, false, 'duplex-container'),
|
||||
new CheckboxTicketItemElement(cssBackground, true,
|
||||
'css-background-container'),
|
||||
new CheckboxTicketItemElement(selectionOnly, true,
|
||||
'selection-only-container')
|
||||
new CheckboxTicketItemElement(headerFooter, true,
|
||||
'header-footer-container'),
|
||||
new CheckboxTicketItemElement(fitToPage, false,
|
||||
'fit-to-page-container'),
|
||||
new CheckboxTicketItemElement(duplex, false, 'duplex-container'),
|
||||
new CheckboxTicketItemElement(cssBackground, true,
|
||||
'css-background-container'),
|
||||
new CheckboxTicketItemElement(selectionOnly, true,
|
||||
'selection-only-container')
|
||||
];
|
||||
|
||||
if (this.rasterizeEnabled_) {
|
||||
this.elements_.splice(4, 0,
|
||||
new CheckboxTicketItemElement(rasterize, true,
|
||||
'rasterize-container'));
|
||||
}
|
||||
};
|
||||
|
||||
OtherOptionsSettings.prototype = {
|
||||
@ -206,6 +218,7 @@ cr.define('print_preview', function() {
|
||||
decorateInternal: function() {
|
||||
for (var i = 0; i < this.elements_.length; i++)
|
||||
this.elements_[i].decorate();
|
||||
$('rasterize-container').hidden = !this.rasterizeEnabled_;
|
||||
},
|
||||
|
||||
/** @override */
|
||||
|
@ -142,6 +142,7 @@ enum PrintSettingsBuckets {
|
||||
NON_DEFAULT_MARGINS,
|
||||
DISTILL_PAGE_UNUSED,
|
||||
SCALING,
|
||||
PRINT_AS_IMAGE,
|
||||
PRINT_SETTINGS_BUCKET_BOUNDARY
|
||||
};
|
||||
|
||||
@ -289,6 +290,12 @@ void ReportPrintSettingsStats(const base::DictionaryValue& settings) {
|
||||
&external_preview) && external_preview) {
|
||||
ReportPrintSettingHistogram(EXTERNAL_PDF_PREVIEW);
|
||||
}
|
||||
|
||||
bool rasterize = false;
|
||||
if (settings.GetBoolean(printing::kSettingRasterizePdf,
|
||||
&rasterize) && rasterize) {
|
||||
ReportPrintSettingHistogram(PRINT_AS_IMAGE);
|
||||
}
|
||||
}
|
||||
|
||||
// Callback that stores a PDF file on disk.
|
||||
|
@ -278,6 +278,8 @@ content::WebUIDataSource* CreatePrintPreviewUISource() {
|
||||
IDS_PRINT_PREVIEW_OPTION_BACKGROUND_COLORS_AND_IMAGES);
|
||||
source->AddLocalizedString("optionSelectionOnly",
|
||||
IDS_PRINT_PREVIEW_OPTION_SELECTION_ONLY);
|
||||
source->AddLocalizedString("optionRasterize",
|
||||
IDS_PRINT_PREVIEW_OPTION_RASTERIZE);
|
||||
source->AddLocalizedString("marginsLabel", IDS_PRINT_PREVIEW_MARGINS_LABEL);
|
||||
source->AddLocalizedString("defaultMargins",
|
||||
IDS_PRINT_PREVIEW_DEFAULT_MARGINS);
|
||||
@ -410,6 +412,10 @@ content::WebUIDataSource* CreatePrintPreviewUISource() {
|
||||
bool scaling_enabled = base::FeatureList::IsEnabled(features::kPrintScaling);
|
||||
source->AddBoolean("scalingEnabled", scaling_enabled);
|
||||
|
||||
bool print_pdf_as_image_enabled = base::FeatureList::IsEnabled(
|
||||
features::kPrintPdfAsImage);
|
||||
source->AddBoolean("printPdfAsImageEnabled", print_pdf_as_image_enabled);
|
||||
|
||||
#if defined(OS_CHROMEOS)
|
||||
bool cups_and_md_settings_enabled =
|
||||
base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
|
@ -169,6 +169,9 @@ const base::Feature kPreferHtmlOverPlugins{"PreferHtmlOverPlugins",
|
||||
|
||||
// Enables the Print Scaling feature in print preview.
|
||||
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||
const base::Feature kPrintPdfAsImage{"PrintPdfAsImage",
|
||||
base::FEATURE_DISABLED_BY_DEFAULT};
|
||||
|
||||
const base::Feature kPrintScaling{"PrintScaling",
|
||||
base::FEATURE_DISABLED_BY_DEFAULT};
|
||||
#endif
|
||||
|
@ -100,6 +100,8 @@ extern const base::Feature kPreferHtmlOverPlugins;
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
|
||||
extern const base::Feature kPrintPdfAsImage;
|
||||
|
||||
extern const base::Feature kPrintScaling;
|
||||
#endif
|
||||
|
||||
|
@ -61,12 +61,16 @@ PrintPreviewWebUITest.prototype = {
|
||||
* @override
|
||||
*/
|
||||
testGenPreamble: function() {
|
||||
// Enable print scaling for tests.
|
||||
// Enable print scaling and print as image for tests.
|
||||
GEN(' base::FeatureList::ClearInstanceForTesting();');
|
||||
GEN(' std::unique_ptr<base::FeatureList>');
|
||||
GEN(' feature_list(new base::FeatureList);');
|
||||
GEN(' char enabled_features[128] = {0};');
|
||||
GEN(' strcpy(enabled_features, features::kPrintScaling.name);');
|
||||
GEN(' strcat(strcat(enabled_features, ","), ');
|
||||
GEN(' features::kPrintPdfAsImage.name);');
|
||||
GEN(' feature_list->InitializeFromCommandLine(');
|
||||
GEN(' features::kPrintScaling.name, std::string());');
|
||||
GEN(' enabled_features, std::string());');
|
||||
GEN(' base::FeatureList::SetInstance(std::move(feature_list));');
|
||||
},
|
||||
|
||||
@ -519,7 +523,11 @@ TEST_F('PrintPreviewWebUITest', 'PrintToPDFSelectedCapabilities', function() {
|
||||
this.setCapabilities(device);
|
||||
|
||||
var otherOptions = $('other-options-settings');
|
||||
checkSectionVisible(otherOptions, false);
|
||||
checkSectionVisible(otherOptions, true);
|
||||
checkElementDisplayed(
|
||||
otherOptions.querySelector('#fit-to-page-container'), false);
|
||||
checkElementDisplayed(
|
||||
otherOptions.querySelector('#rasterize-container'), true);
|
||||
checkSectionVisible($('media-size-settings'), false);
|
||||
checkSectionVisible($('scaling-settings'), false);
|
||||
|
||||
@ -535,6 +543,7 @@ TEST_F('PrintPreviewWebUITest', 'SourceIsHTMLCapabilities', function() {
|
||||
|
||||
var otherOptions = $('other-options-settings');
|
||||
var fitToPage = otherOptions.querySelector('#fit-to-page-container');
|
||||
var rasterize = otherOptions.querySelector('#rasterize-container');
|
||||
var mediaSize = $('media-size-settings');
|
||||
var scalingSettings = $('scaling-settings');
|
||||
|
||||
@ -542,12 +551,14 @@ TEST_F('PrintPreviewWebUITest', 'SourceIsHTMLCapabilities', function() {
|
||||
// available).
|
||||
checkSectionVisible(otherOptions, true);
|
||||
checkElementDisplayed(fitToPage, false);
|
||||
checkElementDisplayed(rasterize, false);
|
||||
checkSectionVisible(mediaSize, false);
|
||||
checkSectionVisible(scalingSettings, false);
|
||||
|
||||
this.expandMoreSettings();
|
||||
|
||||
checkElementDisplayed(fitToPage, false);
|
||||
checkElementDisplayed(rasterize, false);
|
||||
checkSectionVisible(mediaSize, true);
|
||||
checkSectionVisible(scalingSettings, true);
|
||||
|
||||
@ -566,12 +577,18 @@ TEST_F('PrintPreviewWebUITest', 'SourceIsPDFCapabilities', function() {
|
||||
var scalingSettings = $('scaling-settings');
|
||||
var fitToPageContainer =
|
||||
otherOptions.querySelector('#fit-to-page-container');
|
||||
var rasterizeContainer =
|
||||
otherOptions.querySelector('#rasterize-container');
|
||||
|
||||
checkSectionVisible(otherOptions, true);
|
||||
checkElementDisplayed(fitToPageContainer, true);
|
||||
checkElementDisplayed(rasterizeContainer, false);
|
||||
expectTrue(
|
||||
fitToPageContainer.querySelector('.checkbox').checked);
|
||||
this.expandMoreSettings();
|
||||
checkElementDisplayed(rasterizeContainer, true);
|
||||
expectFalse(
|
||||
rasterizeContainer.querySelector('.checkbox').checked);
|
||||
checkSectionVisible($('media-size-settings'), true);
|
||||
checkSectionVisible(scalingSettings, true);
|
||||
|
||||
|
@ -25,6 +25,7 @@ void RenderParamsFromPrintSettings(const PrintSettings& settings,
|
||||
params->scale_factor = settings.scale_factor();
|
||||
// Currently hardcoded at 72dpi. See PrintSettings' constructor.
|
||||
params->desired_dpi = settings.desired_dpi();
|
||||
params->rasterize_pdf = settings.rasterize_pdf();
|
||||
// Always use an invalid cookie.
|
||||
params->document_cookie = 0;
|
||||
params->selection_only = settings.selection_only();
|
||||
|
@ -42,26 +42,27 @@ namespace IPC {
|
||||
} // namespace IPC
|
||||
|
||||
PrintMsg_Print_Params::PrintMsg_Print_Params()
|
||||
: page_size(),
|
||||
content_size(),
|
||||
printable_area(),
|
||||
margin_top(0),
|
||||
margin_left(0),
|
||||
dpi(0),
|
||||
scale_factor(1.0f),
|
||||
desired_dpi(0),
|
||||
document_cookie(0),
|
||||
selection_only(false),
|
||||
supports_alpha_blend(false),
|
||||
preview_ui_id(-1),
|
||||
preview_request_id(0),
|
||||
is_first_request(false),
|
||||
print_scaling_option(blink::WebPrintScalingOptionSourceSize),
|
||||
print_to_pdf(false),
|
||||
display_header_footer(false),
|
||||
title(),
|
||||
url(),
|
||||
should_print_backgrounds(false) {}
|
||||
: page_size(),
|
||||
content_size(),
|
||||
printable_area(),
|
||||
margin_top(0),
|
||||
margin_left(0),
|
||||
dpi(0),
|
||||
scale_factor(1.0f),
|
||||
desired_dpi(0),
|
||||
rasterize_pdf(false),
|
||||
document_cookie(0),
|
||||
selection_only(false),
|
||||
supports_alpha_blend(false),
|
||||
preview_ui_id(-1),
|
||||
preview_request_id(0),
|
||||
is_first_request(false),
|
||||
print_scaling_option(blink::WebPrintScalingOptionSourceSize),
|
||||
print_to_pdf(false),
|
||||
display_header_footer(false),
|
||||
title(),
|
||||
url(),
|
||||
should_print_backgrounds(false) {}
|
||||
|
||||
PrintMsg_Print_Params::PrintMsg_Print_Params(
|
||||
const PrintMsg_Print_Params& other) = default;
|
||||
@ -77,6 +78,7 @@ void PrintMsg_Print_Params::Reset() {
|
||||
dpi = 0;
|
||||
scale_factor = 1.0f;
|
||||
desired_dpi = 0;
|
||||
rasterize_pdf = false;
|
||||
document_cookie = 0;
|
||||
selection_only = false;
|
||||
supports_alpha_blend = false;
|
||||
|
@ -47,6 +47,7 @@ struct PrintMsg_Print_Params {
|
||||
double dpi;
|
||||
double scale_factor;
|
||||
int desired_dpi;
|
||||
bool rasterize_pdf;
|
||||
int document_cookie;
|
||||
bool selection_only;
|
||||
bool supports_alpha_blend;
|
||||
@ -128,6 +129,9 @@ IPC_STRUCT_TRAITS_BEGIN(PrintMsg_Print_Params)
|
||||
// Desired apparent dpi on paper.
|
||||
IPC_STRUCT_TRAITS_MEMBER(desired_dpi)
|
||||
|
||||
// Whether to rasterize a PDF for printing
|
||||
IPC_STRUCT_TRAITS_MEMBER(rasterize_pdf)
|
||||
|
||||
// Cookie for the document to ensure correctness.
|
||||
IPC_STRUCT_TRAITS_MEMBER(document_cookie)
|
||||
|
||||
|
@ -286,6 +286,7 @@ void ComputeWebKitPrintParamsInDesiredDpi(
|
||||
blink::WebPrintParams* webkit_print_params) {
|
||||
int dpi = GetDPI(&print_params);
|
||||
webkit_print_params->printerDPI = dpi;
|
||||
webkit_print_params->rasterizePDF = print_params.rasterize_pdf;
|
||||
webkit_print_params->printScalingOption = print_params.print_scaling_option;
|
||||
|
||||
webkit_print_params->printContentArea.width = ConvertUnit(
|
||||
|
@ -1765,23 +1765,31 @@ void PepperPluginInstanceImpl::ReportGeometry() {
|
||||
}
|
||||
|
||||
bool PepperPluginInstanceImpl::GetPreferredPrintOutputFormat(
|
||||
PP_PrintOutputFormat_Dev* format) {
|
||||
PP_PrintOutputFormat_Dev* format,
|
||||
const WebPrintParams& print_params) {
|
||||
// Keep a reference on the stack. See NOTE above.
|
||||
scoped_refptr<PepperPluginInstanceImpl> ref(this);
|
||||
if (!LoadPrintInterface())
|
||||
return false;
|
||||
uint32_t supported_formats =
|
||||
plugin_print_interface_->QuerySupportedFormats(pp_instance());
|
||||
if (supported_formats & PP_PRINTOUTPUTFORMAT_PDF) {
|
||||
if ((supported_formats & PP_PRINTOUTPUTFORMAT_PDF) &&
|
||||
!print_params.rasterizePDF) {
|
||||
*format = PP_PRINTOUTPUTFORMAT_PDF;
|
||||
return true;
|
||||
}
|
||||
if (supported_formats & PP_PRINTOUTPUTFORMAT_RASTER) {
|
||||
*format = PP_PRINTOUTPUTFORMAT_RASTER;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PepperPluginInstanceImpl::SupportsPrintInterface() {
|
||||
PP_PrintOutputFormat_Dev format;
|
||||
return GetPreferredPrintOutputFormat(&format);
|
||||
WebPrintParams params;
|
||||
params.rasterizePDF = false;
|
||||
return GetPreferredPrintOutputFormat(&format, params);
|
||||
}
|
||||
|
||||
bool PepperPluginInstanceImpl::IsPrintScalingDisabled() {
|
||||
@ -1795,7 +1803,7 @@ int PepperPluginInstanceImpl::PrintBegin(const WebPrintParams& print_params) {
|
||||
// Keep a reference on the stack. See NOTE above.
|
||||
scoped_refptr<PepperPluginInstanceImpl> ref(this);
|
||||
PP_PrintOutputFormat_Dev format;
|
||||
if (!GetPreferredPrintOutputFormat(&format)) {
|
||||
if (!GetPreferredPrintOutputFormat(&format, print_params)) {
|
||||
// PrintBegin should not have been called since SupportsPrintInterface
|
||||
// would have returned false;
|
||||
NOTREACHED();
|
||||
@ -1857,7 +1865,8 @@ void PepperPluginInstanceImpl::PrintPageHelper(
|
||||
if (!print_output)
|
||||
return;
|
||||
|
||||
if (current_print_settings_.format == PP_PRINTOUTPUTFORMAT_PDF)
|
||||
if (current_print_settings_.format == PP_PRINTOUTPUTFORMAT_PDF ||
|
||||
current_print_settings_.format == PP_PRINTOUTPUTFORMAT_RASTER)
|
||||
PrintPDFOutput(print_output, metafile);
|
||||
|
||||
// Now we need to release the print output resource.
|
||||
|
@ -647,7 +647,8 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
|
||||
// Queries the plugin for supported print formats and sets |format| to the
|
||||
// best format to use. Returns false if the plugin does not support any
|
||||
// print format that we can handle (we can handle only PDF).
|
||||
bool GetPreferredPrintOutputFormat(PP_PrintOutputFormat_Dev* format);
|
||||
bool GetPreferredPrintOutputFormat(PP_PrintOutputFormat_Dev* format,
|
||||
const blink::WebPrintParams& params);
|
||||
bool PrintPDFOutput(PP_Resource print_output,
|
||||
printing::PdfMetafileSkia* metafile);
|
||||
|
||||
|
@ -5,4 +5,5 @@ include_rules = [
|
||||
"+printing/units.h",
|
||||
"+third_party/pdfium/public",
|
||||
"+ui/gfx/geometry/rect.h",
|
||||
"+ui/gfx/codec/jpeg_codec.h",
|
||||
]
|
||||
|
@ -57,6 +57,7 @@
|
||||
#include "third_party/pdfium/public/fpdf_transformpage.h"
|
||||
#include "third_party/pdfium/public/fpdfview.h"
|
||||
#include "ui/events/keycodes/keyboard_codes.h"
|
||||
#include "ui/gfx/codec/jpeg_codec.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
@ -617,6 +618,17 @@ void TearDownV8() {
|
||||
g_isolate_holder = nullptr;
|
||||
}
|
||||
|
||||
int GetBlockForJpeg(void* param,
|
||||
unsigned long pos,
|
||||
unsigned char* buf,
|
||||
unsigned long size) {
|
||||
std::vector<uint8_t>* data_vector = static_cast<std::vector<uint8_t>*>(param);
|
||||
if (pos + size < pos || pos + size > data_vector->size())
|
||||
return 0;
|
||||
memcpy(buf, data_vector->data() + pos, size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool InitializeSDK() {
|
||||
@ -1353,9 +1365,11 @@ bool PDFiumEngine::HandleEvent(const pp::InputEvent& event) {
|
||||
}
|
||||
|
||||
uint32_t PDFiumEngine::QuerySupportedPrintOutputFormats() {
|
||||
if (!HasPermission(PDFEngine::PERMISSION_PRINT_LOW_QUALITY))
|
||||
return 0;
|
||||
return PP_PRINTOUTPUTFORMAT_PDF;
|
||||
if (HasPermission(PDFEngine::PERMISSION_PRINT_HIGH_QUALITY))
|
||||
return PP_PRINTOUTPUTFORMAT_PDF | PP_PRINTOUTPUTFORMAT_RASTER;
|
||||
if (HasPermission(PDFEngine::PERMISSION_PRINT_LOW_QUALITY))
|
||||
return PP_PRINTOUTPUTFORMAT_RASTER;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PDFiumEngine::PrintBegin() {
|
||||
@ -1366,10 +1380,13 @@ pp::Resource PDFiumEngine::PrintPages(
|
||||
const PP_PrintPageNumberRange_Dev* page_ranges, uint32_t page_range_count,
|
||||
const PP_PrintSettings_Dev& print_settings) {
|
||||
ScopedSubstFont scoped_subst_font(this);
|
||||
if (HasPermission(PDFEngine::PERMISSION_PRINT_HIGH_QUALITY))
|
||||
if (HasPermission(PDFEngine::PERMISSION_PRINT_HIGH_QUALITY) &&
|
||||
(print_settings.format & PP_PRINTOUTPUTFORMAT_PDF)) {
|
||||
return PrintPagesAsPDF(page_ranges, page_range_count, print_settings);
|
||||
else if (HasPermission(PDFEngine::PERMISSION_PRINT_LOW_QUALITY))
|
||||
} else if (HasPermission(PDFEngine::PERMISSION_PRINT_LOW_QUALITY)) {
|
||||
return PrintPagesAsRasterPDF(page_ranges, page_range_count, print_settings);
|
||||
}
|
||||
|
||||
return pp::Resource();
|
||||
}
|
||||
|
||||
@ -1412,6 +1429,8 @@ FPDF_DOCUMENT PDFiumEngine::CreateSinglePageRasterPdf(
|
||||
print_settings.orientation,
|
||||
FPDF_ANNOT | FPDF_PRINTING | FPDF_NO_CATCH);
|
||||
|
||||
unsigned char* bitmap_data =
|
||||
static_cast<unsigned char*>(FPDFBitmap_GetBuffer(bitmap));
|
||||
double ratio_x = ConvertUnitDouble(bitmap_size.width(),
|
||||
print_settings.dpi,
|
||||
kPointsPerInch);
|
||||
@ -1422,7 +1441,25 @@ FPDF_DOCUMENT PDFiumEngine::CreateSinglePageRasterPdf(
|
||||
// Add the bitmap to an image object and add the image object to the output
|
||||
// page.
|
||||
FPDF_PAGEOBJECT temp_img = FPDFPageObj_NewImgeObj(temp_doc);
|
||||
FPDFImageObj_SetBitmap(&temp_page, 1, temp_img, bitmap);
|
||||
|
||||
std::vector<uint8_t> compressed_bitmap_data;
|
||||
int quality = 40;
|
||||
if (!(print_settings.format & PP_PRINTOUTPUTFORMAT_PDF) &&
|
||||
(gfx::JPEGCodec::Encode(
|
||||
bitmap_data, gfx::JPEGCodec::FORMAT_BGRA, FPDFBitmap_GetWidth(bitmap),
|
||||
FPDFBitmap_GetHeight(bitmap), FPDFBitmap_GetStride(bitmap), quality,
|
||||
&compressed_bitmap_data))) {
|
||||
FPDF_FILEACCESS file_access = {};
|
||||
file_access.m_FileLen =
|
||||
static_cast<unsigned long>(compressed_bitmap_data.size());
|
||||
file_access.m_GetBlock = &GetBlockForJpeg;
|
||||
file_access.m_Param = &compressed_bitmap_data;
|
||||
|
||||
FPDFImageObj_LoadJpegFileInline(&temp_page, 1, temp_img, &file_access);
|
||||
} else {
|
||||
FPDFImageObj_SetBitmap(&temp_page, 1, temp_img, bitmap);
|
||||
}
|
||||
|
||||
FPDFImageObj_SetMatrix(temp_img, ratio_x, 0, 0, ratio_y, 0, 0);
|
||||
FPDFPage_InsertObject(temp_page, temp_img);
|
||||
FPDFPage_GenerateContent(temp_page);
|
||||
|
@ -172,6 +172,9 @@ const char kSettingPrintWithExtension[] = "printWithExtension";
|
||||
// Scaling factor
|
||||
const char kSettingScaleFactor[] = "scaleFactor";
|
||||
|
||||
// Scaling factor
|
||||
const char kSettingRasterizePdf[] = "rasterizePDF";
|
||||
|
||||
// Ticket option. Contains the ticket in CJT format.
|
||||
const char kSettingTicket[] = "ticket";
|
||||
|
||||
|
@ -65,6 +65,7 @@ PRINTING_EXPORT extern const char kSettingPrintableAreaY[];
|
||||
PRINTING_EXPORT extern const char kSettingPrinterDescription[];
|
||||
PRINTING_EXPORT extern const char kSettingPrinterName[];
|
||||
PRINTING_EXPORT extern const char kSettingPrinterOptions[];
|
||||
PRINTING_EXPORT extern const char kSettingRasterizePdf[];
|
||||
PRINTING_EXPORT extern const char kSettingScaleFactor[];
|
||||
PRINTING_EXPORT extern const char kSettingTicket[];
|
||||
PRINTING_EXPORT extern const char kSettingShouldPrintBackgrounds[];
|
||||
|
@ -96,6 +96,9 @@ class PRINTING_EXPORT PrintSettings {
|
||||
void set_scale_factor(double scale_factor) { scale_factor_ = scale_factor; }
|
||||
double scale_factor() const { return scale_factor_; }
|
||||
|
||||
void set_rasterize_pdf(bool rasterize_pdf) { rasterize_pdf_ = rasterize_pdf; }
|
||||
bool rasterize_pdf() const { return rasterize_pdf_; }
|
||||
|
||||
void set_supports_alpha_blend(bool supports_alpha_blend) {
|
||||
supports_alpha_blend_ = supports_alpha_blend;
|
||||
}
|
||||
@ -212,6 +215,9 @@ class PRINTING_EXPORT PrintSettings {
|
||||
// Scale factor
|
||||
double scale_factor_;
|
||||
|
||||
// True if PDF should be printed as a raster PDF
|
||||
bool rasterize_pdf_;
|
||||
|
||||
// Is the orientation landscape or portrait.
|
||||
bool landscape_;
|
||||
|
||||
|
@ -177,6 +177,7 @@ bool PrintSettingsFromJobSettings(const base::DictionaryValue& job_settings,
|
||||
bool collate = false;
|
||||
int copies = 1;
|
||||
int scale_factor = 100;
|
||||
bool rasterize_pdf = false;
|
||||
|
||||
if (!job_settings.GetBoolean(kSettingCollate, &collate) ||
|
||||
!job_settings.GetInteger(kSettingCopies, &copies) ||
|
||||
@ -184,7 +185,8 @@ bool PrintSettingsFromJobSettings(const base::DictionaryValue& job_settings,
|
||||
!job_settings.GetInteger(kSettingDuplexMode, &duplex_mode) ||
|
||||
!job_settings.GetBoolean(kSettingLandscape, &landscape) ||
|
||||
!job_settings.GetString(kSettingDeviceName, &device_name) ||
|
||||
!job_settings.GetInteger(kSettingScaleFactor, &scale_factor)) {
|
||||
!job_settings.GetInteger(kSettingScaleFactor, &scale_factor) ||
|
||||
!job_settings.GetBoolean(kSettingRasterizePdf, &rasterize_pdf)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -195,7 +197,7 @@ bool PrintSettingsFromJobSettings(const base::DictionaryValue& job_settings,
|
||||
settings->set_duplex_mode(static_cast<DuplexMode>(duplex_mode));
|
||||
settings->set_color(static_cast<ColorModel>(color));
|
||||
settings->set_scale_factor(static_cast<double>(scale_factor) / 100.0);
|
||||
|
||||
settings->set_rasterize_pdf(rasterize_pdf);
|
||||
#if defined(OS_WIN)
|
||||
// Modifiable implies HTML and not other formats like PDF.
|
||||
bool can_modify = false;
|
||||
|
@ -73,6 +73,7 @@ PrintingContext::Result PrintingContext::UsePdfSettings() {
|
||||
pdf_settings->SetBoolean(kSettingPrintWithPrivet, false);
|
||||
pdf_settings->SetBoolean(kSettingPrintWithExtension, false);
|
||||
pdf_settings->SetInteger(kSettingScaleFactor, 100);
|
||||
pdf_settings->SetBoolean(kSettingRasterizePdf, false);
|
||||
return UpdatePrintSettings(*pdf_settings);
|
||||
}
|
||||
|
||||
|
@ -1595,6 +1595,24 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"PrintPdfAsImage": [
|
||||
{
|
||||
"platforms": [
|
||||
"chromeos",
|
||||
"linux",
|
||||
"mac",
|
||||
"win"
|
||||
],
|
||||
"experiments": [
|
||||
{
|
||||
"name": "Enabled",
|
||||
"enable_features": [
|
||||
"PrintPdfAsImage"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PrintScaling": [
|
||||
{
|
||||
"platforms": [
|
||||
|
@ -51,6 +51,9 @@ struct WebPrintParams {
|
||||
// Specifies user selected DPI for printing.
|
||||
int printerDPI;
|
||||
|
||||
// Specifies whether to print PDFs as image.
|
||||
bool rasterizePDF = false;
|
||||
|
||||
// Specifies whether to reduce/enlarge/retain the print contents to fit the
|
||||
// printable area. (This is used only by plugin printing).
|
||||
WebPrintScalingOption printScalingOption;
|
||||
|
@ -93987,6 +93987,7 @@ value.
|
||||
<int value="147373243" label="enable-deferred-image-decoding"/>
|
||||
<int value="157217034" label="enable-tab-for-desktop-share"/>
|
||||
<int value="157318016" label="AutomaticTabDiscarding:enabled"/>
|
||||
<int value="173288154" label="PrintPdfAsImage:enabled"/>
|
||||
<int value="178337215" label="enable-md-history"/>
|
||||
<int value="180074362" label="memory-pressure-thresholds"/>
|
||||
<int value="189728101" label="FasterLocationReload:disabled"/>
|
||||
@ -94078,9 +94079,11 @@ value.
|
||||
<int value="606512202" label="AutofillCreditCardPopupLayout:enabled"/>
|
||||
<int value="609112512" label="touch-selection-strategy"/>
|
||||
<int value="610545308" label="enable-potentially-annoying-security-features"/>
|
||||
<int value="624317932" label="print-pdf-as-image"/>
|
||||
<int value="625273056" label="disable-boot-animation"/>
|
||||
<int value="628302973" label="NTPSnippets:enabled"/>
|
||||
<int value="630947363" label="touch-events"/>
|
||||
<int value="635971109" label="PrintPdfAsImage:disabled"/>
|
||||
<int value="636425179" label="mhtml-generator-option"/>
|
||||
<int value="637396292" label="AllBookmarks:enabled"/>
|
||||
<int value="643725031" label="disable-touch-feedback"/>
|
||||
@ -100023,6 +100026,7 @@ value.
|
||||
<int value="16" label="NON_DEFAULT_MARGINS"/>
|
||||
<int value="17" label="DISTILL_PAGE_UNUSED"/>
|
||||
<int value="18" label="SCALING"/>
|
||||
<int value="19" label="PRINT_AS_IMAGE"/>
|
||||
</enum>
|
||||
|
||||
<enum name="PrivetNotificationsEvent" type="int">
|
||||
|
Reference in New Issue
Block a user