Commit 3085b20b authored by Dominik Röttsches's avatar Dominik Röttsches Committed by Commit Bot

Move Blink Windows 8 and below fallback to OOP Mojo fallback APIs

Organise Blink font fallback into two main functions:

  * Retrieving a fallback font from the legacy path which finds a
    fallback font from hard-coded lists that have been curated manually
    and maintained.

  * Retrieving a fallback font through DWrite fallback API, either by
    calling Skia API in-process, which in turn uses DWriteFontProxy out
    of process bridging, or calling a Mojo method to retrieve a fallback
    family name.

Use the LegacyWindowsDWriteFontFallbackEnabled RunTimeEnabledFeature to
decide which fallback font to return, if the flag is on, always use
DWrite. If the flag is off, on Windows 8 and below, only use the
hard-coded fallback path. On Windows 8.1 and above, prioritze the
hard-coded path, but try the API path if the hard-coded path did not
find a result. This is intended as an interim flag to control which
fallback font code path to use and to measure quality and availability
of fallback fonts in the new code path. The flag is to be removed once
we are confident to switch to the new code.

Add UMA metric to record 4 different cases
  * Legacy hard-coded list did not find a font
  * API based fallback did not find a font
  * No font was found by either
  * Legacy fallback and API fallback disagreed on fallback font

Record these metrics per ICU UBlockCode.

Using API based fallback leads to a number of improvements exposed by
some of our tests.  For Japanese locales, Yu Gothic UI is selected in
favor of Yu Gothic, which chooses the better screen-optimized, more
modern variant of the font (fast/text/international/001.html,
fast/text/international/002.html,
fast/text/international/wrap-CJK-001.html). For traditional Chinese,
YaHeng UI is selected in favor of SimSun, improving screen display of
Chinese ideographs ( fast/text/justify-ideograph-complex.html,
fast/text/justify-ideograph-simple.html). For untagged Han ideographs,
Yu Gothic UI and Microsoft JhengHei UI are chosen vs. SimSun-ExtB and
SimSun before. For Thai, Leelawade UI is selected over Tahoma. So, with
less hand-curated fonts and removing code, we get much improved CJK and
Thai fallback.

Brief design doc linked from the bug.

