[go: nahoru, domu]

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();