// Copyright 2014 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 "ui/gfx/win/direct_write.h" #include #include "base/basictypes.h" #include "base/command_line.h" #include "base/metrics/field_trial.h" #include "base/win/registry.h" #include "base/win/scoped_comptr.h" #include "base/win/windows_version.h" #include "skia/ext/fontmgr_default_win.h" #include "third_party/skia/include/ports/SkTypeface_win.h" #include "ui/gfx/platform_font_win.h" #include "ui/gfx/switches.h" #include "ui/gfx/win/dpi.h" namespace gfx { namespace win { namespace { static bool dwrite_enabled = false; } bool ShouldUseDirectWrite() { // If the flag is currently on, and we're on Win7 or above, we enable // DirectWrite. Skia does not require the additions to DirectWrite in QFE // 2670838, but a simple 'better than XP' check is not enough. if (base::win::GetVersion() < base::win::VERSION_WIN7) return false; base::win::OSInfo::VersionNumber os_version = base::win::OSInfo::GetInstance()->version_number(); if ((os_version.major == 6) && (os_version.minor == 1)) { // We can't use DirectWrite for pre-release versions of Windows 7. if (os_version.build < 7600) return false; } // If forced off, don't use it. const base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess(); if (command_line.HasSwitch(switches::kDisableDirectWrite)) return false; // Can't use GDI on HiDPI. if (gfx::GetDPIScale() > 1.0f) return true; // Otherwise, check the field trial. const std::string group_name = base::FieldTrialList::FindFullName("DirectWrite"); return group_name != "Disabled"; } void MaybeInitializeDirectWrite() { static bool tried_dwrite_initialize = false; if (tried_dwrite_initialize) return; tried_dwrite_initialize = true; if (!ShouldUseDirectWrite() || base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableDirectWriteForUI)) { return; } using DWriteCreateFactoryProc = decltype(DWriteCreateFactory)*; HMODULE dwrite_dll = LoadLibraryW(L"dwrite.dll"); if (!dwrite_dll) return; DWriteCreateFactoryProc dwrite_create_factory_proc = reinterpret_cast( GetProcAddress(dwrite_dll, "DWriteCreateFactory")); // Not finding the DWriteCreateFactory function indicates a corrupt dll. if (!dwrite_create_factory_proc) return; base::win::ScopedComPtr factory; // Failure to create the DirectWrite factory indicates a corrupt dll. if (FAILED(dwrite_create_factory_proc( DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast(factory.Receive())))) return; // 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.*). We should just use GDI in these cases. SkFontMgr* direct_write_font_mgr = SkFontMgr_New_DirectWrite(factory.get()); if (!direct_write_font_mgr) return; dwrite_enabled = true; SetDefaultSkiaFactory(direct_write_font_mgr); gfx::PlatformFontWin::SetDirectWriteFactory(factory.get()); } bool IsDirectWriteEnabled() { return dwrite_enabled; } } // namespace win } // namespace gfx