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

Fallback to FreeType for COLR/CPAL on pre Windows 8.1 systems

The availability of IDWriteFontFactory2 (which has the
TranslateColorGlyphRun method on it) is equivalent to the ability of the
underlying DirectWrite implementation to render COLR/CPAL fonts. We are
using this detection to find out whether we are running on a system that
can render COLR/CPAL natively, otherwise pass the web font to a
COLR/CPAL SkFontMgr based on FreeType.

Tests updated to reliably test rendering results for COLR/CPAL including
our Windows 7 bots.

Mac detection to do the same fallback for OS versions below Mac OS 10.13
will follow in a subsequent CL.

Bug: 882844
Cq-Include-Trybots: luci.chromium.try:linux_layout_tests_layout_ng;luci.chromium.try:linux_layout_tests_slimming_paint_v2;master.tryserver.blink:linux_trusty_blink_rel
Change-Id: I5f5aa16cbb176d22d229dee05619419cbb8bb892
Reviewed-on: https://chromium-review.googlesource.com/1219887
Commit-Queue: Dominik Röttsches <drott@chromium.org>
Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Cr-Commit-Position: refs/heads/master@{#592743}
parent 49324561
...@@ -14,6 +14,15 @@ ...@@ -14,6 +14,15 @@
src: url("../../third_party/ChromaCheck/chromacheck-cbdt.woff"); src: url("../../third_party/ChromaCheck/chromacheck-cbdt.woff");
} }
@font-face {
font-family: "chromacheck-colr";
src: url("../../third_party/ChromaCheck/chromacheck-colr.woff");
}
.colr_test {
font-family: chromacheck-colr, sans-serif;
}
.cff2_test { .cff2_test {
font-family: adobevfproto, sans-serif; font-family: adobevfproto, sans-serif;
} }
...@@ -46,17 +55,20 @@ ...@@ -46,17 +55,20 @@
</style> </style>
<body> <body>
<div class="horizontalgrid"> <div class="horizontalgrid">
<div class="gridcell"><p>Should show as a serif font, not as a sans-serif fallback:</p><span class="cff2_test">AbcDef</span></div> <div class="gridcell"><p>Should show as a serif font, not as a sans-serif fallback (CFF2):</p><span class="cff2_test">AbcDef</span></div>
<div class="gridcell"><p>Should show red squares:</p><span class="sbix_test">&#xE901; &#xE901; &#xE901; &#xE901; <div class="gridcell"><p>Should show red squares (SBIX):</p><span class="sbix_test">&#xE901; &#xE901; &#xE901; &#xE901;
&#xE901;</span></div> &#xE901;</span></div>
<div class="gridcell"><p>Should show dark red squares:</p><span class="cbdt_test">&#xE903; &#xE903; &#xE903; <div class="gridcell"><p>Should show dark red squares (CBDT):</p><span class="cbdt_test">&#xE903; &#xE903; &#xE903;
&#xE903; &#xE903;</span></div> &#xE903; &#xE903;</span></div>
<div class="gridcell"><p>Should show red squares (COLR):</p><span class="colr_test">&#xE900; &#xE900; &#xE900;
&#xE900; &#xE900;</span></div>
</div> </div>
<div class="horizontalgrid"> <div class="horizontalgrid">
<div class="gridcell"><p>Should show as a serif font, not as a sans-serif fallback:</p><span class="cff2_test upright">AbcDef</span></div> <div class="gridcell"><p>Should show as a serif font, not as a sans-serif fallback (CFF2):</p><span class="cff2_test upright">AbcDef</span></div>
<div class="gridcell"><p>Should show red squares:</p><span class="sbix_test upright">&#xE901; &#xE901; &#xE901; <div class="gridcell"><p>Should show red squares (SBIX):</p><span class="sbix_test upright">&#xE901; &#xE901; &#xE901;
&#xE901; &#xE901;</span></div> &#xE901; &#xE901;</span></div>
<div class="gridcell"><p>Should show dark red squares:</p><span class="cbdt_test upright">&#xE903; &#xE903; &#xE903; &#xE903; &#xE903;</span></div> <div class="gridcell"><p>Should show dark red squares (CBDT):</p><span class="cbdt_test upright">&#xE903; &#xE903; &#xE903; &#xE903; &#xE903;</span></div>
<div class="gridcell"><p>Should show dark red squares (COLR):</p><span class="colr_test upright">&#xE900; &#xE900; &#xE900; &#xE900; &#xE900;</span></div>
</div> </div>
</body> </body>
</html> </html>
...@@ -14,6 +14,11 @@ ...@@ -14,6 +14,11 @@
src: url("../../third_party/ChromaCheck/chromacheck-cbdt.woff"); src: url("../../third_party/ChromaCheck/chromacheck-cbdt.woff");
} }
@font-face {
font-family: "chromacheck-colr";
src: url("../../third_party/ChromaCheck/chromacheck-colr.woff");
}
.cff2_test { .cff2_test {
font-family: adobevfproto, sans-serif; font-family: adobevfproto, sans-serif;
} }
...@@ -24,6 +29,10 @@ ...@@ -24,6 +29,10 @@
font-family: chromacheck-cbdt, sans-serif; font-family: chromacheck-cbdt, sans-serif;
} }
.colr_test {
font-family: chromacheck-colr, sans-serif;
}
.horizontalgrid { .horizontalgrid {
display: flex; display: flex;
} }
...@@ -40,9 +49,10 @@ ...@@ -40,9 +49,10 @@
</style> </style>
<body> <body>
<div class="horizontalgrid"> <div class="horizontalgrid">
<div class="gridcell"><p>Should show as a serif font, not as a sans-serif fallback:</p><span class="cff2_test"></span></div> <div class="gridcell"><p>Should show as a serif font, not as a sans-serif fallback (CFF2):</p><span class="cff2_test"></span></div>
<div class="gridcell"><p>Should show red squares:</p><span class="sbix_test"></span></div> <div class="gridcell"><p>Should show red squares (SBIX):</p><span class="sbix_test"></span></div>
<div class="gridcell"><p>Should show dark red squares:</p><span class="cbdt_test"></span></div> <div class="gridcell"><p>Should show dark red squares (CBDT):</p><span class="cbdt_test"></span></div>
<div class="gridcell"><p>Should show red squares (COLR):</p><span class="colr_test"></span></div>
</div> </div>
<script> <script>
function appendRotatedScale(theNode, testText) { function appendRotatedScale(theNode, testText) {
...@@ -63,6 +73,7 @@ ...@@ -63,6 +73,7 @@
appendRotatedScale(document.querySelector(".cff2_test"), "y"); appendRotatedScale(document.querySelector(".cff2_test"), "y");
appendRotatedScale(document.querySelector(".sbix_test"), "\uE901"); appendRotatedScale(document.querySelector(".sbix_test"), "\uE901");
appendRotatedScale(document.querySelector(".cbdt_test"), "\uE903"); appendRotatedScale(document.querySelector(".cbdt_test"), "\uE903");
appendRotatedScale(document.querySelector(".colr_test"), "\uE900");
</script> </script>
</body> </body>
</html> </html>
...@@ -48,6 +48,12 @@ bool FontFormatCheck::IsCbdtCblcColorFont() { ...@@ -48,6 +48,12 @@ bool FontFormatCheck::IsCbdtCblcColorFont() {
table_tags_.Contains(HB_TAG('C', 'B', 'L', 'C')); table_tags_.Contains(HB_TAG('C', 'B', 'L', 'C'));
} }
bool FontFormatCheck::IsColrCpalColorFont() {
return table_tags_.size() &&
table_tags_.Contains(HB_TAG('C', 'O', 'L', 'R')) &&
table_tags_.Contains(HB_TAG('C', 'P', 'A', 'L'));
}
bool FontFormatCheck::IsSbixColorFont() { bool FontFormatCheck::IsSbixColorFont() {
return table_tags_.size() && table_tags_.Contains(HB_TAG('s', 'b', 'i', 'x')); return table_tags_.size() && table_tags_.Contains(HB_TAG('s', 'b', 'i', 'x'));
} }
...@@ -56,6 +62,10 @@ bool FontFormatCheck::IsCff2OutlineFont() { ...@@ -56,6 +62,10 @@ bool FontFormatCheck::IsCff2OutlineFont() {
return table_tags_.size() && table_tags_.Contains(HB_TAG('C', 'F', 'F', '2')); return table_tags_.size() && table_tags_.Contains(HB_TAG('C', 'F', 'F', '2'));
} }
bool FontFormatCheck::IsColorFont() {
return IsCbdtCblcColorFont() || IsColrCpalColorFont() || IsSbixColorFont();
}
FontFormatCheck::VariableFontSubType FontFormatCheck::ProbeVariableFont( FontFormatCheck::VariableFontSubType FontFormatCheck::ProbeVariableFont(
sk_sp<SkTypeface> typeface) { sk_sp<SkTypeface> typeface) {
if (!typeface->getTableSize( if (!typeface->getTableSize(
......
...@@ -17,8 +17,10 @@ class FontFormatCheck { ...@@ -17,8 +17,10 @@ class FontFormatCheck {
FontFormatCheck(sk_sp<SkData>); FontFormatCheck(sk_sp<SkData>);
bool IsVariableFont(); bool IsVariableFont();
bool IsCbdtCblcColorFont(); bool IsCbdtCblcColorFont();
bool IsColrCpalColorFont();
bool IsSbixColorFont(); bool IsSbixColorFont();
bool IsCff2OutlineFont(); bool IsCff2OutlineFont();
bool IsColorFont();
// Still needed in FontCustomPlatformData. // Still needed in FontCustomPlatformData.
enum class VariableFontSubType { enum class VariableFontSubType {
......
...@@ -10,9 +10,15 @@ ...@@ -10,9 +10,15 @@
#include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/skia/include/core/SkStream.h" #include "third_party/skia/include/core/SkStream.h"
#include "third_party/skia/include/core/SkTypeface.h" #include "third_party/skia/include/core/SkTypeface.h"
#if defined(OS_WIN)
#include "third_party/blink/public/common/dwrite_rasterizer_support/dwrite_rasterizer_support.h"
#endif
#if defined(OS_WIN) || defined(OS_MACOSX) #if defined(OS_WIN) || defined(OS_MACOSX)
#include "third_party/skia/include/ports/SkFontMgr_empty.h" #include "third_party/skia/include/ports/SkFontMgr_empty.h"
#endif #endif
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
#include "third_party/blink/renderer/platform/fonts/mac/core_text_variations_support.h" #include "third_party/blink/renderer/platform/fonts/mac/core_text_variations_support.h"
#endif #endif
...@@ -27,8 +33,7 @@ bool WebFontTypefaceFactory::CreateTypeface(sk_sp<SkData> sk_data, ...@@ -27,8 +33,7 @@ bool WebFontTypefaceFactory::CreateTypeface(sk_sp<SkData> sk_data,
std::unique_ptr<SkStreamAsset> stream(new SkMemoryStream(sk_data)); std::unique_ptr<SkStreamAsset> stream(new SkMemoryStream(sk_data));
if (!format_check.IsVariableFont() && !format_check.IsCbdtCblcColorFont() && if (!format_check.IsVariableFont() && !format_check.IsColorFont()) {
!format_check.IsCff2OutlineFont() && !format_check.IsSbixColorFont()) {
typeface = DefaultFontManager()->makeFromStream(std::move(stream)); typeface = DefaultFontManager()->makeFromStream(std::move(stream));
if (typeface) { if (typeface) {
ReportWebFontInstantiationResult(kSuccessConventionalWebFont); ReportWebFontInstantiationResult(kSuccessConventionalWebFont);
...@@ -39,10 +44,12 @@ bool WebFontTypefaceFactory::CreateTypeface(sk_sp<SkData> sk_data, ...@@ -39,10 +44,12 @@ bool WebFontTypefaceFactory::CreateTypeface(sk_sp<SkData> sk_data,
return false; return false;
} }
// We don't expect variable CBDT/CBLC or Sbix variable fonts for now.
if (format_check.IsCbdtCblcColorFont()) { if (format_check.IsCbdtCblcColorFont()) {
typeface = FreeTypeFontManager()->makeFromStream(std::move(stream)); typeface = FreeTypeFontManager()->makeFromStream(std::move(stream));
if (typeface) if (typeface)
ReportWebFontInstantiationResult(kSuccessCbdtCblcColorFont); ReportWebFontInstantiationResult(kSuccessCbdtCblcColorFont);
return typeface.get();
} }
if (format_check.IsSbixColorFont()) { if (format_check.IsSbixColorFont()) {
...@@ -50,24 +57,37 @@ bool WebFontTypefaceFactory::CreateTypeface(sk_sp<SkData> sk_data, ...@@ -50,24 +57,37 @@ bool WebFontTypefaceFactory::CreateTypeface(sk_sp<SkData> sk_data,
if (typeface) { if (typeface) {
ReportWebFontInstantiationResult(kSuccessSbixFont); ReportWebFontInstantiationResult(kSuccessSbixFont);
} }
return typeface.get();
} }
// CFF2 must always go through the FreeTypeFontManager, even on Mac OS, as it
// is not natively supported.
if (format_check.IsCff2OutlineFont()) { if (format_check.IsCff2OutlineFont()) {
typeface = FreeTypeFontManager()->makeFromStream(std::move(stream)); typeface = FreeTypeFontManager()->makeFromStream(std::move(stream));
if (typeface) if (typeface)
ReportWebFontInstantiationResult(kSuccessCff2Font); ReportWebFontInstantiationResult(kSuccessCff2Font);
return typeface.get();
} }
// Variable CFF2 fonts must go through FreeType. // Variable COLR/CPAL fonts must go through the Variations
if (format_check.IsVariableFont() && !format_check.IsCff2OutlineFont()) { // FontManager, which is FreeType on Windows.
if (format_check.IsVariableFont()) {
typeface = FontManagerForVariations()->makeFromStream(std::move(stream)); typeface = FontManagerForVariations()->makeFromStream(std::move(stream));
if (typeface) if (typeface)
ReportWebFontInstantiationResult(kSuccessVariableWebFont); ReportWebFontInstantiationResult(kSuccessVariableWebFont);
else else
ReportWebFontInstantiationResult(kErrorInstantiatingVariableFont); ReportWebFontInstantiationResult(kErrorInstantiatingVariableFont);
return typeface.get();
}
if (format_check.IsColrCpalColorFont()) {
typeface = FontManagerForColrCpal()->makeFromStream(std::move(stream));
if (typeface)
ReportWebFontInstantiationResult(kSuccessColrCpalFont);
return typeface.get();
} }
return true; return false;
} }
sk_sp<SkFontMgr> WebFontTypefaceFactory::FontManagerForVariations() { sk_sp<SkFontMgr> WebFontTypefaceFactory::FontManagerForVariations() {
...@@ -105,6 +125,16 @@ sk_sp<SkFontMgr> WebFontTypefaceFactory::FreeTypeFontManager() { ...@@ -105,6 +125,16 @@ sk_sp<SkFontMgr> WebFontTypefaceFactory::FreeTypeFontManager() {
#endif #endif
} }
sk_sp<SkFontMgr> WebFontTypefaceFactory::FontManagerForColrCpal() {
#if defined(OS_WIN)
if (!blink::DWriteRasterizerSupport::IsDWriteFactory2Available())
return FreeTypeFontManager();
#endif
// TODO(https://crbug.com/882844): Check Mac OS version and use the FreeType
// font manager accordingly.
return DefaultFontManager();
}
void WebFontTypefaceFactory::ReportWebFontInstantiationResult( void WebFontTypefaceFactory::ReportWebFontInstantiationResult(
WebFontInstantiationResult result) { WebFontInstantiationResult result) {
DEFINE_THREAD_SAFE_STATIC_LOCAL( DEFINE_THREAD_SAFE_STATIC_LOCAL(
......
...@@ -27,6 +27,7 @@ class WebFontTypefaceFactory { ...@@ -27,6 +27,7 @@ class WebFontTypefaceFactory {
static sk_sp<SkFontMgr> FontManagerForVariations(); static sk_sp<SkFontMgr> FontManagerForVariations();
static sk_sp<SkFontMgr> FontManagerForSbix(); static sk_sp<SkFontMgr> FontManagerForSbix();
static sk_sp<SkFontMgr> FreeTypeFontManager(); static sk_sp<SkFontMgr> FreeTypeFontManager();
static sk_sp<SkFontMgr> FontManagerForColrCpal();
private: private:
// These values are written to logs. New enum values can be added, but // These values are written to logs. New enum values can be added, but
...@@ -38,7 +39,8 @@ class WebFontTypefaceFactory { ...@@ -38,7 +39,8 @@ class WebFontTypefaceFactory {
kSuccessCbdtCblcColorFont = 3, kSuccessCbdtCblcColorFont = 3,
kSuccessCff2Font = 4, kSuccessCff2Font = 4,
kSuccessSbixFont = 5, kSuccessSbixFont = 5,
kMaxWebFontInstantiationResult = 6 kSuccessColrCpalFont = 6,
kMaxWebFontInstantiationResult = 7
}; };
static sk_sp<SkFontMgr> DefaultFontManager(); static sk_sp<SkFontMgr> DefaultFontManager();
......
...@@ -51390,6 +51390,7 @@ Full version information for the fingerprint enum values: ...@@ -51390,6 +51390,7 @@ Full version information for the fingerprint enum values:
<int value="3" label="Success CBDT/CBLC color font"/> <int value="3" label="Success CBDT/CBLC color font"/>
<int value="4" label="Success CFF2 outline font"/> <int value="4" label="Success CFF2 outline font"/>
<int value="5" label="Success Sbix color font"/> <int value="5" label="Success Sbix color font"/>
<int value="6" label="Success COLR/CPAL color font"/>
</enum> </enum>
<enum name="WebFontInterventionResult"> <enum name="WebFontInterventionResult">
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