// Copyright 2017 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "third_party/blink/renderer/platform/fonts/web_font_typeface_factory.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" #include "third_party/blink/renderer/platform/fonts/font_cache.h" #include "third_party/blink/renderer/platform/fonts/opentype/font_format_check.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/skia/include/core/SkStream.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" #include "third_party/blink/renderer/platform/fonts/win/dwrite_font_format_support.h" #endif #if defined(OS_WIN) || defined(OS_MAC) #include "third_party/skia/include/ports/SkFontMgr_empty.h" #endif #if defined(OS_MAC) #include "third_party/blink/renderer/platform/fonts/mac/core_text_font_format_support.h" #endif namespace blink { bool WebFontTypefaceFactory::CreateTypeface(sk_sp sk_data, sk_sp& typeface) { CHECK(!typeface); FontFormatCheck format_check(sk_data); std::unique_ptr stream(new SkMemoryStream(sk_data)); if (!format_check.IsVariableFont() && !format_check.IsColorFont()) { typeface = DefaultFontManager()->makeFromStream(std::move(stream)); if (typeface) { ReportInstantiationResult( InstantiationResult::kSuccessConventionalWebFont); return true; } // Not UMA reporting general decoding errors as these are already recorded // as kPackageFormatUnknown in FontResource.cpp. return false; } // We don't expect variable CBDT/CBLC or Sbix variable fonts for now. if (format_check.IsCbdtCblcColorFont()) { typeface = FreeTypeFontManager()->makeFromStream(std::move(stream)); if (typeface) { ReportInstantiationResult(InstantiationResult::kSuccessCbdtCblcColorFont); } return typeface.get(); } if (format_check.IsColrCpalColorFontV1()) { if (RuntimeEnabledFeatures::COLRV1FontsEnabled()) { typeface = FreeTypeFontManager()->makeFromStream(std::move(stream)); if (typeface) { ReportInstantiationResult(InstantiationResult::kSuccessColrV1Font); } return typeface.get(); } else { // Always reject COLRv1 fonts when the feature is off. return false; } } if (format_check.IsSbixColorFont()) { typeface = FontManagerForSbix()->makeFromStream(std::move(stream)); if (typeface) { ReportInstantiationResult(InstantiationResult::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()) { typeface = FreeTypeFontManager()->makeFromStream(std::move(stream)); if (typeface) ReportInstantiationResult(InstantiationResult::kSuccessCff2Font); return typeface.get(); } // Variable COLR/CPAL fonts must go through the Variations // FontManager, which is FreeType on Windows. if (format_check.IsVariableFont()) { typeface = FontManagerForVariations()->makeFromStream(std::move(stream)); if (typeface) { ReportInstantiationResult(InstantiationResult::kSuccessVariableWebFont); } else { ReportInstantiationResult( InstantiationResult::kErrorInstantiatingVariableFont); } return typeface.get(); } if (format_check.IsColrCpalColorFontV0()) { typeface = FontManagerForColrCpal()->makeFromStream(std::move(stream)); if (typeface) { ReportInstantiationResult(InstantiationResult::kSuccessColrCpalFont); } return typeface.get(); } return false; } sk_sp WebFontTypefaceFactory::FontManagerForVariations() { #if defined(OS_WIN) if (DWriteVersionSupportsVariations()) return DefaultFontManager(); return FreeTypeFontManager(); #else #if defined(OS_MAC) if (!CoreTextVersionSupportsVariations()) return FreeTypeFontManager(); #endif return DefaultFontManager(); #endif } sk_sp WebFontTypefaceFactory::FontManagerForSbix() { #if defined(OS_MAC) return DefaultFontManager(); #endif return FreeTypeFontManager(); } sk_sp WebFontTypefaceFactory::DefaultFontManager() { #if defined(OS_WIN) return FontCache::GetFontCache()->FontManager(); #else return sk_sp(SkFontMgr::RefDefault()); #endif } sk_sp WebFontTypefaceFactory::FreeTypeFontManager() { #if defined(OS_WIN) || defined(OS_MAC) return sk_sp(SkFontMgr_New_Custom_Empty()); #else return DefaultFontManager(); #endif } sk_sp WebFontTypefaceFactory::FontManagerForColrCpal() { #if defined(OS_WIN) if (!blink::DWriteRasterizerSupport::IsDWriteFactory2Available()) return FreeTypeFontManager(); #endif #if defined(OS_MAC) if (!CoreTextVersionSupportsColrCpal()) return FreeTypeFontManager(); #endif return DefaultFontManager(); } void WebFontTypefaceFactory::ReportInstantiationResult( InstantiationResult result) { UMA_HISTOGRAM_ENUMERATION("Blink.Fonts.VariableFontsRatio", result); } } // namespace blink