From ec4f625e7a97b668156af7e77b118bd3da3736ef Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 7 Oct 2021 17:06:56 +0300 Subject: [PATCH] Port patch to 96.0.4664.0 --- .../GDI Implementation - 96.0.4664.0.patch | 1293 +++++++++++++++++ 1 file changed, 1293 insertions(+) create mode 100644 patches/96.0.4664.0/GDI Implementation - 96.0.4664.0.patch diff --git a/patches/96.0.4664.0/GDI Implementation - 96.0.4664.0.patch b/patches/96.0.4664.0/GDI Implementation - 96.0.4664.0.patch new file mode 100644 index 0000000..37c133b --- /dev/null +++ b/patches/96.0.4664.0/GDI Implementation - 96.0.4664.0.patch @@ -0,0 +1,1293 @@ +diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc +index d262a915ce733..d4e9aecde7a39 100644 +--- a/chrome/browser/chrome_content_browser_client.cc ++++ b/chrome/browser/chrome_content_browser_client.cc +@@ -628,7 +628,7 @@ namespace { + // running on Windows 10 1511 and above. See + // https://blogs.windows.com/blog/tag/code-integrity-guard/. + const base::Feature kRendererCodeIntegrity{"RendererCodeIntegrity", +- base::FEATURE_ENABLED_BY_DEFAULT}; ++ base::FEATURE_DISABLED_BY_DEFAULT}; + // Enables pre-launch Code Integrity Guard (CIG) for Chrome network service + // process, when running on Windows 10 1511 and above. This has no effect if + // NetworkServiceSandbox feature is disabled. See +diff --git a/content/browser/renderer_host/dwrite_font_lookup_table_builder_win.cc b/content/browser/renderer_host/dwrite_font_lookup_table_builder_win.cc +index ca42d51cd5be2..6c0ce98e4815e 100644 +--- a/content/browser/renderer_host/dwrite_font_lookup_table_builder_win.cc ++++ b/content/browser/renderer_host/dwrite_font_lookup_table_builder_win.cc +@@ -330,6 +330,7 @@ bool DWriteFontLookupTableBuilder::FontUniqueNameTableReady() { + + void DWriteFontLookupTableBuilder:: + SchedulePrepareFontUniqueNameTableIfNeeded() { ++ return; // Important + DCHECK(base::FeatureList::IsEnabled(features::kFontSrcLocalMatching)); + + { +diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc +index 90cb82a9ed133..df21a09f57966 100644 +--- a/content/public/common/content_features.cc ++++ b/content/public/common/content_features.cc +@@ -313,7 +313,7 @@ const base::Feature kFeaturePolicyForClientHints{ + // font name or postscript name. Rolling out behind a flag, as enabling this + // enables a font indexer on Android which we need to test in the field first. + const base::Feature kFontSrcLocalMatching{"FontSrcLocalMatching", +- base::FEATURE_ENABLED_BY_DEFAULT}; ++ base::FEATURE_DISABLED_BY_DEFAULT}; + + #if !defined(OS_ANDROID) + // Feature controlling whether or not memory pressure signals will be forwarded +diff --git a/content/renderer/renderer_main.cc b/content/renderer/renderer_main.cc +index 8b718ccf63e64..5fb0791d03ec8 100644 +--- a/content/renderer/renderer_main.cc ++++ b/content/renderer/renderer_main.cc +@@ -193,8 +193,8 @@ int RendererMain(const MainFunctionParams& parameters) { + + { + bool should_run_loop = true; +- bool need_sandbox = +- !command_line.HasSwitch(sandbox::policy::switches::kNoSandbox); ++ bool need_sandbox = false; ++ // !command_line.HasSwitch(sandbox::policy::switches::kNoSandbox); + + #if !defined(OS_WIN) && !defined(OS_MAC) + // Sandbox is enabled before RenderProcess initialization on all platforms, +diff --git a/content/renderer/renderer_main_platform_delegate_win.cc b/content/renderer/renderer_main_platform_delegate_win.cc +index c3dc3c9c07ee2..71bc0227a9b3b 100644 +--- a/content/renderer/renderer_main_platform_delegate_win.cc ++++ b/content/renderer/renderer_main_platform_delegate_win.cc +@@ -26,6 +26,12 @@ + #include "ui/gfx/win/direct_write.h" + + namespace content { ++namespace { ++ void SkiaPreCacheFont(const LOGFONT& logfont) { ++ RenderThread* render_thread = RenderThread::Get(); ++ if (render_thread) render_thread->PreCacheFont(logfont); ++ } ++} + + RendererMainPlatformDelegate::RendererMainPlatformDelegate( + const MainFunctionParams& parameters) +@@ -50,13 +56,14 @@ void RendererMainPlatformDelegate::PlatformInitialize() { + // cached and there's no more need to access the registry. If the sandbox + // is disabled, we don't have to make this dummy call. + std::unique_ptr zone(icu::TimeZone::createDefault()); ++ SkTypeface_SetEnsureLOGFONTAccessibleProc(SkiaPreCacheFont); + } + +- InitializeDWriteFontProxy(); ++ // InitializeDWriteFontProxy(); + } + + void RendererMainPlatformDelegate::PlatformUninitialize() { +- UninitializeDWriteFontProxy(); ++ // UninitializeDWriteFontProxy(); + } + + bool RendererMainPlatformDelegate::EnableSandbox() { +diff --git a/mod/base/no_destructor.h b/mod/base/no_destructor.h +new file mode 100644 +index 0000000000000..21cfef8565dd1 +--- /dev/null ++++ b/mod/base/no_destructor.h +@@ -0,0 +1,98 @@ ++// Copyright 2018 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. ++ ++#ifndef BASE_NO_DESTRUCTOR_H_ ++#define BASE_NO_DESTRUCTOR_H_ ++ ++#include ++#include ++ ++namespace base { ++ ++// A wrapper that makes it easy to create an object of type T with static ++// storage duration that: ++// - is only constructed on first access ++// - never invokes the destructor ++// in order to satisfy the styleguide ban on global constructors and ++// destructors. ++// ++// Runtime constant example: ++// const std::string& GetLineSeparator() { ++// // Forwards to std::string(size_t, char, const Allocator&) constructor. ++// static const base::NoDestructor s(5, '-'); ++// return *s; ++// } ++// ++// More complex initialization with a lambda: ++// const std::string& GetSessionNonce() { ++// static const base::NoDestructor nonce([] { ++// std::string s(16); ++// crypto::RandString(s.data(), s.size()); ++// return s; ++// }()); ++// return *nonce; ++// } ++// ++// NoDestructor stores the object inline, so it also avoids a pointer ++// indirection and a malloc. Also note that since C++11 static local variable ++// initialization is thread-safe and so is this pattern. Code should prefer to ++// use NoDestructor over: ++// - A function scoped static T* or T& that is dynamically initialized. ++// - A global base::LazyInstance. ++// ++// Note that since the destructor is never run, this *will* leak memory if used ++// as a stack or member variable. Furthermore, a NoDestructor should never ++// have global scope as that may require a static initializer. ++template ++class NoDestructor { ++ public: ++ // Not constexpr; just write static constexpr T x = ...; if the value should ++ // be a constexpr. ++ template ++ explicit NoDestructor(Args&&... args) { ++ new (storage_) T(std::forward(args)...); ++ } ++ ++ // Allows copy and move construction of the contained type, to allow ++ // construction from an initializer list, e.g. for std::vector. ++ explicit NoDestructor(const T& x) { new (storage_) T(x); } ++ explicit NoDestructor(T&& x) { new (storage_) T(std::move(x)); } ++ ++ NoDestructor(const NoDestructor&) = delete; ++ NoDestructor& operator=(const NoDestructor&) = delete; ++ ++ ~NoDestructor() = default; ++ ++ const T& operator*() const { return *get(); } ++ T& operator*() { return *get(); } ++ ++ const T* operator->() const { return get(); } ++ T* operator->() { return get(); } ++ ++ const T* get() const { return reinterpret_cast(storage_); } ++ T* get() { return reinterpret_cast(storage_); } ++ ++ private: ++ alignas(T) char storage_[sizeof(T)]; ++ ++#if defined(LEAK_SANITIZER) ++ // TODO(https://crbug.com/812277): This is a hack to work around the fact ++ // that LSan doesn't seem to treat NoDestructor as a root for reachability ++ // analysis. This means that code like this: ++ // static base::NoDestructor> v({1, 2, 3}); ++ // is considered a leak. Using the standard leak sanitizer annotations to ++ // suppress leaks doesn't work: std::vector is implicitly constructed before ++ // calling the base::NoDestructor constructor. ++ // ++ // Unfortunately, I haven't been able to demonstrate this issue in simpler ++ // reproductions: until that's resolved, hold an explicit pointer to the ++ // placement-new'd object in leak sanitizer mode to help LSan realize that ++ // objects allocated by the contained type are still reachable. ++ T* storage_ptr_ = reinterpret_cast(storage_); ++#endif // defined(LEAK_SANITIZER) ++}; ++ ++} // namespace base ++ ++#endif // BASE_NO_DESTRUCTOR_H_ +diff --git a/mod/third_party/skia/include/core/SkFontLCDConfig.h b/mod/third_party/skia/include/core/SkFontLCDConfig.h +new file mode 100644 +index 0000000000000..6cdbaf740300b +--- /dev/null ++++ b/mod/third_party/skia/include/core/SkFontLCDConfig.h +@@ -0,0 +1,58 @@ ++/* ++ * Copyright 2013 Google Inc. ++ * ++ * Use of this source code is governed by a BSD-style license that can be ++ * found in the LICENSE file. ++ */ ++ ++#ifndef SkFontLCDConfig_DEFINED ++#define SkFontLCDConfig_DEFINED ++ ++#include "third_party/skia/include/core/SkTypes.h" ++ ++class SK_API SkFontLCDConfig { ++public: ++ /** LCDs either have their color elements arranged horizontally or ++ vertically. When rendering subpixel glyphs we need to know which way ++ round they are. ++ ++ Note, if you change this after startup, you'll need to flush the glyph ++ cache because it'll have the wrong type of masks cached. ++ ++ @deprecated use SkPixelGeometry instead. ++ */ ++ enum LCDOrientation { ++ kHorizontal_LCDOrientation = 0, //!< this is the default ++ kVertical_LCDOrientation = 1, ++ }; ++ ++ /** @deprecated set on Device creation. */ ++ static void SetSubpixelOrientation(LCDOrientation orientation); ++ /** @deprecated get from Device. */ ++ static LCDOrientation GetSubpixelOrientation(); ++ ++ /** LCD color elements can vary in order. For subpixel text we need to know ++ the order which the LCDs uses so that the color fringes are in the ++ correct place. ++ ++ Note, if you change this after startup, you'll need to flush the glyph ++ cache because it'll have the wrong type of masks cached. ++ ++ kNONE_LCDOrder means that the subpixel elements are not spatially ++ separated in any usable fashion. ++ ++ @deprecated use SkPixelGeometry instead. ++ */ ++ enum LCDOrder { ++ kRGB_LCDOrder = 0, //!< this is the default ++ kBGR_LCDOrder = 1, ++ kNONE_LCDOrder = 2, ++ }; ++ ++ /** @deprecated set on Device creation. */ ++ static void SetSubpixelOrder(LCDOrder order); ++ /** @deprecated get from Device. */ ++ static LCDOrder GetSubpixelOrder(); ++}; ++ ++#endif +diff --git a/mod/ui/gfx/platform_font_win.cc b/mod/ui/gfx/platform_font_win.cc +new file mode 100644 +index 0000000000000..46b09a22abd1f +--- /dev/null ++++ b/mod/ui/gfx/platform_font_win.cc +@@ -0,0 +1,595 @@ ++// Copyright (c) 2012 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 "mod/base/no_destructor.h" ++#include "mod/ui/gfx/platform_font_win.h" ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "base/containers/flat_map.h" ++#include "base/debug/alias.h" ++#include "base/feature_list.h" ++#include "base/logging.h" ++#include "base/stl_util.h" ++#include "base/strings/string_util.h" ++#include "base/strings/sys_string_conversions.h" ++#include "base/strings/utf_string_conversions.h" ++#include "base/trace_event/trace_event.h" ++#include "base/win/scoped_gdi_object.h" ++#include "base/win/scoped_hdc.h" ++#include "base/win/scoped_select_object.h" ++#include "mod/third_party/skia/include/core/SkFontLCDConfig.h" ++#include "third_party/skia/include/core/SkFontMetrics.h" ++#include "third_party/skia/include/core/SkRefCnt.h" ++#include "third_party/skia/include/core/SkTypeface.h" ++#include "ui/gfx/canvas.h" ++#include "ui/gfx/font.h" ++#include "ui/gfx/font_render_params.h" ++#include "ui/gfx/platform_font_skia.h" ++#include "ui/gfx/system_fonts_win.h" ++#include "ui/gfx/win/direct_write.h" ++#include "ui/gfx/win/scoped_set_map_mode.h" ++ ++namespace { ++ ++// Sets style properties on |font_info| based on |font_style|. ++void SetLogFontStyle(int font_style, LOGFONT* font_info) { ++ font_info->lfUnderline = (font_style & gfx::Font::UNDERLINE) != 0; ++ font_info->lfItalic = (font_style & gfx::Font::ITALIC) != 0; ++} ++gfx::Font::Weight ToGfxFontWeight(int weight) { ++ return static_cast(weight); ++} ++// Uses the GDI interop functionality exposed by DirectWrite to find a ++// matching DirectWrite font for the LOGFONT passed in. If we fail to ++// find a direct match then we try the DirectWrite font substitution ++// route to find a match. ++// The contents of the LOGFONT pointer |font_info| may be modified on ++// return. ++/* ++HRESULT FindDirectWriteFontForLOGFONT(IDWriteFactory* factory, ++ LOGFONT* font_info, ++ IDWriteFont** dwrite_font) { ++ TRACE_EVENT0("fonts", "gfx::FindDirectWriteFontForLOGFONT"); ++ Microsoft::WRL::ComPtr gdi_interop; ++ HRESULT hr = factory->GetGdiInterop(gdi_interop.GetAddressOf()); ++ if (FAILED(hr)) { ++ CHECK(false); ++ return hr; ++ } ++ hr = gdi_interop->CreateFontFromLOGFONT(font_info, dwrite_font); ++ if (SUCCEEDED(hr)) ++ return hr; ++ Microsoft::WRL::ComPtr font_collection; ++ hr = factory->GetSystemFontCollection(font_collection.GetAddressOf()); ++ if (FAILED(hr)) ++ return hr; ++ // We try to find a matching font by triggering DirectWrite to substitute the ++ // font passed in with a matching font (FontSubstitutes registry key) ++ // If this succeeds we return the matched font. ++ base::win::ScopedGDIObject font(::CreateFontIndirect(font_info)); ++ base::win::ScopedGetDC screen_dc(NULL); ++ base::win::ScopedSelectObject scoped_font(screen_dc, font.get()); ++ Microsoft::WRL::ComPtr font_face; ++ hr = gdi_interop->CreateFontFaceFromHdc(screen_dc, font_face.GetAddressOf()); ++ if (FAILED(hr)) ++ return hr; ++ LOGFONT converted_font = {0}; ++ hr = gdi_interop->ConvertFontFaceToLOGFONT(font_face.Get(), &converted_font); ++ if (SUCCEEDED(hr)) { ++ hr = font_collection->GetFontFromFontFace(font_face.Get(), dwrite_font); ++ if (SUCCEEDED(hr)) { ++ wcscpy_s(font_info->lfFaceName, base::size(font_info->lfFaceName), ++ converted_font.lfFaceName); ++ } ++ } ++ return hr; ++} ++*/ ++// Returns a matching IDWriteFont for the |font_info| passed in. If we fail ++// to find a matching font, then we return the IDWriteFont corresponding to ++// the default font on the system. ++// Returns S_OK on success. ++// The contents of the LOGFONT pointer |font_info| may be modified on ++// return. ++/* ++HRESULT GetMatchingDirectWriteFont(LOGFONT* font_info, ++ bool italic, ++ IDWriteFactory* factory, ++ IDWriteFont** dwrite_font) { ++ TRACE_EVENT0("fonts", "gfx::GetMatchingDirectWriteFont"); ++ // First try the GDI compat route to get a matching DirectWrite font. ++ // If that succeeds then we are good. If that fails then try and find a ++ // match from the DirectWrite font collection. ++ HRESULT hr = FindDirectWriteFontForLOGFONT(factory, font_info, dwrite_font); ++ if (SUCCEEDED(hr)) ++ return hr; ++ // Get a matching font from the system font collection exposed by ++ // DirectWrite. ++ Microsoft::WRL::ComPtr font_collection; ++ hr = factory->GetSystemFontCollection(font_collection.GetAddressOf()); ++ if (FAILED(hr)) { ++ // On some old windows, the call to GetSystemFontCollection may fail. ++ return hr; ++ } ++ // Steps as below:- ++ // This mirrors skia. ++ // 1. Attempt to find a DirectWrite font family based on the face name in the ++ // font. That may not work at all times, as the face name could be random ++ // GDI has its own font system where in it creates a font matching the ++ // characteristics in the LOGFONT structure passed into ++ // CreateFontIndirect. DirectWrite does not do that. If this succeeds then ++ // return the matching IDWriteFont from the family. ++ // 2. If step 1 fails then repeat with the default system font. This has the ++ // same limitations with the face name as mentioned above. ++ // 3. If step 2 fails then return the first family from the collection and ++ // use that. ++ Microsoft::WRL::ComPtr font_family; ++ BOOL exists = FALSE; ++ uint32_t index = 0; ++ hr = font_collection->FindFamilyName(font_info->lfFaceName, &index, &exists); ++ // If we fail to find a match then try fallback to the default font on the ++ // system. This is what skia does as well. ++ if (FAILED(hr) || (index == UINT_MAX) || !exists) { ++ NONCLIENTMETRICS metrics = {0}; ++ metrics.cbSize = sizeof(metrics); ++ if (!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, ++ sizeof(metrics), ++ &metrics, ++ 0)) { ++ CHECK(false); ++ return E_FAIL; ++ } ++ if (wcsncmp(font_info->lfFaceName, metrics.lfMessageFont.lfFaceName, ++ base::size(font_info->lfFaceName))) { ++ // First try the GDI compat route to get a matching DirectWrite font. If ++ // that succeeds we are good. If not find a matching font from the font ++ // collection. ++ wcscpy_s(font_info->lfFaceName, base::size(font_info->lfFaceName), ++ metrics.lfMessageFont.lfFaceName); ++ hr = FindDirectWriteFontForLOGFONT(factory, font_info, dwrite_font); ++ if (SUCCEEDED(hr)) ++ return hr; ++ // Best effort to find a matching font from the system font collection. ++ hr = font_collection->FindFamilyName(metrics.lfMessageFont.lfFaceName, ++ &index, ++ &exists); ++ } ++ } ++ if (index != UINT_MAX && exists) { ++ hr = font_collection->GetFontFamily(index, font_family.GetAddressOf()); ++ } else { ++ // If we fail to find a matching font, then fallback to the first font in ++ // the list. This is what skia does as well. ++ hr = font_collection->GetFontFamily(0, font_family.GetAddressOf()); ++ } ++ if (FAILED(hr)) { ++ CHECK(false); ++ return hr; ++ } ++ DWRITE_FONT_WEIGHT weight = ++ static_cast(font_info->lfWeight); ++ DWRITE_FONT_STRETCH stretch = DWRITE_FONT_STRETCH_NORMAL; ++ DWRITE_FONT_STYLE style = ++ (italic) ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL; ++ // The IDWriteFontFamily::GetFirstMatchingFont call fails on certain machines ++ // for fonts like MS UI Gothic, Segoe UI, etc. It is not clear why these ++ // fonts could be accessible to GDI and not to DirectWrite. ++ // The code below adds some debug fields to help track down these failures. ++ // 1. We get the matching font list for the font attributes passed in. ++ // 2. We get the font count in the family with a debug alias variable. ++ // 3. If GetFirstMatchingFont fails then we CHECK as before. ++ // Next step would be to remove the CHECKs in this function and fallback to ++ // GDI. ++ // http://crbug.com/434425 ++ // TODO(ananta) ++ // Remove the GetMatchingFonts and related code here once we get to a stable ++ // state in canary. ++ Microsoft::WRL::ComPtr matching_font_list; ++ hr = font_family->GetMatchingFonts(weight, stretch, style, ++ matching_font_list.GetAddressOf()); ++ uint32_t matching_font_count = 0; ++ if (SUCCEEDED(hr)) ++ matching_font_count = matching_font_list->GetFontCount(); ++ hr = font_family->GetFirstMatchingFont(weight, stretch, style, dwrite_font); ++ if (FAILED(hr)) { ++ base::debug::Alias(&matching_font_count); ++ CHECK(false); ++ } ++ base::string16 font_name; ++ gfx::GetFamilyNameFromDirectWriteFont(*dwrite_font, &font_name); ++ wcscpy_s(font_info->lfFaceName, base::size(font_info->lfFaceName), ++ font_name.c_str()); ++ return hr; ++} ++*/ ++} // namespace ++namespace gfx { ++// Enable the use of PlatformFontSkia instead of PlatformFontWin. ++const base::Feature kPlatformFontSkiaOnWindows{ ++ "PlatformFontSkiaOnWindows", base::FEATURE_ENABLED_BY_DEFAULT}; ++// static ++PlatformFontWin::HFontRef* PlatformFontWin::base_font_ref_; ++// TODO(ananta) ++// Remove the CHECKs in this function once this stabilizes on the field. ++// HRESULT GetFamilyNameFromDirectWriteFont(IDWriteFont* dwrite_font, ++// base::string16* family_name) { ++// Microsoft::WRL::ComPtr font_family; ++// HRESULT hr = dwrite_font->GetFontFamily(font_family.GetAddressOf()); ++// if (FAILED(hr)) ++// CHECK(false); ++// Microsoft::WRL::ComPtr family_names; ++// hr = font_family->GetFamilyNames(family_names.GetAddressOf()); ++// if (FAILED(hr)) ++// CHECK(false); ++// // TODO(ananta) ++// // Add support for retrieving the family for the current locale. ++// wchar_t family_name_for_locale[MAX_PATH] = {0}; ++// hr = family_names->GetString(0, family_name_for_locale, ++// base::size(family_name_for_locale)); ++// if (FAILED(hr)) ++// CHECK(false); ++// *family_name = family_name_for_locale; ++// return hr; ++// } ++//////////////////////////////////////////////////////////////////////////////// ++// PlatformFontWin, public ++PlatformFontWin::PlatformFontWin() : font_ref_(GetBaseFontRef()) { ++} ++PlatformFontWin::PlatformFontWin(const std::string& font_name, int font_size) { ++ InitWithFontNameAndSize(font_name, font_size); ++} ++PlatformFontWin::PlatformFontWin(sk_sp typeface, ++ int font_size_pixels, ++ const absl::optional& params) ++ : typeface_(std::move(typeface)) { ++ DCHECK(typeface_); ++ // TODO(http://crbug.com/944227): This is a transitional code path until we ++ // complete migrating to PlatformFontSkia on Windows. Being unable to wrap the ++ // SkTypeface into a PlatformFontSkia and performing a rematching by font ++ // family name instead loses platform font handles encapsulated in SkTypeface, ++ // and in turn leads to instantiating a different font than what was returned ++ // by font fallback, compare https://crbug.com/1003829. ++ SkString family_name; ++ typeface_->getFamilyName(&family_name); ++ InitWithFontNameAndSize(family_name.c_str(), font_size_pixels); ++} ++//////////////////////////////////////////////////////////////////////////////// ++// PlatformFontWin, PlatformFont implementation: ++Font PlatformFontWin::DeriveFont(int size_delta, ++ int style, ++ Font::Weight weight) const { ++ LOGFONT font_info; ++ GetObject(GetNativeFont(), sizeof(LOGFONT), &font_info); ++ const int requested_font_size = font_ref_->requested_font_size(); ++ font_info.lfHeight = win::AdjustFontSize(-requested_font_size, size_delta); ++ font_info.lfWeight = static_cast(weight); ++ SetLogFontStyle(style, &font_info); ++ HFONT hfont = CreateFontIndirect(&font_info); ++ return Font(new PlatformFontWin(CreateHFontRef(hfont))); ++} ++int PlatformFontWin::GetHeight() { ++ return font_ref_->height(); ++} ++Font::Weight PlatformFontWin::GetWeight() const { ++ return font_ref_->weight(); ++} ++int PlatformFontWin::GetBaseline() { ++ return font_ref_->baseline(); ++} ++int PlatformFontWin::GetCapHeight() { ++ return font_ref_->cap_height(); ++} ++int PlatformFontWin::GetExpectedTextWidth(int length) { ++ return length * std::min(font_ref_->GetDluBaseX(), ++ font_ref_->ave_char_width()); ++} ++int PlatformFontWin::GetStyle() const { ++ return font_ref_->style(); ++} ++const std::string& PlatformFontWin::GetFontName() const { ++ return font_ref_->font_name(); ++} ++std::string PlatformFontWin::GetActualFontName() const { ++ // With the current implementation on Windows, HFontRef::font_name() returns ++ // the font name taken from the HFONT handle, but it's not the name that comes ++ // from the font's metadata. See http://crbug.com/327287 ++ return font_ref_->font_name(); ++} ++std::string PlatformFontWin::GetLocalizedFontName() const { ++ base::win::ScopedCreateDC memory_dc(CreateCompatibleDC(NULL)); ++ if (!memory_dc.Get()) ++ return GetFontName(); ++ // When a font has a localized name for a language matching the system ++ // locale, GetTextFace() returns the localized name. ++ base::win::ScopedSelectObject font(memory_dc.Get(), font_ref_->hfont()); ++ wchar_t localized_font_name[LF_FACESIZE]; ++ int length = GetTextFace(memory_dc.Get(), base::size(localized_font_name), ++ &localized_font_name[0]); ++ if (length <= 0) ++ return GetFontName(); ++ return base::SysWideToUTF8(localized_font_name); ++} ++int PlatformFontWin::GetFontSize() const { ++ return font_ref_->font_size(); ++} ++const FontRenderParams& PlatformFontWin::GetFontRenderParams() { ++ static const base::NoDestructor params( ++ gfx::GetFontRenderParams(FontRenderParamsQuery(), nullptr)); ++ return *params; ++} ++sk_sp PlatformFontWin::GetNativeSkTypeface() const { // was GetNativeSkTypefaceIfAvailable() ++ return sk_sp(typeface_); ++} ++NativeFont PlatformFontWin::GetNativeFont() const { ++ return font_ref_->hfont(); ++} ++//////////////////////////////////////////////////////////////////////////////// ++// Font, private: ++void PlatformFontWin::InitWithCopyOfHFONT(HFONT hfont) { ++ DCHECK(hfont); ++ LOGFONT font_info; ++ GetObject(hfont, sizeof(LOGFONT), &font_info); ++ font_ref_ = CreateHFontRef(CreateFontIndirect(&font_info)); ++} ++ ++ ++void PlatformFontWin::InitWithFontNameAndSize(const std::string& font_name, ++ int font_size) { ++ ++ std::wstring_convert> convert; ++ HFONT hf = ::CreateFont(-font_size, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ++ DEFAULT_CHARSET, ++ OUT_DEFAULT_PRECIS, ++ CLIP_DEFAULT_PRECIS, ++ DEFAULT_QUALITY, ++ DEFAULT_PITCH | FF_DONTCARE, ++ convert.from_bytes(font_name).c_str()); ++ font_ref_ = CreateHFontRef(hf); ++} ++// static ++void PlatformFontWin::GetTextMetricsForFont(HDC hdc, ++ HFONT font, ++ TEXTMETRIC* text_metrics) { ++ base::win::ScopedSelectObject scoped_font(hdc, font); ++ GetTextMetrics(hdc, text_metrics); ++} ++// static ++PlatformFontWin::HFontRef* PlatformFontWin::GetBaseFontRef() { ++ if (base_font_ref_ == nullptr) { ++ // We'll delegate to our SystemFonts instance to give us the default ++ // message font. ++ PlatformFontWin* message_font = static_cast( ++ win::GetSystemFont(win::SystemFont::kMessage).platform_font()); ++ base_font_ref_ = message_font->font_ref_.get(); ++ } ++ return base_font_ref_; ++} ++PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRef(HFONT font) { ++ TRACE_EVENT0("fonts", "PlatformFont::CreateHFontRef"); ++ TEXTMETRIC font_metrics; ++ { ++ base::win::ScopedGetDC screen_dc(NULL); ++ ScopedSetMapMode mode(screen_dc, MM_TEXT); ++ GetTextMetricsForFont(screen_dc, font, &font_metrics); ++ } ++ return CreateHFontRefFromSkia(font, font_metrics); ++} ++PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRefFromGDI( ++ HFONT font, ++ const TEXTMETRIC& font_metrics) { ++ TRACE_EVENT0("fonts", "PlatformFontWin::CreateHFontRefFromGDI"); ++ const int height = std::max(1, font_metrics.tmHeight); ++ const int baseline = std::max(1, font_metrics.tmAscent); ++ const int cap_height = ++ std::max(1, font_metrics.tmAscent - font_metrics.tmInternalLeading); ++ const int ave_char_width = std::max(1, font_metrics.tmAveCharWidth); ++ const int font_size = ++ std::max(1, font_metrics.tmHeight - font_metrics.tmInternalLeading); ++ int style = 0; ++ if (font_metrics.tmItalic) ++ style |= Font::ITALIC; ++ if (font_metrics.tmUnderlined) ++ style |= Font::UNDERLINE; ++ return new HFontRef(font, font_size, height, baseline, cap_height, ++ ave_char_width, ToGfxFontWeight(font_metrics.tmWeight), ++ style); ++} ++// static ++PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRefFromSkia( ++ HFONT gdi_font, ++ const TEXTMETRIC& font_metrics) { ++ TRACE_EVENT0("fonts", "PlatformFontWin::CreateHFontRefFromSkia"); ++ LOGFONT font_info = {0}; ++ GetObject(gdi_font, sizeof(LOGFONT), &font_info); ++ // If the font height is passed in as 0, assume the height to be -1 to ensure ++ // that we return the metrics for a 1 point font. ++ // If the font height is positive it represents the rasterized font's cell ++ // height. Calculate the actual height accordingly. ++ if (font_info.lfHeight > 0) { ++ font_info.lfHeight = ++ font_metrics.tmInternalLeading - font_metrics.tmHeight; ++ } else if (font_info.lfHeight == 0) { ++ font_info.lfHeight = -1; ++ } ++ if (font_info.lfWeight == 0) { ++ font_info.lfWeight = static_cast(Font::Weight::NORMAL); ++ } ++ // const bool italic = font_info.lfItalic != 0; ++ // Skia does not return all values we need for font metrics. For e.g. ++ // the cap height which indicates the height of capital letters is not ++ // returned even though it is returned by DirectWrite. ++ // TODO(ananta) ++ // Fix SkScalerContext_win_dw.cpp to return all metrics we need from ++ // DirectWrite and remove the code here which retrieves metrics from ++ // DirectWrite to calculate the cap height. ++ return CreateHFontRefFromGDI(gdi_font, font_metrics); // test ++/* ++ Microsoft::WRL::ComPtr dwrite_font; ++ HRESULT hr = GetMatchingDirectWriteFont( ++ &font_info, italic, win::GetDirectWriteFactory(), &dwrite_font); ++ if (FAILED(hr)) { ++ // If we are not able to find a font using Direct Write, fallback to ++ // the old GDI font. ++ return CreateHFontRefFromGDI(gdi_font, font_metrics); ++ } ++ DWRITE_FONT_METRICS dwrite_font_metrics = {0}; ++ dwrite_font->GetMetrics(&dwrite_font_metrics); ++ SkFontStyle skia_font_style(font_info.lfWeight, SkFontStyle::kNormal_Width, ++ font_info.lfItalic ? SkFontStyle::kItalic_Slant ++ : SkFontStyle::kUpright_Slant); ++ sk_sp skia_face( ++ SkTypeface::MakeFromName( ++ base::SysWideToUTF8(font_info.lfFaceName).c_str(), ++ skia_font_style)); ++ FontRenderParams font_params = ++ gfx::GetFontRenderParams(FontRenderParamsQuery(), nullptr); ++ SkFontLCDConfig::SetSubpixelOrder( ++ FontRenderParams::SubpixelRenderingToSkiaLCDOrder( ++ font_params.subpixel_rendering)); ++ SkFontLCDConfig::SetSubpixelOrientation( ++ FontRenderParams::SubpixelRenderingToSkiaLCDOrientation( ++ font_params.subpixel_rendering)); ++ SkFont font(std::move(skia_face), -font_info.lfHeight); ++ font.setEdging(font_params.antialiasing ? SkFont::Edging::kAntiAlias ++ : SkFont::Edging::kAlias); ++ SkFontMetrics skia_metrics; ++ font.getMetrics(&skia_metrics); ++ // The calculations below are similar to those in the CreateHFontRef ++ // function. The height, baseline and cap height are rounded up to ensure ++ // that they match up closely with GDI. ++ const int height = std::ceil(skia_metrics.fDescent - skia_metrics.fAscent); ++ const int baseline = std::max(1, std::ceil(-skia_metrics.fAscent)); ++ const int cap_height = std::ceil( ++ font.getSize() * static_cast(dwrite_font_metrics.capHeight) / ++ dwrite_font_metrics.designUnitsPerEm); ++ // The metrics retrieved from skia don't have the average character width. In ++ // any case if we get the average character width from skia then use that or ++ // the average character width in the TEXTMETRIC structure. ++ // TODO(ananta): Investigate whether it is possible to retrieve this value ++ // from DirectWrite. ++ const int ave_char_width = ++ skia_metrics.fAvgCharWidth == 0 ? font_metrics.tmAveCharWidth ++ : skia_metrics.fAvgCharWidth; ++ int style = 0; ++ if (italic) ++ style |= Font::ITALIC; ++ if (font_info.lfUnderline) ++ style |= Font::UNDERLINE; ++ // DirectWrite may have substituted the GDI font name with a fallback ++ // font. Ensure that it is updated here. ++ DeleteObject(gdi_font); ++ gdi_font = ::CreateFontIndirect(&font_info); ++ return new HFontRef(gdi_font, -font_info.lfHeight, height, baseline, ++ cap_height, ave_char_width, ++ ToGfxFontWeight(font_info.lfWeight), style); ++ */ ++} ++// static ++Font PlatformFontWin::HFontToFont(HFONT hfont) { ++ return Font(new PlatformFontWin(CreateHFontRef(hfont))); ++} ++PlatformFontWin::PlatformFontWin(HFontRef* hfont_ref) : font_ref_(hfont_ref) { ++} ++PlatformFontWin::PlatformFontWin(NativeFont native_font) { ++ InitWithCopyOfHFONT(native_font); ++} ++PlatformFontWin::~PlatformFontWin() { ++} ++//////////////////////////////////////////////////////////////////////////////// ++// PlatformFontWin::HFontRef: ++PlatformFontWin::HFontRef::HFontRef(HFONT hfont, ++ int font_size, ++ int height, ++ int baseline, ++ int cap_height, ++ int ave_char_width, ++ Font::Weight weight, ++ int style) ++ : hfont_(hfont), ++ font_size_(font_size), ++ height_(height), ++ baseline_(baseline), ++ cap_height_(cap_height), ++ ave_char_width_(ave_char_width), ++ weight_(weight), ++ style_(style), ++ dlu_base_x_(-1), ++ requested_font_size_(font_size) { ++ DLOG_ASSERT(hfont); ++ LOGFONT font_info; ++ GetObject(hfont_, sizeof(LOGFONT), &font_info); ++ ++ std::wstring_convert> convert; ++ font_name_ = convert.to_bytes(font_info.lfFaceName); ++ ++ // Retrieve the font size from the GetTextMetrics API instead of referencing ++ // it from the LOGFONT structure. This is because the height as reported by ++ // the LOGFONT structure is not always correct. For small fonts with size 1 ++ // the LOGFONT structure reports the height as -1, while the actual font size ++ // is different. (2 on my XP machine). ++ base::win::ScopedGetDC screen_dc(NULL); ++ TEXTMETRIC font_metrics = {0}; ++ PlatformFontWin::GetTextMetricsForFont(screen_dc, hfont_, &font_metrics); ++ requested_font_size_ = font_metrics.tmHeight - font_metrics.tmInternalLeading; ++} ++int PlatformFontWin::HFontRef::GetDluBaseX() { ++ if (dlu_base_x_ != -1) ++ return dlu_base_x_; ++ dlu_base_x_ = GetAverageCharWidthInDialogUnits(hfont_); ++ return dlu_base_x_; ++} ++// static ++int PlatformFontWin::HFontRef::GetAverageCharWidthInDialogUnits( ++ HFONT gdi_font) { ++ base::win::ScopedGetDC screen_dc(NULL); ++ base::win::ScopedSelectObject font(screen_dc, gdi_font); ++ ScopedSetMapMode mode(screen_dc, MM_TEXT); ++ // Yes, this is how Microsoft recommends calculating the dialog unit ++ // conversions. See: http://support.microsoft.com/kb/125681 ++ SIZE ave_text_size; ++ GetTextExtentPoint32(screen_dc, ++ L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", ++ 52, &ave_text_size); ++ int dlu_base_x = (ave_text_size.cx / 26 + 1) / 2; ++ DCHECK_NE(dlu_base_x, -1); ++ return dlu_base_x; ++} ++PlatformFontWin::HFontRef::~HFontRef() { ++ DeleteObject(hfont_); ++} ++//////////////////////////////////////////////////////////////////////////////// ++// PlatformFont, public: ++// static ++PlatformFont* PlatformFont::CreateDefault() { ++// if (base::FeatureList::IsEnabled(kPlatformFontSkiaOnWindows)) // turned off ++ // return new PlatformFontSkia; ++ return new PlatformFontWin; ++} ++// static ++PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name, ++ int font_size) { ++ TRACE_EVENT0("fonts", "PlatformFont::CreateFromNameAndSize"); ++ // if (base::FeatureList::IsEnabled(kPlatformFontSkiaOnWindows)) // turned off ++ // return new PlatformFontSkia(font_name, font_size); ++ return new PlatformFontWin(font_name, font_size); ++} ++// static ++PlatformFont* PlatformFont::CreateFromSkTypeface( ++ sk_sp typeface, ++ int font_size, ++ const absl::optional& params) { ++ TRACE_EVENT0("fonts", "PlatformFont::CreateFromSkTypeface"); ++ // if (base::FeatureList::IsEnabled(kPlatformFontSkiaOnWindows)) // turned off ++ // return new PlatformFontSkia(typeface, font_size, params); ++ return new PlatformFontWin(typeface, font_size, params); ++} ++ ++} // namespace gfx +\ No newline at end of file +diff --git a/mod/ui/gfx/platform_font_win.h b/mod/ui/gfx/platform_font_win.h +new file mode 100644 +index 0000000000000..660d89ba995b6 +--- /dev/null ++++ b/mod/ui/gfx/platform_font_win.h +@@ -0,0 +1,178 @@ ++// Copyright (c) 2012 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. ++#ifndef UI_GFX_PLATFORM_FONT_WIN_H_ ++#define UI_GFX_PLATFORM_FONT_WIN_H_ ++#include ++#include ++#include "base/compiler_specific.h" ++#include "base/feature_list.h" ++#include "base/gtest_prod_util.h" ++#include "base/macros.h" ++#include "base/memory/ref_counted.h" ++// #include "mod/base/strings/string16.h" ++#include "third_party/skia/include/core/SkTypeface.h" ++#include "ui/gfx/gfx_export.h" ++#include "ui/gfx/platform_font.h" ++struct IDWriteFactory; ++struct IDWriteFont; ++namespace gfx { ++// Deprecation of PlatformFontWin (See http://crbug.com/944227). ++extern GFX_EXPORT const base::Feature kPlatformFontSkiaOnWindows; ++class GFX_EXPORT PlatformFontWin : public PlatformFont { ++ public: ++ PlatformFontWin(); ++ PlatformFontWin(const std::string& font_name, int font_size); ++ // Wraps the provided SkTypeface without triggering a font rematch. ++ PlatformFontWin(sk_sp typeface, ++ int font_size_pixels, ++ const absl::optional& params); ++ // Dialog units to pixels conversion. ++ // See http://support.microsoft.com/kb/145994 for details. ++ int horizontal_dlus_to_pixels(int dlus) const { ++ return dlus * font_ref_->GetDluBaseX() / 4; ++ } ++ int vertical_dlus_to_pixels(int dlus) const { ++ return dlus * font_ref_->height() / 8; ++ } ++ // Returns the font name for the system locale. Some fonts, particularly ++ // East Asian fonts, have different names per locale. If the localized font ++ // name could not be retrieved, returns GetFontName(). ++ std::string GetLocalizedFontName() const; ++ // Overridden from PlatformFont: ++ Font DeriveFont(int size_delta, ++ int style, ++ Font::Weight weight) const override; ++ int GetHeight() override; ++ Font::Weight GetWeight() const override; ++ int GetBaseline() override; ++ int GetCapHeight() override; ++ int GetExpectedTextWidth(int length) override; ++ int GetStyle() const override; ++ const std::string& GetFontName() const override; ++ std::string GetActualFontName() const override; ++ int GetFontSize() const override; ++ const FontRenderParams& GetFontRenderParams() override; ++ sk_sp GetNativeSkTypeface() const override; // was GetNativeSkTypefaceIfAvailable() ++ NativeFont GetNativeFont() const; ++ // Called once during initialization if we should be retrieving font metrics ++ // from skia and DirectWrite. ++ static void SetDirectWriteFactory(IDWriteFactory* factory); ++ private: ++ FRIEND_TEST_ALL_PREFIXES(PlatformFontWinTest, Metrics_SkiaVersusGDI); ++ FRIEND_TEST_ALL_PREFIXES(PlatformFontWinTest, DirectWriteFontSubstitution); ++ explicit PlatformFontWin(NativeFont native_font); ++ ~PlatformFontWin() override; ++ // Chrome text drawing bottoms out in the Windows GDI functions that take an ++ // HFONT (an opaque handle into Windows). To avoid lots of GDI object ++ // allocation and destruction, Font indirectly refers to the HFONT by way of ++ // an HFontRef. That is, every Font has an HFontRef, which has an HFONT. ++ // ++ // HFontRef is reference counted. Upon deletion, it deletes the HFONT. ++ // By making HFontRef maintain the reference to the HFONT, multiple ++ // HFontRefs can share the same HFONT, and Font can provide value semantics. ++ class GFX_EXPORT HFontRef : public base::RefCounted { ++ public: ++ // This constructor takes control of the HFONT, and will delete it when ++ // the HFontRef is deleted. ++ HFontRef(HFONT hfont, ++ int font_size, ++ int height, ++ int baseline, ++ int cap_height, ++ int ave_char_width, ++ Font::Weight weight, ++ int style); ++ // Accessors ++ HFONT hfont() const { return hfont_; } ++ int height() const { return height_; } ++ int baseline() const { return baseline_; } ++ int cap_height() const { return cap_height_; } ++ int ave_char_width() const { return ave_char_width_; } ++ Font::Weight weight() const { return weight_; } ++ int style() const { return style_; } ++ const std::string& font_name() const { return font_name_; } ++ int font_size() const { return font_size_; } ++ int requested_font_size() const { return requested_font_size_; } ++ // Returns the average character width in dialog units. ++ int GetDluBaseX(); ++ // Helper to return the average character width using the text extent ++ // technique mentioned here. http://support.microsoft.com/kb/125681. ++ static int GetAverageCharWidthInDialogUnits(HFONT gdi_font); ++ private: ++ friend class base::RefCounted; ++ FRIEND_TEST_ALL_PREFIXES(PlatformFontWinTest, Metrics_SkiaVersusGDI); ++ FRIEND_TEST_ALL_PREFIXES(PlatformFontWinTest, DirectWriteFontSubstitution); ++ ~HFontRef(); ++ const HFONT hfont_; ++ const int font_size_; ++ const int height_; ++ const int baseline_; ++ const int cap_height_; ++ const int ave_char_width_; ++ const Font::Weight weight_; ++ const int style_; ++ // Average character width in dialog units. This is queried lazily from the ++ // system, with an initial value of -1 meaning it hasn't yet been queried. ++ int dlu_base_x_; ++ std::string font_name_; ++ // If the requested font size is not possible for the font, |font_size_| ++ // will be different than |requested_font_size_|. This is stored separately ++ // so that code that increases the font size in a loop will not cause the ++ // loop to get stuck on the same size. ++ int requested_font_size_; ++ DISALLOW_COPY_AND_ASSIGN(HFontRef); ++ }; ++ // Initializes this object with a copy of the specified HFONT. ++ void InitWithCopyOfHFONT(HFONT hfont); ++ // Initializes this object with the specified font name and size. ++ void InitWithFontNameAndSize(const std::string& font_name, ++ int font_size); ++ // Returns the GDI metrics for the font passed in. ++ static void GetTextMetricsForFont(HDC hdc, ++ HFONT font, ++ TEXTMETRIC* text_metrics); ++ // Returns the base font ref. This should ONLY be invoked on the ++ // UI thread. ++ static HFontRef* GetBaseFontRef(); ++ // Creates and returns a new HFontRef from the specified HFONT. ++ static HFontRef* CreateHFontRef(HFONT font); ++ // Creates and returns a new HFontRef from the specified HFONT. Uses provided ++ // |font_metrics| instead of calculating new one. ++ static HFontRef* CreateHFontRefFromGDI(HFONT font, ++ const TEXTMETRIC& font_metrics); ++ // Creates and returns a new HFontRef from the specified HFONT using metrics ++ // from skia. Currently this is only used if we use DirectWrite for font ++ // metrics. ++ // |gdi_font| : Handle to the GDI font created via CreateFontIndirect. ++ // |font_metrics| : The GDI font metrics retrieved via the GetTextMetrics ++ // API. This is currently used to calculate the correct height of the font ++ // in case we get a font created with a positive height. ++ // A positive height represents the cell height (ascent + descent). ++ // A negative height represents the character Em height which is cell ++ // height minus the internal leading value. ++ static PlatformFontWin::HFontRef* CreateHFontRefFromSkia( ++ HFONT gdi_font, ++ const TEXTMETRIC& font_metrics); ++ // Takes control of a native font (e.g. from CreateFontIndirect()) and wraps ++ // it in a Font object to manage its lifespan. Note that |hfont| may not be ++ // valid after the call; use the returned Font object instead. ++ static Font HFontToFont(HFONT hfont); ++ // Creates a new PlatformFontWin with the specified HFontRef. Used when ++ // constructing a Font from a HFONT we don't want to copy. ++ explicit PlatformFontWin(HFontRef* hfont_ref); ++ // Reference to the base font all fonts are derived from. ++ static HFontRef* base_font_ref_; ++ // Indirect reference to the HFontRef, which references the underlying HFONT. ++ scoped_refptr font_ref_; ++ // An optional typeface when the font is constructed from a typeface. ++ sk_sp typeface_; ++ DISALLOW_COPY_AND_ASSIGN(PlatformFontWin); ++}; ++// Returns the family name for the |IDWriteFont| interface passed in. ++// The family name is returned in the |family_name| parameter. ++// Returns S_OK on success. ++// HRESULT GetFamilyNameFromDirectWriteFont(IDWriteFont* dwrite_font, ++// base::string16* family_name); ++} // namespace gfx ++#endif // UI_GFX_PLATFORM_FONT_WIN_H_ +\ No newline at end of file +diff --git a/sandbox/policy/win/sandbox_win.cc b/sandbox/policy/win/sandbox_win.cc +index f4f23deab53f0..2c049fdfd0418 100644 +--- a/sandbox/policy/win/sandbox_win.cc ++++ b/sandbox/policy/win/sandbox_win.cc +@@ -1017,13 +1017,13 @@ ResultCode SandboxWin::GeneratePolicyForSandboxedProcess( + + // Pre-startup mitigations. + MitigationFlags mitigations = +- MITIGATION_HEAP_TERMINATE | ++ // MITIGATION_HEAP_TERMINATE | + MITIGATION_BOTTOM_UP_ASLR | + MITIGATION_DEP | + MITIGATION_DEP_NO_ATL_THUNK | + MITIGATION_EXTENSION_POINT_DISABLE | + MITIGATION_SEHOP | +- MITIGATION_NONSYSTEM_FONT_DISABLE | ++ // MITIGATION_NONSYSTEM_FONT_DISABLE | + MITIGATION_IMAGE_LOAD_NO_REMOTE | + MITIGATION_IMAGE_LOAD_NO_LOW_LABEL | + MITIGATION_RESTRICT_INDIRECT_BRANCH_PREDICTION; +@@ -1040,11 +1040,11 @@ ResultCode SandboxWin::GeneratePolicyForSandboxedProcess( + if (result != SBOX_ALL_OK) + return result; + +- if (process_type == switches::kRendererProcess) { +- result = SandboxWin::AddWin32kLockdownPolicy(policy.get()); +- if (result != SBOX_ALL_OK) +- return result; +- } ++ // if (process_type == switches::kRendererProcess) { ++ // result = SandboxWin::AddWin32kLockdownPolicy(policy.get()); ++ // if (result != SBOX_ALL_OK) ++ // return result; ++ // } + + // Post-startup mitigations. + mitigations = MITIGATION_DLL_SEARCH_ORDER; +diff --git a/third_party/blink/renderer/platform/fonts/font_cache.cc b/third_party/blink/renderer/platform/fonts/font_cache.cc +index e625b635ce733..0682ce6c9847a 100644 +--- a/third_party/blink/renderer/platform/fonts/font_cache.cc ++++ b/third_party/blink/renderer/platform/fonts/font_cache.cc +@@ -111,7 +111,8 @@ FontCache::FontCache() + // This code path is only for unit tests. This SkFontMgr does not work in + // sandboxed environments, but injecting this initialization code to all + // unit tests isn't easy. +- font_manager_ = SkFontMgr_New_DirectWrite(); ++ // font_manager_ = SkFontMgr_New_DirectWrite(); ++ font_manager_ = SkFontMgr_New_GDI(); + // Set |is_test_font_mgr_| to capture if this is not happening in the + // production code. crbug.com/561873 + is_test_font_mgr_ = true; +diff --git a/third_party/blink/renderer/platform/fonts/font_custom_platform_data.cc b/third_party/blink/renderer/platform/fonts/font_custom_platform_data.cc +index c00c904754a4a..7f7c12e999f6a 100644 +--- a/third_party/blink/renderer/platform/fonts/font_custom_platform_data.cc ++++ b/third_party/blink/renderer/platform/fonts/font_custom_platform_data.cc +@@ -92,6 +92,22 @@ FontPlatformData FontCustomPlatformData::GetFontPlatformData( + + sk_sp return_typeface = base_typeface_; + ++ bool syntheticBold = bold && !base_typeface_->isBold(); ++ bool syntheticItalic = italic && !base_typeface_->isItalic(); ++ if (syntheticBold || syntheticItalic) { ++ SkString name; ++ base_typeface_->getFamilyName(&name); ++ SkFontStyle realStyle = base_typeface_->fontStyle(); ++ SkFontStyle syntheticStyle = SkFontStyle( ++ realStyle.weight() + (syntheticBold ? 200 : 0), realStyle.width(), ++ syntheticItalic ? SkFontStyle::kItalic_Slant : realStyle.slant()); ++ sk_sp typeface; ++ typeface = (FontCache::GetFontCache()->FontManager()->legacyMakeTypeface(name.c_str(), syntheticStyle)); ++ syntheticBold = false; ++ syntheticItalic = false; ++ return FontPlatformData((const sk_sp) typeface.release(), "", size, syntheticBold, syntheticItalic, orientation); ++ } ++ + // Maximum axis count is maximum value for the OpenType USHORT, + // which is a 16bit unsigned. + // https://www.microsoft.com/typography/otspec/fvar.htm Variation +diff --git a/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc b/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc +index 958d18378b486..e2384d6a740f2 100644 +--- a/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc ++++ b/third_party/blink/renderer/platform/fonts/skia/font_cache_skia.cc +@@ -248,7 +248,7 @@ sk_sp FontCache::CreateTypeface( + // SkTypeface::CreateFromName which may redirect the call to the default font + // Manager. On Windows the font manager is always present. + if (font_manager_) { +- auto tf = sk_sp(font_manager_->matchFamilyStyle( ++ auto tf = sk_sp(font_manager_->legacyMakeTypeface( + name.c_str(), font_description.SkiaFontStyle())); + return tf; + } +diff --git a/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc b/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc +index 432c044bd3503..794094ca510ec 100644 +--- a/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc ++++ b/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc +@@ -56,7 +56,7 @@ static inline bool IsFontPresent(const UChar* font_name, + SkFontMgr* font_manager) { + String family = font_name; + sk_sp tf( +- font_manager->matchFamilyStyle(family.Utf8().c_str(), SkFontStyle())); ++ font_manager->legacyMakeTypeface(family.Utf8().c_str(), SkFontStyle())); + if (!tf) + return false; + +diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn +index 39b9d0763d9ec..4d495b14358aa 100644 +--- a/ui/gfx/BUILD.gn ++++ b/ui/gfx/BUILD.gn +@@ -195,6 +195,8 @@ component("gfx") { + "font_render_params_win.cc", + "path_win.cc", + "path_win.h", ++ "//mod/ui/gfx/platform_font_win.cc", ++ "//mod/ui/gfx/platform_font_win.h", + "system_fonts_win.cc", + "system_fonts_win.h", + "win/crash_id_helper.cc", +diff --git a/ui/gfx/font_render_params_win.cc b/ui/gfx/font_render_params_win.cc +index 1369f8a4fdff6..23458998fc626 100644 +--- a/ui/gfx/font_render_params_win.cc ++++ b/ui/gfx/font_render_params_win.cc +@@ -64,13 +64,13 @@ class CachedFontRenderParams { + params_->subpixel_positioning = false; + params_->autohinter = false; + params_->use_bitmaps = false; +- params_->hinting = FontRenderParams::HINTING_MEDIUM; ++ params_->hinting = FontRenderParams::HINTING_FULL; + params_->subpixel_rendering = FontRenderParams::SUBPIXEL_RENDERING_NONE; + + BOOL enabled = false; + if (SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &enabled, 0) && enabled) { + params_->antialiasing = true; +- params_->subpixel_positioning = true; ++ params_->subpixel_positioning = false; + + UINT type = 0; + if (SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &type, 0) && +diff --git a/ui/gfx/render_text_harfbuzz.cc b/ui/gfx/render_text_harfbuzz.cc +index e378c6c655d56..529ed40269e39 100644 +--- a/ui/gfx/render_text_harfbuzz.cc ++++ b/ui/gfx/render_text_harfbuzz.cc +@@ -2076,7 +2076,9 @@ void RenderTextHarfBuzz::ShapeRuns( + // could be a raster font like System, which would not give us a reasonable + // fallback font list. + Font segoe("Segoe UI", 13); +- if (!FontWasAlreadyTried(segoe.platform_font()->GetNativeSkTypeface(), ++ if (//fallback_fonts_already_tried.size() > 0 && ++ segoe.platform_font()->GetNativeSkTypeface() != NULL && ++ !FontWasAlreadyTried(segoe.platform_font()->GetNativeSkTypeface(), + &fallback_fonts_already_tried)) { + std::vector default_fallback_families = GetFallbackFonts(segoe); + fallback_font_list.insert(fallback_font_list.end(), +diff --git a/ui/gfx/win/direct_write.cc b/ui/gfx/win/direct_write.cc +index fc7356b2f2443..acbce8861b3b1 100644 +--- a/ui/gfx/win/direct_write.cc ++++ b/ui/gfx/win/direct_write.cc +@@ -21,92 +21,16 @@ + namespace gfx { + namespace win { + +-namespace { +- +-// Pointer to the global IDWriteFactory interface. +-IDWriteFactory* g_direct_write_factory = nullptr; +- +-void SetDirectWriteFactory(IDWriteFactory* factory) { +- DCHECK(!g_direct_write_factory); +- // We grab a reference on the DirectWrite factory. This reference is +- // leaked, which is ok because skia leaks it as well. +- factory->AddRef(); +- g_direct_write_factory = factory; +-} +- +-} // anonymous namespace +- + void CreateDWriteFactory(IDWriteFactory** factory) { +- Microsoft::WRL::ComPtr factory_unknown; +- HRESULT hr = +- DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), +- &factory_unknown); +- if (FAILED(hr)) { +- base::debug::Alias(&hr); +- CHECK(false); +- return; +- } +- factory_unknown.CopyTo(factory); + } + + void InitializeDirectWrite() { +- static bool tried_dwrite_initialize = false; +- DCHECK(!tried_dwrite_initialize); +- tried_dwrite_initialize = true; +- +- TRACE_EVENT0("fonts", "gfx::InitializeDirectWrite"); +- SCOPED_UMA_HISTOGRAM_LONG_TIMER("DirectWrite.Fonts.Gfx.InitializeTime"); +- +- Microsoft::WRL::ComPtr factory; +- CreateDWriteFactory(&factory); +- CHECK(!!factory); +- SetDirectWriteFactory(factory.Get()); +- +- // The skia call to create a new DirectWrite font manager instance can fail +- // if we are unable to get the system font collection from the DirectWrite +- // factory. The GetSystemFontCollection method in the IDWriteFactory +- // interface fails with E_INVALIDARG on certain Windows 7 gold versions +- // (6.1.7600.*). +- sk_sp direct_write_font_mgr = +- SkFontMgr_New_DirectWrite(factory.Get()); +- int iteration = 0; +- if (!direct_write_font_mgr && +- base::win::GetVersion() == base::win::Version::WIN7) { +- // Windows (win7_rtm) may fail to map the service sections +- // (crbug.com/956064). +- constexpr int kMaxRetries = 5; +- constexpr base::TimeDelta kRetrySleepTime = base::Microseconds(500); +- while (iteration < kMaxRetries) { +- base::PlatformThread::Sleep(kRetrySleepTime); +- direct_write_font_mgr = SkFontMgr_New_DirectWrite(factory.Get()); +- if (direct_write_font_mgr) +- break; +- ++iteration; +- } +- } +- if (!direct_write_font_mgr) +- iteration = -1; +- base::UmaHistogramSparse("DirectWrite.Fonts.Gfx.InitializeLoopCount", +- iteration); +- // TODO(crbug.com/956064): Move to a CHECK when the cause of the crash is +- // fixed and remove the if statement that fallback to GDI font manager. +- DCHECK(!!direct_write_font_mgr); +- if (!direct_write_font_mgr) +- direct_write_font_mgr = SkFontMgr_New_GDI(); +- +- // Override the default skia font manager. This must be called before any +- // use of the skia font manager is done (e.g. before any call to +- // SkFontMgr::RefDefault()). ++ sk_sp direct_write_font_mgr = SkFontMgr_New_GDI(); + skia::OverrideDefaultSkFontMgr(std::move(direct_write_font_mgr)); + } + + IDWriteFactory* GetDirectWriteFactory() { +- // Some unittests may access this accessor without any previous call to +- // |InitializeDirectWrite|. A call to |InitializeDirectWrite| after this +- // function being called is still invalid. +- if (!g_direct_write_factory) +- InitializeDirectWrite(); +- return g_direct_write_factory; ++ return 0; + } + + absl::optional RetrieveLocalizedString(