using HINTING_FULL by default in headless builds, added command line parameter to override it
These changes fix font rendering differences between headless and
non-headless runs on linux. Default font hinting is HINTING_MEDIUM,
which leads to usage of subpixel glyphs positioning in Skia. But in
desktop environment hinting eventually resolves to HINTING_FULL and we
get slightly different font rendering as a result and no option to
control it using command line flags.
In this commit --font-render-hinting is added as a new command line
parameter for headless runs with HINTING_FULL as a default value
R=dvallet@chromium.org, skyostil@google.com
Bug: 744577
Change-Id: Iffac55899a7ac98c418d9ee5b4af961017cfb09a
Reviewed-on: https://chromium-review.googlesource.com/899248
Reviewed-by: Sami Kyöstilä <skyostil@chromium.org>
Commit-Queue: David Vallet <dvallet@chromium.org>
Cr-Commit-Position: refs/heads/master@{#536535}
diff --git a/AUTHORS b/AUTHORS
index 9a89d94..5c6d7c3 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -499,6 +499,7 @@
Magnus Danielsson <fuzzac@gmail.com>
Mahesh Kulkarni <mahesh.kk@samsung.com>
Mahesh Machavolu <mahesh.ma@samsung.com>
+Maksim Kolesin <mkolesin@gmail.com>
Maksim Sisov <maksim.sisov@intel.com>
Malcolm Wang <malcolm.2.wang@gmail.com>
Mallikarjuna Rao V <vm.arjun@samsung.com>
diff --git a/headless/BUILD.gn b/headless/BUILD.gn
index 9df61c0..7ec31247 100644
--- a/headless/BUILD.gn
+++ b/headless/BUILD.gn
@@ -965,5 +965,6 @@
deps = [
":headless_shell_lib",
"//build/config:exe_and_shlib_deps",
+ "//skia", # we need this to override font render hinting in headless build
]
}
diff --git a/headless/app/headless_shell.cc b/headless/app/headless_shell.cc
index c098a8a..ffe1ec11 100644
--- a/headless/app/headless_shell.cc
+++ b/headless/app/headless_shell.cc
@@ -73,6 +73,25 @@
return false;
}
+bool ParseFontRenderHinting(
+ const std::string& font_render_hinting_string,
+ gfx::FontRenderParams::Hinting* font_render_hinting) {
+ if (font_render_hinting_string == "max") {
+ *font_render_hinting = gfx::FontRenderParams::Hinting::HINTING_MAX;
+ } else if (font_render_hinting_string == "full") {
+ *font_render_hinting = gfx::FontRenderParams::Hinting::HINTING_FULL;
+ } else if (font_render_hinting_string == "medium") {
+ *font_render_hinting = gfx::FontRenderParams::Hinting::HINTING_MEDIUM;
+ } else if (font_render_hinting_string == "slight") {
+ *font_render_hinting = gfx::FontRenderParams::Hinting::HINTING_SLIGHT;
+ } else if (font_render_hinting_string == "none") {
+ *font_render_hinting = gfx::FontRenderParams::Hinting::HINTING_NONE;
+ } else {
+ return false;
+ }
+ return true;
+}
+
#if !defined(CHROME_MULTIPLE_DLL_CHILD)
GURL ConvertArgumentToURL(const base::CommandLine::StringType& arg) {
GURL url(arg);
@@ -792,6 +811,19 @@
builder.SetUserAgent(ua);
}
+ if (command_line.HasSwitch(switches::kFontRenderHinting)) {
+ std::string font_render_hinting_string =
+ command_line.GetSwitchValueASCII(switches::kFontRenderHinting);
+ gfx::FontRenderParams::Hinting font_render_hinting;
+ if (ParseFontRenderHinting(font_render_hinting_string,
+ &font_render_hinting)) {
+ builder.SetFontRenderHinting(font_render_hinting);
+ } else {
+ LOG(ERROR) << "Unknown font-render-hinting parameter value";
+ return EXIT_FAILURE;
+ }
+ }
+
return HeadlessBrowserMain(
builder.Build(),
base::Bind(&HeadlessShell::OnStart, base::Unretained(&shell)));
diff --git a/headless/app/headless_shell_switches.cc b/headless/app/headless_shell_switches.cc
index a25a7c0..04ace58e3 100644
--- a/headless/app/headless_shell_switches.cc
+++ b/headless/app/headless_shell_switches.cc
@@ -112,5 +112,10 @@
// Whitelist for Negotitate Auth servers.
const char kAuthServerWhitelist[] = "auth-server-whitelist";
+// Sets font render hinting when running headless, affects Skia rendering and
+// whether glyph subpixel positioning is enabled.
+// Possible values: none|slight|medium|full|max. Default: full.
+const char kFontRenderHinting[] = "font-render-hinting";
+
} // namespace switches
} // namespace headless
diff --git a/headless/app/headless_shell_switches.h b/headless/app/headless_shell_switches.h
index 5d62fc8..6e46e7f7 100644
--- a/headless/app/headless_shell_switches.h
+++ b/headless/app/headless_shell_switches.h
@@ -33,6 +33,7 @@
extern const char kVirtualTimeBudget[];
extern const char kWindowSize[];
extern const char kAuthServerWhitelist[];
+extern const char kFontRenderHinting[];
// Switches which are replicated from content.
using ::switches::kRemoteDebuggingPort;
diff --git a/headless/lib/browser/headless_browser_context_options.cc b/headless/lib/browser/headless_browser_context_options.cc
index 220d593..39bdec3 100644
--- a/headless/lib/browser/headless_browser_context_options.cc
+++ b/headless/lib/browser/headless_browser_context_options.cc
@@ -106,4 +106,10 @@
return std::move(protocol_handlers_);
}
+gfx::FontRenderParams::Hinting
+HeadlessBrowserContextOptions::font_render_hinting() const {
+ return ReturnOverriddenValue(font_render_hinting_,
+ browser_options_->font_render_hinting);
+}
+
} // namespace headless
diff --git a/headless/lib/browser/headless_browser_context_options.h b/headless/lib/browser/headless_browser_context_options.h
index 224e5df..45e3ef0 100644
--- a/headless/lib/browser/headless_browser_context_options.h
+++ b/headless/lib/browser/headless_browser_context_options.h
@@ -54,6 +54,9 @@
bool allow_cookies() const;
+ // See HeadlessBrowser::Options::font_render_hinting.
+ gfx::FontRenderParams::Hinting font_render_hinting() const;
+
// Custom network protocol handlers. These can be used to override URL
// fetching for different network schemes.
const ProtocolHandlerMap& protocol_handlers() const;
@@ -88,6 +91,8 @@
ProtocolHandlerMap protocol_handlers_;
+ base::Optional<gfx::FontRenderParams::Hinting> font_render_hinting_;
+
DISALLOW_COPY_AND_ASSIGN(HeadlessBrowserContextOptions);
};
diff --git a/headless/lib/browser/headless_web_contents_impl.cc b/headless/lib/browser/headless_web_contents_impl.cc
index 4304118..bf2c655 100644
--- a/headless/lib/browser/headless_web_contents_impl.cc
+++ b/headless/lib/browser/headless_web_contents_impl.cc
@@ -39,6 +39,7 @@
#include "printing/features/features.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/compositor/compositor.h"
+#include "ui/gfx/switches.h"
#if BUILDFLAG(ENABLE_BASIC_PRINTING)
#include "headless/lib/browser/headless_print_manager.h"
@@ -344,6 +345,8 @@
#endif
web_contents->GetMutableRendererPrefs()->accept_languages =
browser_context->options()->accept_language();
+ web_contents->GetMutableRendererPrefs()->hinting =
+ browser_context->options()->font_render_hinting();
web_contents_->SetDelegate(web_contents_delegate_.get());
render_process_host_->AddObserver(this);
agent_host_->AddObserver(this);
diff --git a/headless/public/headless_browser.cc b/headless/public/headless_browser.cc
index dd8765a..e92b1a5c 100644
--- a/headless/public/headless_browser.cc
+++ b/headless/public/headless_browser.cc
@@ -23,6 +23,9 @@
const char kProductName[] = "HeadlessChrome";
constexpr gfx::Size kDefaultWindowSize(800, 600);
+constexpr gfx::FontRenderParams::Hinting kDefaultFontRenderHinting =
+ gfx::FontRenderParams::Hinting::HINTING_FULL;
+
std::string GetProductNameAndVersion() {
return std::string(kProductName) + "/" + PRODUCT_VERSION;
}
@@ -44,7 +47,8 @@
#endif
product_name_and_version(GetProductNameAndVersion()),
user_agent(content::BuildUserAgentFromProduct(product_name_and_version)),
- window_size(kDefaultWindowSize) {
+ window_size(kDefaultWindowSize),
+ font_render_hinting(kDefaultFontRenderHinting) {
}
Options::Options(Options&& options) = default;
@@ -189,6 +193,12 @@
return *this;
}
+Builder& Builder::SetFontRenderHinting(
+ gfx::FontRenderParams::Hinting font_render_hinting) {
+ options_.font_render_hinting = font_render_hinting;
+ return *this;
+}
+
Options Builder::Build() {
return std::move(options_);
}
diff --git a/headless/public/headless_browser.h b/headless/public/headless_browser.h
index 7e94e4a..7bc9412 100644
--- a/headless/public/headless_browser.h
+++ b/headless/public/headless_browser.h
@@ -22,6 +22,7 @@
#include "headless/public/headless_export.h"
#include "headless/public/headless_web_contents.h"
#include "net/base/host_port_pair.h"
+#include "ui/gfx/font_render_params.h"
#include "ui/gfx/geometry/size.h"
#if defined(OS_WIN)
@@ -215,6 +216,9 @@
bool enable_crash_reporter = false;
base::FilePath crash_dumps_dir;
+ // Font render hinting value to override any default settings
+ gfx::FontRenderParams::Hinting font_render_hinting;
+
// Reminder: when adding a new field here, do not forget to add it to
// HeadlessBrowserContextOptions (where appropriate).
private:
@@ -264,6 +268,8 @@
const base::Callback<void(WebPreferences*)>& callback);
Builder& SetCrashReporterEnabled(bool enabled);
Builder& SetCrashDumpsDir(const base::FilePath& dir);
+ Builder& SetFontRenderHinting(
+ gfx::FontRenderParams::Hinting font_render_hinting);
Options Build();