0

Add kPrintWithPostScriptType42Fonts feature.

Add an off by default base::Feature for controlling whether PostScript
printing generates Type 42 fonts on Windows. This will speed up printing
for some printers that support PostScript level 3 and have a TrueType
rasterizer. Since this feature is experimental, 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 mode.
- New Printing.ConversionSize metrics to see how the new printing modes
  perform size-wise.
- A very basic sanity test.
- Control for the feature in chrome://flags.
- Control for the feature via an enterprise policy.

Also fix another Windows-only printing enterprise policy to use
"MS_WIN_NAME" when referring to Windows.

Bug: 1232526
Change-Id: I4f3a333e6c83fb56d4482c8aa3af4fcc6b8533dc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3150776
Reviewed-by: Julian Pastarmov <pastarmovj@chromium.org>
Reviewed-by: Zentaro Kavanagh <zentaro@chromium.org>
Reviewed-by: danakj <danakj@chromium.org>
Reviewed-by: Alan Screen <awscreen@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/main@{#919845}
This commit is contained in:
Lei Zhang
2021-09-09 17:04:44 +00:00
committed by Chromium LUCI CQ
parent b8fdc13665
commit 1419caba51
23 changed files with 205 additions and 18 deletions

@ -5066,6 +5066,11 @@ const FeatureEntry kFeatureEntries[] = {
#endif // defined(OS_MAC)
#if defined(OS_WIN)
{"print-with-postscript-type42-fonts",
flag_descriptions::kPrintWithPostScriptType42FontsName,
flag_descriptions::kPrintWithPostScriptType42FontsDescription, kOsWin,
FEATURE_VALUE_TYPE(printing::features::kPrintWithPostScriptType42Fonts)},
{"print-with-reduced-rasterization",
flag_descriptions::kPrintWithReducedRasterizationName,
flag_descriptions::kPrintWithReducedRasterizationDescription, kOsWin,

@ -4569,6 +4569,11 @@
"owners": [ "chromeos-camera-eng@google.com" ],
"expiry_milestone": 96
},
{
"name": "print-with-postscript-type42-fonts",
"owners": [ "thestig" ],
"expiry_milestone": 100
},
{
"name": "print-with-reduced-rasterization",
"owners": [ "thestig" ],

@ -3829,6 +3829,12 @@ const char kGdiTextPrinting[] = "GDI Text Printing";
const char kGdiTextPrintingDescription[] =
"Use GDI to print text as simply text";
const char kPrintWithPostScriptType42FontsName[] =
"Print with PostScript Type 42 fonts";
const char kPrintWithPostScriptType42FontsDescription[] =
"When using PostScript level 3 printing, render text with Type 42 fonts if "
"possible.";
const char kPrintWithReducedRasterizationName[] =
"Print with reduced rasterization";
const char kPrintWithReducedRasterizationDescription[] =

@ -2192,6 +2192,9 @@ extern const char kUseWinrtMidiApiDescription[];
extern const char kGdiTextPrinting[];
extern const char kGdiTextPrintingDescription[];
extern const char kPrintWithPostScriptType42FontsName[];
extern const char kPrintWithPostScriptType42FontsDescription[];
extern const char kPrintWithReducedRasterizationName[];
extern const char kPrintWithReducedRasterizationDescription[];

@ -1267,6 +1267,9 @@ const PolicyToPreferenceMapEntry kSimplePolicyMap[] = {
{ key::kBrowserSwitcherChromeParameters,
browser_switcher::prefs::kChromeParameters,
base::Value::Type::LIST },
{ key::kPrintPostScriptMode,
prefs::kPrintPostScriptMode,
base::Value::Type::INTEGER },
{ key::kPrintRasterizationMode,
prefs::kPrintRasterizationMode,
base::Value::Type::INTEGER },

@ -217,6 +217,8 @@ std::unique_ptr<MetafilePlayer> PdfConverterImpl::GetMetaFileFromMapping(
std::unique_ptr<Emf> metafile;
if (settings_.mode == PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2 ||
settings_.mode == PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3 ||
settings_.mode ==
PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3_WITH_TYPE42_FONTS ||
settings_.mode == PdfRenderSettings::Mode::TEXTONLY) {
metafile = std::make_unique<PostScriptMetaFile>();
} else {
@ -421,6 +423,11 @@ void PdfConverterImpl::RecordConversionMetrics() {
"Printing.ConversionSize.EmfWithReducedRasterizationAndGdiText",
average_page_size_in_kb);
return;
case PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3_WITH_TYPE42_FONTS:
UMA_HISTOGRAM_MEMORY_KB(
"Printing.ConversionSize.PostScript3WithType42Fonts",
average_page_size_in_kb);
return;
default:
NOTREACHED();
return;

@ -339,6 +339,33 @@ IN_PROC_BROWSER_TEST_F(PdfToEmfConverterBrowserTest, PostScriptLevel3Basic) {
}
}
IN_PROC_BROWSER_TEST_F(PdfToEmfConverterBrowserTest,
PostScriptLevel3WithType42FontsBasic) {
const PdfRenderSettings pdf_settings(
kLetter200DpiRect, gfx::Point(0, 0), k200DpiSize,
/*autorotate=*/false, /*use_color=*/true,
PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3_WITH_TYPE42_FONTS);
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));
// The output is PS encapsulated in EMF.
// TODO(thestig): Update test expectations once PDFium generates PostScript
// with Type 42 fonts.
#ifdef NTDDI_WIN10_VB // Windows 10.0.19041
ASSERT_TRUE(GetPageExpectedEmfData(
GetFileNameForPageNumber("pdf_converter_basic_ps_new_page_", i)));
#else
ASSERT_TRUE(GetPageExpectedEmfData(
GetFileNameForPageNumber("pdf_converter_basic_ps_page_", i)));
#endif
ComparePageEmfHeader();
ComparePageEmfPayload();
}
}
IN_PROC_BROWSER_TEST_F(PdfToEmfConverterBrowserTest, PostScriptLevel2Mono) {
const PdfRenderSettings pdf_settings(
kLetter200DpiRect, gfx::Point(0, 0), k200DpiSize,

@ -49,6 +49,16 @@ void HoldRefCallback(scoped_refptr<PrintJob> job, base::OnceClosure callback) {
}
#if defined(OS_WIN)
// Those must be kept in sync with the values defined in policy_templates.json.
enum class PrintPostScriptMode {
// Do normal PostScript generation. Text is always rendered with Type 3 fonts.
// Default value when policy not set.
kDefault = 0,
// Text is rendered with Type 42 fonts if possible.
kType42 = 1,
kMaxValue = kType42,
};
// Those must be kept in sync with the values defined in policy_templates.json.
enum class PrintRasterizationMode {
// Do full page rasterization if necessary. Default value when policy not set.
@ -58,6 +68,17 @@ enum class PrintRasterizationMode {
kMaxValue = kFast,
};
bool PrintWithPostScriptType42Fonts(PrefService* prefs) {
// Managed preference takes precedence over user preference and field trials.
if (prefs && prefs->IsManagedPreference(prefs::kPrintPostScriptMode)) {
int value = prefs->GetInteger(prefs::kPrintPostScriptMode);
return value == static_cast<int>(PrintPostScriptMode::kType42);
}
return base::FeatureList::IsEnabled(
features::kPrintWithPostScriptType42Fonts);
}
bool PrintWithReducedRasterization(PrefService* prefs) {
// Managed preference takes precedence over user preference and field trials.
if (prefs && prefs->IsManagedPreference(prefs::kPrintRasterizationMode)) {
@ -67,7 +88,17 @@ bool PrintWithReducedRasterization(PrefService* prefs) {
return base::FeatureList::IsEnabled(features::kPrintWithReducedRasterization);
}
#endif
PrefService* GetPrefsForWebContents(content::WebContents* web_contents) {
// TODO(thestig): Figure out why crbug.com/1083911 occurred, which is likely
// because `web_contents` was null. As a result, this section has many more
// pointer checks to avoid crashing.
content::BrowserContext* context =
web_contents ? web_contents->GetBrowserContext() : nullptr;
return context ? Profile::FromBrowserContext(context)->GetPrefs() : nullptr;
}
#endif // defined(OS_WIN)
} // namespace
@ -353,14 +384,7 @@ void PrintJob::StartPdfToEmfConversion(
settings.print_text_with_gdi() && !settings.printer_language_is_xps() &&
base::FeatureList::IsEnabled(::features::kGdiTextPrinting);
// TODO(thestig): Figure out why crbug.com/1083911 occurred, which is likely
// because `web_contents` was null. As a result, this section has many more
// pointer checks to avoid crashing.
content::WebContents* web_contents = worker_->GetWebContents();
content::BrowserContext* context =
web_contents ? web_contents->GetBrowserContext() : nullptr;
PrefService* prefs =
context ? Profile::FromBrowserContext(context)->GetPrefs() : nullptr;
PrefService* prefs = GetPrefsForWebContents(worker_->GetWebContents());
bool print_with_reduced_rasterization = PrintWithReducedRasterization(prefs);
using RenderMode = PdfRenderSettings::Mode;
@ -451,11 +475,19 @@ void PrintJob::StartPdfToPostScriptConversion(
pdf_conversion_state_ = std::make_unique<PdfConversionState>(
gfx::Size(), gfx::Rect());
const PrintSettings& settings = document()->settings();
PdfRenderSettings::Mode mode;
if (ps_level2) {
mode = PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2;
} else {
PrefService* prefs = GetPrefsForWebContents(worker_->GetWebContents());
mode = PrintWithPostScriptType42Fonts(prefs)
? PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3_WITH_TYPE42_FONTS
: PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3;
}
PdfRenderSettings render_settings(
content_area, physical_offsets, settings.dpi_size(),
/*autorotate=*/true, settings.color() == mojom::ColorModel::kColor,
ps_level2 ? PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2
: PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3);
/*autorotate=*/true, settings.color() == mojom::ColorModel::kColor, mode);
pdf_conversion_state_->Start(
bytes, render_settings,
base::BindOnce(&PrintJob::OnPdfConversionStarted, this));

@ -437,6 +437,7 @@ void ProfileImpl::RegisterProfilePrefs(
registry->RegisterBooleanPref(prefs::kPrintPdfAsImageAvailability, false);
#endif
#if defined(OS_WIN) && BUILDFLAG(ENABLE_PRINTING)
registry->RegisterIntegerPref(prefs::kPrintPostScriptMode, 0);
registry->RegisterIntegerPref(prefs::kPrintRasterizationMode, 0);
#endif
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)

@ -1375,6 +1375,9 @@ const char kPrintRasterizePdfDpi[] = "printing.rasterize_pdf_dpi";
#endif
#if defined(OS_WIN) && BUILDFLAG(ENABLE_PRINTING)
// An integer pref that holds the PostScript mode to use when printing.
const char kPrintPostScriptMode[] = "printing.postscript_mode";
// An integer pref that holds the rasterization mode to use when printing.
const char kPrintRasterizationMode[] = "printing.rasterization_mode";
#endif

@ -451,6 +451,7 @@ extern const char kPrintRasterizePdfDpi[];
#endif
#if defined(OS_WIN) && BUILDFLAG(ENABLE_PRINTING)
extern const char kPrintPostScriptMode[];
extern const char kPrintRasterizationMode[];
#endif

@ -99,6 +99,9 @@ void PdfToEmfConverter::SetPrintMode() {
case PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3:
printing_mode = chrome_pdf::PrintingMode::kPostScript3;
break;
case PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3_WITH_TYPE42_FONTS:
printing_mode = chrome_pdf::PrintingMode::kPostScript3WithType42Fonts;
break;
case PdfRenderSettings::Mode::EMF_WITH_REDUCED_RASTERIZATION:
case PdfRenderSettings::Mode::EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT:
printing_mode = chrome_pdf::PrintingMode::kEmfWithReducedRasterization;
@ -202,7 +205,9 @@ void PdfToEmfConverter::ConvertPage(uint32_t page_number,
float scale_factor = 1.0f;
bool postscript =
pdf_render_settings_.mode == PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2 ||
pdf_render_settings_.mode == PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3;
pdf_render_settings_.mode == PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3 ||
pdf_render_settings_.mode ==
PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3_WITH_TYPE42_FONTS;
base::ReadOnlySharedMemoryRegion emf_region =
RenderPdfPageToMetafile(page_number, postscript, &scale_factor);
std::move(callback).Run(std::move(emf_region), scale_factor);

@ -23,7 +23,9 @@ struct PdfRenderSettings {
[EnableIf=is_win]
EMF_WITH_REDUCED_RASTERIZATION,
[EnableIf=is_win]
EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT
EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT,
[EnableIf=is_win]
POSTSCRIPT_LEVEL3_WITH_TYPE42_FONTS,
};
gfx.mojom.Rect area;

@ -34,6 +34,8 @@ struct EnumTraits<printing::mojom::PdfRenderSettings_Mode,
return MojomMode::EMF_WITH_REDUCED_RASTERIZATION;
case PrintMode::EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT:
return MojomMode::EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT;
case PrintMode::POSTSCRIPT_LEVEL3_WITH_TYPE42_FONTS:
return MojomMode::POSTSCRIPT_LEVEL3_WITH_TYPE42_FONTS;
#endif
}
NOTREACHED() << "Unknown mode " << static_cast<int>(mode);
@ -67,6 +69,9 @@ struct EnumTraits<printing::mojom::PdfRenderSettings_Mode,
case MojomMode::EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT:
*output = PrintMode::EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT;
return true;
case MojomMode::POSTSCRIPT_LEVEL3_WITH_TYPE42_FONTS:
*output = PrintMode::POSTSCRIPT_LEVEL3_WITH_TYPE42_FONTS;
return true;
#endif
}
NOTREACHED() << "Unknown mode " << static_cast<int>(input);

@ -622,6 +622,21 @@
}
]
},
"PrintPostScriptMode": {
"os": [
"win"
],
"policy_pref_mapping_tests": [
{
"policies": {
"PrintPostScriptMode": 1
},
"prefs": {
"printing.postscript_mode": {}
}
}
]
},
"PrintRasterizationMode": {
"os": [
"win"

@ -1137,6 +1137,7 @@
'PrintRasterizePdfDpi',
'DeletePrintJobHistoryAllowed',
'CloudPrintWarningsSuppressed',
'PrintPostScriptMode',
]
},
{
@ -24542,6 +24543,46 @@
Local printers are also known as native printing destinations, and include destinations available to the local machine and shared network printers.'''
},
{
'name': 'PrintPostScriptMode',
'owners': ['thestig@chromium.org', 'file://printing/OWNERS'],
'type': 'int-enum',
'schema': {
'type': 'integer',
'enum': [ 0, 1 ],
},
'items': [
{
'name': 'Default',
'value': 0,
'caption': '''Default''',
},
{
'name': 'Type42',
'value': 1,
'caption': '''Type42''',
},
],
'supported_on': ['chrome.win:95-'],
'features': {
'dynamic_refresh': True,
'per_profile': True,
},
'example_value': 1,
'default': 0,
'id': 895,
'caption': '''Print PostScript Mode''',
'tags': [],
'desc': '''Controls how <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> prints on <ph name="MS_WIN_NAME">Microsoft® Windows®</ph>.
When printing to a PostScript printer on <ph name="MS_WIN_NAME">Microsoft® Windows®</ph> different PostScript generation methods can affect printing performance.
When this policy is set to Default, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will use a set of default options when generating PostScript. For text in particular, text will always be rendered using Type 3 fonts.
When this policy is set to Type42, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will render text using Type 42 fonts if possible. This should increase printing speed for some PostScript printers.
When this policy is not set, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will be in Default mode.'''
},
{
'name': 'PrintRasterizationMode',
'owners': ['thestig@chromium.org', 'file://printing/OWNERS'],
@ -24572,9 +24613,9 @@
'id': 706,
'caption': '''Print Rasterization Mode''',
'tags': [],
'desc': '''Controls how <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> prints on Windows.
'desc': '''Controls how <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> prints on <ph name="MS_WIN_NAME">Microsoft® Windows®</ph>.
When printing to a non-PostScript printer on Windows, sometimes print jobs need to be rasterized to print correctly.
When printing to a non-PostScript printer on <ph name="MS_WIN_NAME">Microsoft® Windows®</ph>, sometimes print jobs need to be rasterized to print correctly.
When this policy is set to Full, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will do full page rasterization if necessary.
@ -28627,6 +28668,6 @@ The recommended way to configure policy on Windows is via GPO, although provisio
'placeholders': [],
'deleted_policy_ids': [114, 115, 204, 205, 206, 412, 476, 544, 546, 562, 569, 578, 583, 585, 586, 587, 588, 589, 590, 591, 600, 668, 669, 872],
'deleted_atomic_policy_group_ids': [19],
'highest_id_currently_used': 894,
'highest_id_currently_used': 895,
'highest_atomic_group_id_currently_used': 41
}

@ -48,6 +48,9 @@ enum PrintingMode {
// Values 4 and 5 are similar to `kPostScript2` and `kPostScript3`, but are
// not intended for use in sandboxed environments like Chromium's.
kEmfWithReducedRasterization = 6,
kPostScript3WithType42Fonts = 7,
// Value 8 is similar to `kPostScript3WithType42Fonts`, but is not intended
// for use in sandboxed environments like Chromium's.
};
// `pdf_buffer` is the buffer that contains the entire PDF document to be

@ -264,6 +264,8 @@ STATIC_ASSERT_ENUM(kPostScript2, FPDF_PRINTMODE_POSTSCRIPT2);
STATIC_ASSERT_ENUM(kPostScript3, FPDF_PRINTMODE_POSTSCRIPT3);
STATIC_ASSERT_ENUM(kEmfWithReducedRasterization,
FPDF_PRINTMODE_EMF_IMAGE_MASKS);
STATIC_ASSERT_ENUM(kPostScript3WithType42Fonts,
FPDF_PRINTMODE_POSTSCRIPT3_TYPE42);
#endif
} // namespace chrome_pdf

@ -23,7 +23,8 @@ struct PdfRenderSettings {
POSTSCRIPT_LEVEL3,
EMF_WITH_REDUCED_RASTERIZATION,
EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT,
LAST = EMF_WITH_REDUCED_RASTERIZATION_AND_GDI_TEXT
POSTSCRIPT_LEVEL3_WITH_TYPE42_FONTS,
LAST = POSTSCRIPT_LEVEL3_WITH_TYPE42_FONTS
#else
LAST = NORMAL
#endif

@ -22,6 +22,11 @@ const base::Feature kCupsIppPrintingBackend{"CupsIppPrintingBackend",
#endif // defined(OS_MAC)
#if defined(OS_WIN)
// When using PostScript level 3 printing, render text with Type 42 fonts if
// possible.
const base::Feature kPrintWithPostScriptType42Fonts{
"PrintWithPostScriptType42Fonts", base::FEATURE_DISABLED_BY_DEFAULT};
// When using GDI printing, avoid rasterization if possible.
const base::Feature kPrintWithReducedRasterization{
"PrintWithReducedRasterization", base::FEATURE_DISABLED_BY_DEFAULT};

@ -23,6 +23,8 @@ extern const base::Feature kCupsIppPrintingBackend;
#if defined(OS_WIN)
COMPONENT_EXPORT(PRINTING_BASE)
extern const base::Feature kPrintWithPostScriptType42Fonts;
COMPONENT_EXPORT(PRINTING_BASE)
extern const base::Feature kPrintWithReducedRasterization;
COMPONENT_EXPORT(PRINTING_BASE)
extern const base::Feature kUseXpsForPrinting;

@ -26272,6 +26272,7 @@ Called by update_document_policy_enum.py.-->
<int value="892" label="ChromeAppsEnabled"/>
<int value="893" label="BrowserLegacyExtensionPointsBlocked"/>
<int value="894" label="DeviceRestrictedManagedGuestSessionEnabled"/>
<int value="895" label="PrintPostScriptMode"/>
</enum>
<enum name="EnterprisePolicyDeviceIdValidity">
@ -48558,6 +48559,7 @@ from previous Chrome versions.
<int value="-1021097344" label="PolicyAtomicGroup:disabled"/>
<int value="-1020450980" label="gesture-deletion"/>
<int value="-1019967332" label="VrBrowsing:enabled"/>
<int value="-1019760093" label="PrintWithPostScriptType42Fonts:enabled"/>
<int value="-1019492310"
label="OmniboxUIExperimentJogTextfieldOnPopup:enabled"/>
<int value="-1018454657" label="SharingPeerConnectionReceiver:enabled"/>
@ -49180,6 +49182,7 @@ from previous Chrome versions.
<int value="-519960638" label="enable-site-engagement-service"/>
<int value="-519844731" label="SignInProfileCreationFlow:enabled"/>
<int value="-519345823" label="CrOSEnforceSystemAecNsAgc:enabled"/>
<int value="-519342886" label="PrintWithPostScriptType42Fonts:disabled"/>
<int value="-518104091" label="NewAudioRenderingMixingStrategy:enabled"/>
<int value="-516845951" label="enable-embedded-extension-options"/>
<int value="-515913489" label="EphemeralTabUsingBottomSheet:disabled"/>

@ -82,6 +82,16 @@ reviews. Googlers can read more about this at go/gwsq-gerrit.
</summary>
</histogram>
<histogram name="Printing.ConversionSize.PostScript3WithType42Fonts" units="KB"
expires_after="2022-09-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 with Type 42 fonts. Recorded after conversion.
</summary>
</histogram>
<histogram name="Printing.ConversionSize.Pwg" units="KB"
expires_after="2021-09-30">
<owner>thestig@chromium.org</owner>