// Copyright 2015 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 "content/browser/renderer_host/dwrite_font_proxy_message_filter_win.h"

#include <dwrite.h>
#include <shlobj.h>
#include <stddef.h>
#include <stdint.h>

#include <set>
#include <utility>

#include "base/callback_helpers.h"
#include "base/i18n/case_conversion.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "content/common/dwrite_font_proxy_messages.h"
#include "content/common/dwrite_text_analysis_source_win.h"
#include "ipc/ipc_message_macros.h"
#include "ui/gfx/win/direct_write.h"

namespace mswr = Microsoft::WRL;

namespace content {

namespace {

// This enum is used to define the buckets for an enumerated UMA histogram.
// Hence,
//   (a) existing enumerated constants should never be deleted or reordered, and
//   (b) new constants should only be appended at the end of the enumeration.
enum DirectWriteFontLoaderType {
  FILE_SYSTEM_FONT_DIR = 0,
  FILE_OUTSIDE_SANDBOX = 1,
  OTHER_LOADER = 2,

  FONT_LOADER_TYPE_MAX_VALUE
};

void LogLoaderType(DirectWriteFontLoaderType loader_type) {
  UMA_HISTOGRAM_ENUMERATION("DirectWrite.Fonts.Proxy.LoaderType", loader_type,
                            FONT_LOADER_TYPE_MAX_VALUE);
}

const wchar_t* kFontsToIgnore[] = {
    // "Gill Sans Ultra Bold" turns into an Ultra Bold weight "Gill Sans" in
    // DirectWrite, but most users don't have any other weights. The regular
    // weight font is named "Gill Sans MT", but that ends up in a different
    // family with that name. On Mac, there's a "Gill Sans" with various
    // weights, so CSS authors use { 'font-family': 'Gill Sans',
    // 'Gill Sans MT', ... } and because of the DirectWrite family futzing,
    // they end up with an Ultra Bold font, when they just wanted "Gill Sans".
    // Mozilla implemented a more complicated hack where they effectively
    // rename the Ultra Bold font to "Gill Sans MT Ultra Bold", but because the
    // Ultra Bold font is so ugly anyway, we simply ignore it. See
    // http://www.microsoft.com/typography/fonts/font.aspx?FMID=978 for a
    // picture of the font, and the file name. We also ignore "Gill Sans Ultra
    // Bold Condensed".
    L"gilsanub.ttf", L"gillubcd.ttf",
};

base::string16 GetWindowsFontsPath() {
  std::vector<base::char16> font_path_chars;
  // SHGetSpecialFolderPath requires at least MAX_PATH characters.
  font_path_chars.resize(MAX_PATH);
  BOOL result = SHGetSpecialFolderPath(nullptr /* hwndOwner - reserved */,
                                       font_path_chars.data(), CSIDL_FONTS,
                                       FALSE /* fCreate */);
  DCHECK(result);
  return base::i18n::FoldCase(font_path_chars.data());
}

}  // namespace

DWriteFontProxyMessageFilter::DWriteFontProxyMessageFilter()
    : BrowserMessageFilter(DWriteFontProxyMsgStart),
      windows_fonts_path_(GetWindowsFontsPath()) {}

DWriteFontProxyMessageFilter::~DWriteFontProxyMessageFilter() = default;

bool DWriteFontProxyMessageFilter::OnMessageReceived(
    const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(DWriteFontProxyMessageFilter, message)
    IPC_MESSAGE_HANDLER(DWriteFontProxyMsg_FindFamily, OnFindFamily)
    IPC_MESSAGE_HANDLER(DWriteFontProxyMsg_GetFamilyCount, OnGetFamilyCount)
    IPC_MESSAGE_HANDLER(DWriteFontProxyMsg_GetFamilyNames, OnGetFamilyNames)
    IPC_MESSAGE_HANDLER(DWriteFontProxyMsg_GetFontFiles, OnGetFontFiles)
    IPC_MESSAGE_HANDLER(DWriteFontProxyMsg_MapCharacters, OnMapCharacters)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void DWriteFontProxyMessageFilter::OverrideThreadForMessage(
    const IPC::Message& message,
    content::BrowserThread::ID* thread) {
  if (IPC_MESSAGE_CLASS(message) == DWriteFontProxyMsgStart)
    *thread = BrowserThread::FILE;
}

void DWriteFontProxyMessageFilter::OnFindFamily(
    const base::string16& family_name,
    UINT32* family_index) {
  InitializeDirectWrite();
  TRACE_EVENT0("dwrite", "FontProxyHost::OnFindFamily");
  DCHECK(collection_);
  *family_index = UINT32_MAX;
  if (collection_) {
    BOOL exists = FALSE;
    UINT32 index = UINT32_MAX;
    HRESULT hr =
        collection_->FindFamilyName(family_name.data(), &index, &exists);
    if (SUCCEEDED(hr) && exists)
      *family_index = index;
  }
}

void DWriteFontProxyMessageFilter::OnGetFamilyCount(UINT32* count) {
  InitializeDirectWrite();
  TRACE_EVENT0("dwrite", "FontProxyHost::OnGetFamilyCount");
  DCHECK(collection_);
  if (!collection_)
    *count = 0;
  else
    *count = collection_->GetFontFamilyCount();
}

void DWriteFontProxyMessageFilter::OnGetFamilyNames(
    UINT32 family_index,
    std::vector<DWriteStringPair>* family_names) {
  InitializeDirectWrite();
  TRACE_EVENT0("dwrite", "FontProxyHost::OnGetFamilyNames");
  DCHECK(collection_);
  if (!collection_)
    return;

  TRACE_EVENT0("dwrite", "FontProxyHost::DoGetFamilyNames");

  mswr::ComPtr<IDWriteFontFamily> family;
  HRESULT hr = collection_->GetFontFamily(family_index, &family);
  if (FAILED(hr)) {
    return;
  }

  mswr::ComPtr<IDWriteLocalizedStrings> localized_names;
  hr = family->GetFamilyNames(&localized_names);
  if (FAILED(hr)) {
    return;
  }

  size_t string_count = localized_names->GetCount();

  std::vector<base::char16> locale;
  std::vector<base::char16> name;
  for (size_t index = 0; index < string_count; ++index) {
    UINT32 length = 0;
    hr = localized_names->GetLocaleNameLength(index, &length);
    if (FAILED(hr)) {
      return;
    }
    ++length;  // Reserve space for the null terminator.
    locale.resize(length);
    hr = localized_names->GetLocaleName(index, locale.data(), length);
    if (FAILED(hr)) {
      return;
    }
    CHECK_EQ(L'\0', locale[length - 1]);

    length = 0;
    hr = localized_names->GetStringLength(index, &length);
    if (FAILED(hr)) {
      return;
    }
    ++length;  // Reserve space for the null terminator.
    name.resize(length);
    hr = localized_names->GetString(index, name.data(), length);
    if (FAILED(hr)) {
      return;
    }
    CHECK_EQ(L'\0', name[length - 1]);

    // Would be great to use emplace_back instead.
    family_names->push_back(std::pair<base::string16, base::string16>(
        base::string16(locale.data()), base::string16(name.data())));
  }
}

void DWriteFontProxyMessageFilter::OnGetFontFiles(
    uint32_t family_index,
    std::vector<base::string16>* file_paths) {
  InitializeDirectWrite();
  TRACE_EVENT0("dwrite", "FontProxyHost::OnGetFontFiles");
  DCHECK(collection_);
  if (!collection_)
    return;

  mswr::ComPtr<IDWriteFontFamily> family;
  HRESULT hr = collection_->GetFontFamily(family_index, &family);
  if (FAILED(hr)) {
    return;
  }

  UINT32 font_count = family->GetFontCount();

  std::set<base::string16> path_set;
  // Iterate through all the fonts in the family, and all the files for those
  // fonts. If anything goes wrong, bail on the entire family to avoid having
  // a partially-loaded font family.
  for (UINT32 font_index = 0; font_index < font_count; ++font_index) {
    mswr::ComPtr<IDWriteFont> font;
    hr = family->GetFont(font_index, &font);
    if (FAILED(hr)) {
      return;
    }

    AddFilesForFont(&path_set, font.Get());
  }

  file_paths->assign(path_set.begin(), path_set.end());
}

void DWriteFontProxyMessageFilter::OnMapCharacters(
    const base::string16& text,
    const DWriteFontStyle& font_style,
    const base::string16& locale_name,
    uint32_t reading_direction,
    const base::string16& base_family_name,
    MapCharactersResult* result) {
  InitializeDirectWrite();
  result->family_index = UINT32_MAX;
  result->mapped_length = text.length();
  result->family_name.clear();
  result->scale = 0.0;
  result->font_style.font_slant = DWRITE_FONT_STYLE_NORMAL;
  result->font_style.font_stretch = DWRITE_FONT_STRETCH_NORMAL;
  result->font_style.font_weight = DWRITE_FONT_WEIGHT_NORMAL;
  if (factory2_ == nullptr || collection_ == nullptr)
    return;
  if (font_fallback_ == nullptr) {
    if (FAILED(factory2_->GetSystemFontFallback(&font_fallback_)))
      return;
  }

  UINT32 length;
  mswr::ComPtr<IDWriteFont> mapped_font;

  mswr::ComPtr<IDWriteNumberSubstitution> number_substitution;
  if (FAILED(factory2_->CreateNumberSubstitution(
          DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE, locale_name.c_str(),
          TRUE /* ignoreUserOverride */, &number_substitution))) {
    DCHECK(false);
    return;
  }
  mswr::ComPtr<IDWriteTextAnalysisSource> analysis_source;
  if (FAILED(mswr::MakeAndInitialize<TextAnalysisSource>(
          &analysis_source, text, locale_name, number_substitution.Get(),
          static_cast<DWRITE_READING_DIRECTION>(reading_direction)))) {
    DCHECK(false);
    return;
  }

  if (FAILED(font_fallback_->MapCharacters(
          analysis_source.Get(), 0, text.length(), collection_.Get(),
          base_family_name.c_str(),
          static_cast<DWRITE_FONT_WEIGHT>(font_style.font_weight),
          static_cast<DWRITE_FONT_STYLE>(font_style.font_slant),
          static_cast<DWRITE_FONT_STRETCH>(font_style.font_stretch), &length,
          &mapped_font, &result->scale))) {
    DCHECK(false);
    return;
  }

  result->mapped_length = length;
  if (mapped_font == nullptr)
    return;

  mswr::ComPtr<IDWriteFontFamily> mapped_family;
  if (FAILED(mapped_font->GetFontFamily(&mapped_family))) {
    DCHECK(false);
    return;
  }
  mswr::ComPtr<IDWriteLocalizedStrings> family_names;
  if (FAILED(mapped_family->GetFamilyNames(&family_names))) {
    DCHECK(false);
    return;
  }

  result->font_style.font_slant = mapped_font->GetStyle();
  result->font_style.font_stretch = mapped_font->GetStretch();
  result->font_style.font_weight = mapped_font->GetWeight();

  std::vector<base::char16> name;
  size_t name_count = family_names->GetCount();
  for (size_t name_index = 0; name_index < name_count; name_index++) {
    UINT32 name_length = 0;
    if (FAILED(family_names->GetStringLength(name_index, &name_length)))
      continue;  // Keep trying other names

    ++name_length;  // Reserve space for the null terminator.
    name.resize(name_length);
    if (FAILED(family_names->GetString(name_index, name.data(), name_length)))
      continue;
    UINT32 index = UINT32_MAX;
    BOOL exists = false;
    if (FAILED(collection_->FindFamilyName(name.data(), &index, &exists)) ||
        !exists)
      continue;

    // Found a matching family!
    result->family_index = index;
    result->family_name = name.data();
    return;
  }
  // Could not find a matching family
  // TODO(kulshin): log UMA that we matched a font, but could not locate the
  // family
  DCHECK_EQ(result->family_index, UINT32_MAX);
  DCHECK_GT(result->mapped_length, 0u);
}

void DWriteFontProxyMessageFilter::InitializeDirectWrite() {
  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
  if (direct_write_initialized_)
    return;
  direct_write_initialized_ = true;

  mswr::ComPtr<IDWriteFactory> factory;
  gfx::win::CreateDWriteFactory(&factory);
  if (factory == nullptr) {
    // We won't be able to load fonts, but we should still return messages so
    // renderers don't hang if they for some reason send us a font message.
    return;
  }

  // QueryInterface for IDWriteFactory2. It's ok for this to fail if we are
  // running an older version of DirectWrite (earlier than Win8.1).
  factory.As<IDWriteFactory2>(&factory2_);

  HRESULT hr = factory->GetSystemFontCollection(&collection_);
  DCHECK(SUCCEEDED(hr));
}

bool DWriteFontProxyMessageFilter::AddFilesForFont(
    std::set<base::string16>* path_set,
    IDWriteFont* font) {
  mswr::ComPtr<IDWriteFontFace> font_face;
  HRESULT hr;
  hr = font->CreateFontFace(&font_face);
  if (FAILED(hr)) {
    return false;
  }

  UINT32 file_count;
  hr = font_face->GetFiles(&file_count, nullptr);
  if (FAILED(hr)) {
    return false;
  }

  std::vector<mswr::ComPtr<IDWriteFontFile>> font_files;
  font_files.resize(file_count);
  hr = font_face->GetFiles(
      &file_count, reinterpret_cast<IDWriteFontFile**>(font_files.data()));
  if (FAILED(hr)) {
    return false;
  }

  for (unsigned int file_index = 0; file_index < file_count; ++file_index) {
    mswr::ComPtr<IDWriteFontFileLoader> loader;
    hr = font_files[file_index]->GetLoader(&loader);
    if (FAILED(hr)) {
      return false;
    }

    mswr::ComPtr<IDWriteLocalFontFileLoader> local_loader;
    hr = loader.CopyTo(local_loader.GetAddressOf());  // QueryInterface.

    if (hr == E_NOINTERFACE) {
      // We could get here if the system font collection contains fonts that
      // are backed by something other than files in the system fonts folder.
      // I don't think that is actually possible, so for now we'll just
      // ignore it (result will be that we'll be unable to match any styles
      // for this font, forcing blink/skia to fall back to whatever font is
      // next). If we get telemetry indicating that this case actually
      // happens, we can implement this by exposing the loader via ipc. That
      // will likely be by loading the font data into shared memory, although
      // we could proxy the stream reads directly instead.
      LogLoaderType(OTHER_LOADER);
      DCHECK(false);

      return false;
    } else if (FAILED(hr)) {
      return false;
    }

    if (!AddLocalFile(path_set, local_loader.Get(),
                      font_files[file_index].Get())) {
      return false;
    }
  }
  return true;
}

bool DWriteFontProxyMessageFilter::AddLocalFile(
    std::set<base::string16>* path_set,
    IDWriteLocalFontFileLoader* local_loader,
    IDWriteFontFile* font_file) {
  HRESULT hr;
  const void* key;
  UINT32 key_size;
  hr = font_file->GetReferenceKey(&key, &key_size);
  if (FAILED(hr)) {
    return false;
  }

  UINT32 path_length = 0;
  hr = local_loader->GetFilePathLengthFromKey(key, key_size, &path_length);
  if (FAILED(hr)) {
    return false;
  }
  ++path_length;  // Reserve space for the null terminator.
  std::vector<base::char16> file_path_chars;
  file_path_chars.resize(path_length);
  hr = local_loader->GetFilePathFromKey(key, key_size, file_path_chars.data(),
                                        path_length);
  if (FAILED(hr)) {
    return false;
  }

  base::string16 file_path = base::i18n::FoldCase(file_path_chars.data());
  if (!base::StartsWith(file_path, windows_fonts_path_,
                        base::CompareCase::SENSITIVE)) {
    // Skip loading fonts from outside the system fonts directory, since
    // these families will not be accessible to the renderer process. If
    // this turns out to be a common case, we can either grant the renderer
    // access to these files (not sure if this is actually possible), or
    // load the file data ourselves and hand it to the renderer.

    // Really, really, really want to know what families hit this. Current
    // data indicates about 0.09% of families fall into this case. Nothing to
    // worry about if it's random obscure fonts noone has ever heard of, but
    // could be a problem if it's common fonts.

    LogLoaderType(FILE_OUTSIDE_SANDBOX);
    NOTREACHED();  // Not yet implemented.
    return false;
  }

  // Refer to comments in kFontsToIgnore for this block.
  for (const auto& file_to_ignore : kFontsToIgnore) {
    // Ok to do ascii comparison since the strings we are looking for are
    // all ascii.
    if (base::EndsWith(file_path, file_to_ignore,
                       base::CompareCase::INSENSITIVE_ASCII)) {
      // Unlike most other cases in this function, we do not abort loading
      // the entire family, since we want to specifically ignore particular
      // font styles and load the rest of the family if it exists. The
      // renderer can deal with a family with zero files if that ends up
      // being the case.
      return true;
    }
  }

  LogLoaderType(FILE_SYSTEM_FONT_DIR);
  path_set->insert(file_path);
  return true;
}

}  // namespace content