Bug: 976737
Change-Id: I3adff65cddb50061c884b81a3ae00de75d4ba735
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1708138
Commit-Queue: Dominik Röttsches <drott@chromium.org>
Reviewed-by: default avatarStephen Chenney <schenney@chromium.org>
Reviewed-by: default avatarKoji Ishii <kojii@chromium.org>
Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Cr-Commit-Position: refs/heads/master@{#687373}
parent e4391092
......@@ -55,6 +55,10 @@
#include "third_party/skia/include/core/SkFontMgr.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#if defined(OS_WIN)
#include "third_party/blink/public/mojom/dwrite_font_proxy/dwrite_font_proxy.mojom-blink.h"
#endif
class SkString;
class SkTypeface;
......@@ -205,6 +209,20 @@ class PLATFORM_EXPORT FontCache {
static void SetUseSkiaFontFallback(bool use_skia_font_fallback) {
use_skia_font_fallback_ = use_skia_font_fallback;
}
// On Windows pre 8.1 establish a connection to the DWriteFontProxy service in
// order to retrieve family names for fallback lookup.
void EnsureServiceConnected();
scoped_refptr<SimpleFontData> GetFallbackFamilyNameFromHardcodedChoices(
const FontDescription&,
UChar32 codepoint,
FontFallbackPriority fallback_priority);
scoped_refptr<SimpleFontData> GetDWriteFallbackFamily(
const FontDescription&,
UChar32 codepoint,
FontFallbackPriority fallback_priority);
#endif // defined(OS_WIN)
static void AcceptLanguagesChanged(const String&);
......@@ -334,6 +352,7 @@ class PLATFORM_EXPORT FontCache {
// Windows creates an SkFontMgr for unit testing automatically. This flag is
// to ensure it's not happening in the production from the crash log.
bool is_test_font_mgr_ = false;
mojom::blink::DWriteFontProxyPtr service_;
#endif // defined(OS_WIN)
#if defined(OS_LINUX) || defined(OS_CHROMEOS)
......
......@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h"
#include <memory>
#include "base/test/scoped_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/fonts/font_cache.h"
#include "third_party/blink/renderer/platform/fonts/shaping/caching_word_shape_iterator.h"
......@@ -27,6 +28,7 @@ class CachingWordShaperTest : public testing::Test {
cache = std::make_unique<ShapeCache>();
}
base::test::ScopedTaskEnvironment scoped_task_environment_;
FontCachePurgePreventer font_cache_purge_preventer;
FontDescription font_description;
Font font;
......
......@@ -7,6 +7,7 @@
#include <unicode/uscript.h>
#include "base/stl_util.h"
#include "base/test/scoped_task_environment.h"
#include "build/build_config.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -129,6 +130,7 @@ class HarfBuzzShaperTest : public testing::Test {
return result;
}
base::test::ScopedTaskEnvironment scoped_task_environment_;
FontCachePurgePreventer font_cache_purge_preventer;
FontDescription font_description;
Font font;
......
......@@ -47,6 +47,10 @@ namespace blink {
namespace {
const char kArial[] = "Arial";
const char kCourierNew[] = "Courier New";
const char kTimesNewRoman[] = "Times New Roman";
static inline bool IsFontPresent(const UChar* font_name,
SkFontMgr* font_manager) {
String family = font_name;
......@@ -543,4 +547,28 @@ const UChar* GetFallbackFamily(UChar32 character,
return family;
}
const String GetOutOfProcessFallbackFamily(
UChar32 character,
FontDescription::GenericFamilyType generic_family,
String bcp47_language_tag,
FontFallbackPriority,
const mojom::blink::DWriteFontProxyPtr& service) {
String base_family_name_approximation;
switch (generic_family) {
case FontDescription::kMonospaceFamily:
base_family_name_approximation = kCourierNew;
break;
case FontDescription::kSansSerifFamily:
base_family_name_approximation = kArial;
break;
default:
base_family_name_approximation = kTimesNewRoman;
}
String fallback_family_name;
service->FallbackFamilyNameForCodepoint(base_family_name_approximation,
bcp47_language_tag, character,
&fallback_family_name);
return fallback_family_name;
}
} // namespace blink
......@@ -36,6 +36,7 @@
#include <usp10.h>
#include <wchar.h>
#include <windows.h>
#include "third_party/blink/public/mojom/dwrite_font_proxy/dwrite_font_proxy.mojom-blink.h"
#include "third_party/blink/renderer/platform/fonts/font_description.h"
#include "third_party/blink/renderer/platform/fonts/font_fallback_priority.h"
#include "third_party/blink/renderer/platform/platform_export.h"
......@@ -45,9 +46,9 @@ class SkFontMgr;
namespace blink {
// Return a font family that can render |character| based on what script
// that characters belong to.
// When scriptChecked is non-zero, the script used to determine
// the family is returned.
// that characters belong to based on hard-coded tables that have been curated
// over time. When scriptChecked is non-zero, the script used to determine the
// family is returned.
PLATFORM_EXPORT const UChar* GetFallbackFamily(
UChar32 character,
FontDescription::GenericFamilyType,
......@@ -56,6 +57,17 @@ PLATFORM_EXPORT const UChar* GetFallbackFamily(
FontFallbackPriority,
SkFontMgr* font_manager);
// Return a font family that can render |character| based on what script
// that characters belong to by performing an out of process lookup and using
// system fallback API based on IDWriteTextLayout. This method is only to be
// used on pre Windows 8.1, as otherwise IDWriteFontFallback API is available.
PLATFORM_EXPORT const String GetOutOfProcessFallbackFamily(
UChar32 character,
FontDescription::GenericFamilyType,
String bcp47_language_tag,
FontFallbackPriority,
const mojom::blink::DWriteFontProxyPtr& font_proxy);
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_WIN_FONT_FALLBACK_WIN_H_
......@@ -45,7 +45,7 @@
⇦⇧⇨⇩←↑→↓⟀
#text_presentation_arrows_maths:
"Yu Gothic UI" : 4,
"MS PGothic" : 4,
"Cambria Math" : 4,
"Segoe UI Symbol" : 1
......
......@@ -13936,6 +13936,57 @@ uploading your change for review.
</summary>
</histogram>
<histogram name="Blink.Fonts.WinFallback.LegacyNoneFound" expires_after="M82">
<owner>drott@chromium.org</owner>
<owner>layout-dev@chromium.org</owner>
<summary>
Tracks Blink Windows font fallback results while migrating to API based
fallback vs. the previous use of a hard-coded list. Records a data point
when the legacy hard-coded list code did not find fallback for a particular
Unicode code block ID (ICU::UBlockCode). Recorded at the time of Blink
layout code requesting a fallback font for a character and locale.
</summary>
</histogram>
<histogram name="Blink.Fonts.WinFallback.LegacyWinAPIDisagree"
expires_after="M82">
<owner>drott@chromium.org</owner>
<owner>layout-dev@chromium.org</owner>
<summary>
Tracks Blink Windows font fallback results while migrating to API based
fallback vs. the previous use of a hard-coded list. Records a data point
when the Windows API out of process fallback code and the legacy hard-coded
list fallback code disagree in fallback font result for a particular Unicode
code block ID (ICU::UBlockCode). Recorded at the time of Blink layout code
requesting a fallback font for a character and locale.
</summary>
</histogram>
<histogram name="Blink.Fonts.WinFallback.NoFallbackFound" expires_after="M82">
<owner>drott@chromium.org</owner>
<owner>layout-dev@chromium.org</owner>
<summary>
Tracks Blink Windows font fallback results while migrating to API based
fallback vs. the previous use of a hard-coded list. Records a data point
when no fallback font result was found for a particular Unicode code block
ID (ICU::UBlockCode) through either the out-of-process Windows DWrite API or
the hard-coded list fallback code. Recorded at the time of Blink layout code
requesting a fallback font for a character and locale.
</summary>
</histogram>
<histogram name="Blink.Fonts.WinFallback.WinAPINoneFound" expires_after="M82">
<owner>drott@chromium.org</owner>
<owner>layout-dev@chromium.org</owner>
<summary>
Tracks Blink Windows font fallback results while migrating to API based
fallback vs. the previous use of a hard-coded list. Records a data point
when the Windows API out of process fallback code did not find fallback for
a particular Unicode code block ID (ICU::UBlockCode). Recorded at the time
of Blink layout code requesting a fallback font for a character and locale.
</summary>
</histogram>
<histogram name="Blink.ForcedStyleAndLayout.UpdateTime" units="microseconds"
expires_after="2020-3-1">
<owner>paint-dev@chromium.org</owner>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment