15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// found in the LICENSE file.
45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/renderer/renderer_font_platform_win.h"
65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <dwrite.h>
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <string>
95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <vector>
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <wrl/implements.h>
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <wrl/wrappers/corewrappers.h>
125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/debug/alias.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/debug/crash_logging.h"
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/files/file_enumerator.h"
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/files/file_path.h"
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/files/memory_mapped_file.h"
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/memory/scoped_vector.h"
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/metrics/histogram.h"
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/path_service.h"
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/strings/utf_string_conversions.h"
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/time/time.h"
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/win/iat_patch_function.h"
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/win/registry.h"
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/win/scoped_comptr.h"
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace {
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace mswr = Microsoft::WRL;
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace mswrw = Microsoft::WRL::Wrappers;
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistatic const char kFontKeyName[] = "font_key_name";
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class FontCollectionLoader
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : public mswr::RuntimeClass<mswr::RuntimeClassFlags<mswr::ClassicCom>,
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                IDWriteFontCollectionLoader> {
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public:
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // IDWriteFontCollectionLoader methods.
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual HRESULT STDMETHODCALLTYPE
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      CreateEnumeratorFromKey(IDWriteFactory* factory,
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              void const* key,
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              UINT32 key_size,
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              IDWriteFontFileEnumerator** file_enumerator);
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static HRESULT Initialize(IDWriteFactory* factory);
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  UINT32 GetFontMapSize();
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::wstring GetFontNameFromKey(UINT32 idx);
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool LoadFontListFromRegistry();
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool LoadRestrictedFontList();
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FontCollectionLoader() {};
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual ~FontCollectionLoader() {};
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private:
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  mswr::ComPtr<IDWriteFontFileLoader> file_loader_;
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::vector<std::wstring> reg_fonts_;
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)mswr::ComPtr<FontCollectionLoader> g_font_loader;
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class FontFileStream
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : public mswr::RuntimeClass<mswr::RuntimeClassFlags<mswr::ClassicCom>,
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                IDWriteFontFileStream> {
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public:
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // IDWriteFontFileStream methods.
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual HRESULT STDMETHODCALLTYPE
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ReadFileFragment(void const** fragment_start,
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   UINT64 file_offset,
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   UINT64 fragment_size,
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   void** context) {
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!memory_.get() || !memory_->IsValid() ||
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        file_offset >= memory_->length() ||
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        (file_offset + fragment_size) > memory_->length())
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return E_FAIL;
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    *fragment_start = static_cast<BYTE const*>(memory_->data()) +
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      static_cast<size_t>(file_offset);
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    *context = NULL;
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return S_OK;
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void STDMETHODCALLTYPE ReleaseFileFragment(void* context) {}
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual HRESULT STDMETHODCALLTYPE GetFileSize(UINT64* file_size) {
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!memory_.get() || !memory_->IsValid())
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return E_FAIL;
925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    *file_size = memory_->length();
945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return S_OK;
955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime(UINT64* last_write_time) {
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!memory_.get() || !memory_->IsValid())
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return E_FAIL;
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // According to MSDN article http://goo.gl/rrSYzi the "last modified time"
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // is used by DirectWrite font selection algorithms to determine whether
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // one font resource is more up to date than another one.
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // So by returning 0 we are assuming that it will treat all fonts to be
1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // equally up to date.
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // TODO(shrikant): We should further investigate this.
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    *last_write_time = 0;
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return S_OK;
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FontFileStream::FontFileStream() : font_key_(0) {
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  };
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  HRESULT RuntimeClassInitialize(UINT32 font_key) {
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::FilePath path;
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    PathService::Get(base::DIR_WINDOWS_FONTS, &path);
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::wstring font_key_name(g_font_loader->GetFontNameFromKey(font_key));
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    path = path.Append(font_key_name.c_str());
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    memory_.reset(new base::MemoryMappedFile());
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Put some debug information on stack.
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    WCHAR font_name[256];
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    path.value().copy(font_name, arraysize(font_name));
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::debug::Alias(font_name);
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!memory_->Initialize(path)) {
1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      memory_.reset();
1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return E_FAIL;
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    font_key_ = font_key;
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::debug::SetCrashKeyValue(kFontKeyName,
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  base::WideToUTF8(font_key_name));
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return S_OK;
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual ~FontFileStream() {}
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  UINT32 font_key_;
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<base::MemoryMappedFile> memory_;
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class FontFileLoader
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : public mswr::RuntimeClass<mswr::RuntimeClassFlags<mswr::ClassicCom>,
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                IDWriteFontFileLoader> {
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public:
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // IDWriteFontFileLoader methods.
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual HRESULT STDMETHODCALLTYPE
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  CreateStreamFromKey(void const* ref_key,
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      UINT32 ref_key_size,
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                      IDWriteFontFileStream** stream) {
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (ref_key_size != sizeof(UINT32))
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return E_FAIL;
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    UINT32 font_key = *static_cast<const UINT32*>(ref_key);
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    mswr::ComPtr<FontFileStream> font_stream;
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    HRESULT hr = mswr::MakeAndInitialize<FontFileStream>(&font_stream,
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                         font_key);
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (SUCCEEDED(hr)) {
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      *stream = font_stream.Detach();
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return S_OK;
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return E_FAIL;
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FontFileLoader() {}
1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual ~FontFileLoader() {}
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class FontFileEnumerator
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : public mswr::RuntimeClass<mswr::RuntimeClassFlags<mswr::ClassicCom>,
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                IDWriteFontFileEnumerator> {
1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public:
1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // IDWriteFontFileEnumerator methods.
1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual HRESULT STDMETHODCALLTYPE MoveNext(BOOL* has_current_file) {
1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    *has_current_file = FALSE;
1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (current_file_)
1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      current_file_.ReleaseAndGetAddressOf();
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (font_idx_ < g_font_loader->GetFontMapSize()) {
1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      HRESULT hr =
1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          factory_->CreateCustomFontFileReference(&font_idx_,
1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                  sizeof(UINT32),
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                  file_loader_.Get(),
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                  current_file_.GetAddressOf());
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      DCHECK(SUCCEEDED(hr));
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      *has_current_file = TRUE;
1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      font_idx_++;
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return S_OK;
1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual HRESULT STDMETHODCALLTYPE
1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  GetCurrentFontFile(IDWriteFontFile** font_file) {
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!current_file_) {
1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      *font_file = NULL;
1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return E_FAIL;
2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    *font_file = current_file_.Detach();
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return S_OK;
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FontFileEnumerator(const void* keys,
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                     UINT32 buffer_size,
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                     IDWriteFactory* factory,
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                     IDWriteFontFileLoader* file_loader)
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : factory_(factory), file_loader_(file_loader), font_idx_(0) {}
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual ~FontFileEnumerator() {}
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  mswr::ComPtr<IDWriteFactory> factory_;
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  mswr::ComPtr<IDWriteFontFile> current_file_;
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  mswr::ComPtr<IDWriteFontFileLoader> file_loader_;
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  UINT32 font_idx_;
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// IDWriteFontCollectionLoader methods.
2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)HRESULT STDMETHODCALLTYPE FontCollectionLoader::CreateEnumeratorFromKey(
2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IDWriteFactory* factory,
2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    void const* key,
2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    UINT32 key_size,
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    IDWriteFontFileEnumerator** file_enumerator) {
2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  *file_enumerator = mswr::Make<FontFileEnumerator>(
2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         key, key_size, factory, file_loader_.Get()).Detach();
2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return S_OK;
2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static
2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)HRESULT FontCollectionLoader::Initialize(IDWriteFactory* factory) {
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(g_font_loader == NULL);
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  g_font_loader = mswr::Make<FontCollectionLoader>();
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!g_font_loader) {
2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    DCHECK(FALSE);
2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return E_FAIL;
2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  CHECK(g_font_loader->LoadFontListFromRegistry());
2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  g_font_loader->file_loader_ = mswr::Make<FontFileLoader>().Detach();
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  factory->RegisterFontFileLoader(g_font_loader->file_loader_.Get());
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  factory->RegisterFontCollectionLoader(g_font_loader.Get());
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return S_OK;
2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)UINT32 FontCollectionLoader::GetFontMapSize() {
2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return reg_fonts_.size();
2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)std::wstring FontCollectionLoader::GetFontNameFromKey(UINT32 idx) {
2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(idx < reg_fonts_.size());
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return reg_fonts_[idx];
2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool FontCollectionLoader::LoadFontListFromRegistry() {
2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const wchar_t kFontsRegistry[] =
2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts";
2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  CHECK(reg_fonts_.empty());
2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::win::RegKey regkey;
2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (regkey.Open(HKEY_LOCAL_MACHINE, kFontsRegistry, KEY_READ) !=
2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ERROR_SUCCESS) {
2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::FilePath system_font_path;
2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  PathService::Get(base::DIR_WINDOWS_FONTS, &system_font_path);
2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::wstring name;
2745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::wstring value;
2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (DWORD idx = 0; idx < regkey.GetValueCount(); idx++) {
2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (regkey.GetValueNameAt(idx, &name) == ERROR_SUCCESS &&
2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        regkey.ReadValue(name.c_str(), &value) == ERROR_SUCCESS) {
2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::FilePath path(value.c_str());
2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // We need to check if file name is the only component that exists,
2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // we will ignore all other registry entries.
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      std::vector<base::FilePath::StringType> components;
2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      path.GetComponents(&components);
2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (components.size() == 1 ||
2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          base::FilePath::CompareEqualIgnoreCase(system_font_path.value(),
2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                 path.DirName().value())) {
2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        reg_fonts_.push_back(path.BaseName().value());
2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      }
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  UMA_HISTOGRAM_COUNTS("DirectWrite.Fonts.Loaded", reg_fonts_.size());
2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  UMA_HISTOGRAM_COUNTS("DirectWrite.Fonts.Ignored",
2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                       regkey.GetValueCount() - reg_fonts_.size());
2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return true;
2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// This list is mainly based on prefs/prefs_tab_helper.cc kFontDefaults.
2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst wchar_t* kRestrictedFontSet[] = {
2981675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  // These are the "Web Safe" fonts.
2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"times.ttf",     // IDS_STANDARD_FONT_FAMILY
3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"timesbd.ttf",   // IDS_STANDARD_FONT_FAMILY
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"timesbi.ttf",   // IDS_STANDARD_FONT_FAMILY
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"timesi.ttf",    // IDS_STANDARD_FONT_FAMILY
3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"cour.ttf",      // IDS_FIXED_FONT_FAMILY
3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"courbd.ttf",    // IDS_FIXED_FONT_FAMILY
3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"courbi.ttf",    // IDS_FIXED_FONT_FAMILY
3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"couri.ttf",     // IDS_FIXED_FONT_FAMILY
3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"consola.ttf",   // IDS_FIXED_FONT_FAMILY_ALT_WIN
3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"consolab.ttf",  // IDS_FIXED_FONT_FAMILY_ALT_WIN
3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"consolai.ttf",  // IDS_FIXED_FONT_FAMILY_ALT_WIN
3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"consolaz.ttf",  // IDS_FIXED_FONT_FAMILY_ALT_WIN
3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"arial.ttf",     // IDS_SANS_SERIF_FONT_FAMILY
3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"arialbd.ttf",   // IDS_SANS_SERIF_FONT_FAMILY
3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"arialbi.ttf",   // IDS_SANS_SERIF_FONT_FAMILY
3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"ariali.ttf",    // IDS_SANS_SERIF_FONT_FAMILY
3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"comic.ttf",     // IDS_CURSIVE_FONT_FAMILY
3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"comicbd.ttf",   // IDS_CURSIVE_FONT_FAMILY
3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"comici.ttf",    // IDS_CURSIVE_FONT_FAMILY
3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"comicz.ttf",    // IDS_CURSIVE_FONT_FAMILY
3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"impact.ttf",    // IDS_FANTASY_FONT_FAMILY
3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"segoeui.ttf",   // IDS_PICTOGRAPH_FONT_FAMILY
3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"segoeuib.ttf",  // IDS_PICTOGRAPH_FONT_FAMILY
3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"segoeuii.ttf",  // IDS_PICTOGRAPH_FONT_FAMILY
3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"msgothic.ttc",  // IDS_STANDARD_FONT_FAMILY_JAPANESE
3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"msmincho.ttc",  // IDS_SERIF_FONT_FAMILY_JAPANESE
3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"gulim.ttc",     // IDS_FIXED_FONT_FAMILY_KOREAN
3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"batang.ttc",    // IDS_SERIF_FONT_FAMILY_KOREAN
3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"simsun.ttc",    // IDS_STANDARD_FONT_FAMILY_SIMPLIFIED_HAN
3281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  L"mingliu.ttc",   // IDS_SERIF_FONT_FAMILY_TRADITIONAL_HAN
3291675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
3301675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  // These are from the Blink fallback list.
3311675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  L"david.ttf",     // USCRIPT_HEBREW
3321675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  L"davidbd.ttf",   // USCRIPT_HEBREW
3331675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  L"euphemia.ttf",  // USCRIPT_CANADIAN_ABORIGINAL
3341675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  L"gautami.ttf",   // USCRIPT_TELUGU
3351675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  L"gautamib.ttf",  // USCRIPT_TELUGU
3361675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  L"latha.ttf",     // USCRIPT_TAMIL
3371675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  L"lathab.ttf",    // USCRIPT_TAMIL
3381675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  L"mangal.ttf",    // USCRIPT_DEVANAGARI
3391675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  L"mangalb.ttf",   // USCRIPT_DEVANAGARI
3401675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  L"monbaiti.ttf",  // USCRIPT_MONGOLIAN
3411675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  L"mvboli.ttf",    // USCRIPT_THAANA
3421675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  L"plantc.ttf",    // USCRIPT_CHEROKEE
3431675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  L"raavi.ttf",     // USCRIPT_GURMUKHI
3441675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  L"raavib.ttf",    // USCRIPT_GURMUKHI
3451675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  L"shruti.ttf",    // USCRIPT_GUJARATI
3461675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  L"shrutib.ttf",   // USCRIPT_GUJARATI
3471675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  L"sylfaen.ttf",   // USCRIPT_GEORGIAN and USCRIPT_ARMENIAN
3481675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  L"tahoma.ttf",    // USCRIPT_ARABIC,
3491675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  L"tahomabd.ttf",  // USCRIPT_ARABIC,
3501675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  L"tunga.ttf",     // USCRIPT_KANNADA
3511675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  L"tungab.ttf",    // USCRIPT_KANNADA
3521675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  L"vrinda.ttf",    // USCRIPT_BENGALI
3531675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  L"vrindab.ttf",   // USCRIPT_BENGALI
3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool FontCollectionLoader::LoadRestrictedFontList() {
3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  reg_fonts_.clear();
3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  reg_fonts_.assign(kRestrictedFontSet,
3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    kRestrictedFontSet + _countof(kRestrictedFontSet));
3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return true;
3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace
3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace content {
3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)mswr::ComPtr<IDWriteFontCollection> g_font_collection;
3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)IDWriteFontCollection* GetCustomFontCollection(IDWriteFactory* factory) {
3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (g_font_collection.Get() != NULL)
3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return g_font_collection.Get();
3725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::TimeTicks start_tick = base::TimeTicks::Now();
3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FontCollectionLoader::Initialize(factory);
3765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // We try here to put arbitrary limit on max number of fonts that could
3781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // be loaded, otherwise we fallback to restricted set of fonts.
3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const UINT32 kMaxFontThreshold = 1750;
3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  HRESULT hr = E_FAIL;
3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (g_font_loader->GetFontMapSize() < kMaxFontThreshold) {
3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    hr = factory->CreateCustomFontCollection(
3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        g_font_loader.Get(), NULL, 0, g_font_collection.GetAddressOf());
3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool loadingRestricted = false;
3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (FAILED(hr) || !g_font_collection.Get()) {
3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // We will try here just one more time with restricted font set.
3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    g_font_loader->LoadRestrictedFontList();
3901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    hr = factory->CreateCustomFontCollection(
3911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        g_font_loader.Get(), NULL, 0, g_font_collection.GetAddressOf());
3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::TimeDelta time_delta = base::TimeTicks::Now() - start_tick;
3955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int64 delta = time_delta.ToInternalValue();
3965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::debug::Alias(&delta);
3975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  UINT32 size = g_font_loader->GetFontMapSize();
3985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::debug::Alias(&size);
3991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::debug::Alias(&loadingRestricted);
4005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  CHECK(SUCCEEDED(hr));
4025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  CHECK(g_font_collection.Get() != NULL);
4035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  UMA_HISTOGRAM_TIMES("DirectWrite.Fonts.LoadTime", time_delta);
4051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::debug::ClearCrashKey(kFontKeyName);
4071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return g_font_collection.Get();
4095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace content
412