// 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 "ui/gfx/font_fallback_win.h"

#include <dwrite_2.h>
#include <usp10.h>
#include <wrl.h>

#include <algorithm>
#include <map>

#include "base/i18n/rtl.h"
#include "base/macros.h"
#include "base/memory/singleton.h"
#include "base/message_loop/message_loop.h"
#include "base/profiler/scoped_tracker.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/registry.h"
#include "base/win/scoped_comptr.h"
#include "ui/gfx/font.h"
#include "ui/gfx/font_fallback.h"
#include "ui/gfx/platform_font_win.h"
#include "ui/gfx/win/direct_write.h"
#include "ui/gfx/win/text_analysis_source.h"

namespace gfx {

namespace {

// Queries the registry to get a mapping from font filenames to font names.
void QueryFontsFromRegistry(std::map<std::string, std::string>* map) {
  const wchar_t* kFonts =
      L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts";

  base::win::RegistryValueIterator it(HKEY_LOCAL_MACHINE, kFonts);
  for (; it.Valid(); ++it) {
    const std::string filename =
        base::ToLowerASCII(base::WideToUTF8(it.Value()));
    (*map)[filename] = base::WideToUTF8(it.Name());
  }
}

// Fills |font_names| with a list of font families found in the font file at
// |filename|. Takes in a |font_map| from font filename to font families, which
// is filled-in by querying the registry, if empty.
void GetFontNamesFromFilename(const std::string& filename,
                              std::map<std::string, std::string>* font_map,
                              std::vector<std::string>* font_names) {
  if (font_map->empty())
    QueryFontsFromRegistry(font_map);

  std::map<std::string, std::string>::const_iterator it =
      font_map->find(base::ToLowerASCII(filename));
  if (it == font_map->end())
    return;

  internal::ParseFontFamilyString(it->second, font_names);
}

// Returns true if |text| contains only ASCII digits.
bool ContainsOnlyDigits(const std::string& text) {
  return text.find_first_not_of("0123456789") == base::string16::npos;
}

// Appends a Font with the given |name| and |size| to |fonts| unless the last
// entry is already a font with that name.
void AppendFont(const std::string& name, int size, std::vector<Font>* fonts) {
  if (fonts->empty() || fonts->back().GetFontName() != name)
    fonts->push_back(Font(name, size));
}

// Queries the registry to get a list of linked fonts for |font|.
void QueryLinkedFontsFromRegistry(const Font& font,
                                  std::map<std::string, std::string>* font_map,
                                  std::vector<Font>* linked_fonts) {
  const wchar_t* kSystemLink =
      L"Software\\Microsoft\\Windows NT\\CurrentVersion\\FontLink\\SystemLink";

  base::win::RegKey key;
  if (FAILED(key.Open(HKEY_LOCAL_MACHINE, kSystemLink, KEY_READ)))
    return;

  const std::wstring original_font_name = base::UTF8ToWide(font.GetFontName());
  std::vector<std::wstring> values;
  if (FAILED(key.ReadValues(original_font_name.c_str(), &values))) {
    key.Close();
    return;
  }

  std::string filename;
  std::string font_name;
  for (size_t i = 0; i < values.size(); ++i) {
    internal::ParseFontLinkEntry(
        base::WideToUTF8(values[i]), &filename, &font_name);
    // If the font name is present, add that directly, otherwise add the
    // font names corresponding to the filename.
    if (!font_name.empty()) {
      AppendFont(font_name, font.GetFontSize(), linked_fonts);
    } else if (!filename.empty()) {
      std::vector<std::string> font_names;
      GetFontNamesFromFilename(filename, font_map, &font_names);
      for (size_t i = 0; i < font_names.size(); ++i)
        AppendFont(font_names[i], font.GetFontSize(), linked_fonts);
    }
  }

  key.Close();
}

// CachedFontLinkSettings is a singleton cache of the Windows font settings
// from the registry. It maintains a cached view of the registry's list of
// system fonts and their font link chains.
class CachedFontLinkSettings {
 public:
  static CachedFontLinkSettings* GetInstance();

  // Returns the linked fonts list correspond to |font|. Returned value will
  // never be null.
  const std::vector<Font>* GetLinkedFonts(const Font& font);

 private:
  friend struct base::DefaultSingletonTraits<CachedFontLinkSettings>;

  CachedFontLinkSettings();
  virtual ~CachedFontLinkSettings();

  // Map of system fonts, from file names to font families.
  std::map<std::string, std::string> cached_system_fonts_;

  // Map from font names to vectors of linked fonts.
  std::map<std::string, std::vector<Font> > cached_linked_fonts_;

  DISALLOW_COPY_AND_ASSIGN(CachedFontLinkSettings);
};

// static
CachedFontLinkSettings* CachedFontLinkSettings::GetInstance() {
  return base::Singleton<
      CachedFontLinkSettings,
      base::LeakySingletonTraits<CachedFontLinkSettings>>::get();
}

const std::vector<Font>* CachedFontLinkSettings::GetLinkedFonts(
    const Font& font) {
  const std::string& font_name = font.GetFontName();
  std::map<std::string, std::vector<Font> >::const_iterator it =
      cached_linked_fonts_.find(font_name);
  if (it != cached_linked_fonts_.end())
    return &it->second;

  cached_linked_fonts_[font_name] = std::vector<Font>();
  std::vector<Font>* linked_fonts = &cached_linked_fonts_[font_name];

  // TODO(ckocagil): Remove ScopedTracker below once crbug.com/441028 is fixed.
  tracked_objects::ScopedTracker tracking_profile(
      FROM_HERE_WITH_EXPLICIT_FUNCTION(
          "441028 QueryLinkedFontsFromRegistry()"));

  QueryLinkedFontsFromRegistry(font, &cached_system_fonts_, linked_fonts);
  return linked_fonts;
}

CachedFontLinkSettings::CachedFontLinkSettings() {
}

CachedFontLinkSettings::~CachedFontLinkSettings() {
}

// Callback to |EnumEnhMetaFile()| to intercept font creation.
int CALLBACK MetaFileEnumProc(HDC hdc,
                              HANDLETABLE* table,
                              CONST ENHMETARECORD* record,
                              int table_entries,
                              LPARAM log_font) {
  if (record->iType == EMR_EXTCREATEFONTINDIRECTW) {
    const EMREXTCREATEFONTINDIRECTW* create_font_record =
        reinterpret_cast<const EMREXTCREATEFONTINDIRECTW*>(record);
    *reinterpret_cast<LOGFONT*>(log_font) = create_font_record->elfw.elfLogFont;
  }
  return 1;
}

bool GetUniscribeFallbackFont(const Font& font,
                              const wchar_t* text,
                              int text_length,
                              Font* result) {
  // Adapted from WebKit's |FontCache::GetFontDataForCharacters()|.
  // Uniscribe doesn't expose a method to query fallback fonts, so this works by
  // drawing the text to an EMF object with Uniscribe's ScriptStringOut and then
  // inspecting the EMF object to figure out which font Uniscribe used.
  //
  // DirectWrite in Windows 8.1 provides a cleaner alternative:
  // http://msdn.microsoft.com/en-us/library/windows/desktop/dn280480.aspx

  static HDC hdc = CreateCompatibleDC(NULL);

  // Use a meta file to intercept the fallback font chosen by Uniscribe.
  HDC meta_file_dc = CreateEnhMetaFile(hdc, NULL, NULL, NULL);
  if (!meta_file_dc)
    return false;

  SelectObject(meta_file_dc, font.GetNativeFont());

  SCRIPT_STRING_ANALYSIS script_analysis;
  HRESULT hresult =
      ScriptStringAnalyse(meta_file_dc, text, text_length, 0, -1,
                          SSA_METAFILE | SSA_FALLBACK | SSA_GLYPHS | SSA_LINK,
                          0, NULL, NULL, NULL, NULL, NULL, &script_analysis);

  if (SUCCEEDED(hresult)) {
    hresult = ScriptStringOut(script_analysis, 0, 0, 0, NULL, 0, 0, FALSE);
    ScriptStringFree(&script_analysis);
  }

  bool found_fallback = false;
  HENHMETAFILE meta_file = CloseEnhMetaFile(meta_file_dc);
  if (SUCCEEDED(hresult)) {
    LOGFONT log_font;
    log_font.lfFaceName[0] = 0;
    EnumEnhMetaFile(0, meta_file, MetaFileEnumProc, &log_font, NULL);
    if (log_font.lfFaceName[0]) {
      *result =
          Font(base::UTF16ToUTF8(log_font.lfFaceName), font.GetFontSize());
      found_fallback = true;
    }
  }
  DeleteEnhMetaFile(meta_file);

  return found_fallback;
}

}  // namespace

namespace internal {

void ParseFontLinkEntry(const std::string& entry,
                        std::string* filename,
                        std::string* font_name) {
  std::vector<std::string> parts = base::SplitString(
      entry, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  filename->clear();
  font_name->clear();
  if (parts.size() > 0)
    *filename = parts[0];
  // The second entry may be the font name or the first scaling factor, if the
  // entry does not contain a font name. If it contains only digits, assume it
  // is a scaling factor.
  if (parts.size() > 1 && !ContainsOnlyDigits(parts[1]))
    *font_name = parts[1];
}

void ParseFontFamilyString(const std::string& family,
                           std::vector<std::string>* font_names) {
  // The entry is comma separated, having the font filename as the first value
  // followed optionally by the font family name and a pair of integer scaling
  // factors.
  // TODO(asvitkine): Should we support these scaling factors?
  *font_names = base::SplitString(
      family, "&", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  if (!font_names->empty()) {
    const size_t index = font_names->back().find('(');
    if (index != std::string::npos) {
      font_names->back().resize(index);
      base::TrimWhitespaceASCII(font_names->back(), base::TRIM_TRAILING,
                                &font_names->back());
    }
  }
}

LinkedFontsIterator::LinkedFontsIterator(Font font)
    : original_font_(font),
      next_font_set_(false),
      linked_fonts_(NULL),
      linked_font_index_(0) {
  SetNextFont(original_font_);
}

LinkedFontsIterator::~LinkedFontsIterator() {
}

void LinkedFontsIterator::SetNextFont(Font font) {
  next_font_ = font;
  next_font_set_ = true;
}

bool LinkedFontsIterator::NextFont(Font* font) {
  if (next_font_set_) {
    next_font_set_ = false;
    current_font_ = next_font_;
    *font = current_font_;
    return true;
  }

  // First time through, get the linked fonts list.
  if (linked_fonts_ == NULL)
    linked_fonts_ = GetLinkedFonts();

  if (linked_font_index_ == linked_fonts_->size())
    return false;

  current_font_ = linked_fonts_->at(linked_font_index_++);
  *font = current_font_;
  return true;
}

const std::vector<Font>* LinkedFontsIterator::GetLinkedFonts() const {
  CachedFontLinkSettings* font_link = CachedFontLinkSettings::GetInstance();

  // First, try to get the list for the original font.
  const std::vector<Font>* fonts = font_link->GetLinkedFonts(original_font_);

  // If there are no linked fonts for the original font, try querying the
  // ones for the current font. This may happen if the first font is a custom
  // font that has no linked fonts in the registry.
  //
  // Note: One possibility would be to always merge both lists of fonts,
  //       but it is not clear whether there are any real world scenarios
  //       where this would actually help.
  if (fonts->empty())
    fonts = font_link->GetLinkedFonts(current_font_);

  return fonts;
}

}  // namespace internal

std::vector<Font> GetFallbackFonts(const Font& font) {
  std::string font_family = font.GetFontName();

  // LinkedFontsIterator doesn't care about the font size, so we always pass 10.
  internal::LinkedFontsIterator linked_fonts(Font(font_family, 10));
  std::vector<Font> fallback_fonts;
  Font current;
  while (linked_fonts.NextFont(&current))
    fallback_fonts.push_back(current);
  return fallback_fonts;
}

bool GetFallbackFont(const Font& font,
                     const wchar_t* text,
                     int text_length,
                     Font* result) {
  // Creating a DirectWrite font fallback can be expensive. It's ok in the
  // browser process because we can use the shared system fallback, but in the
  // renderer this can cause hangs. Code that needs font fallback in the
  // renderer should instead use the font proxy.
  DCHECK(base::MessageLoopForUI::IsCurrent());

  // Check that we have at least as much text as was claimed. If we have less
  // text than expected then DirectWrite will become confused and crash. This
  // shouldn't happen, but crbug.com/624905 shows that it happens sometimes.
  DCHECK_GE(wcslen(text), static_cast<size_t>(text_length));
  text_length = std::min(wcslen(text), static_cast<size_t>(text_length));

  base::win::ScopedComPtr<IDWriteFactory> factory;
  gfx::win::CreateDWriteFactory(factory.Receive());
  base::win::ScopedComPtr<IDWriteFactory2> factory2;
  factory.QueryInterface(factory2.Receive());
  if (!factory2) {
    // IDWriteFactory2 is not available before Win8.1
    return GetUniscribeFallbackFont(font, text, text_length, result);
  }

  base::win::ScopedComPtr<IDWriteFontFallback> fallback;
  if (FAILED(factory2->GetSystemFontFallback(fallback.Receive())))
    return false;

  base::string16 locale = base::UTF8ToUTF16(base::i18n::GetConfiguredLocale());

  base::win::ScopedComPtr<IDWriteNumberSubstitution> number_substitution;
  if (FAILED(factory2->CreateNumberSubstitution(
          DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE, locale.c_str(),
          true /* ignoreUserOverride */, number_substitution.Receive()))) {
    return false;
  }

  uint32_t mapped_length = 0;
  base::win::ScopedComPtr<IDWriteFont> mapped_font;
  float scale = 0;
  base::win::ScopedComPtr<IDWriteTextAnalysisSource> text_analysis;
  DWRITE_READING_DIRECTION reading_direction =
      base::i18n::IsRTL() ? DWRITE_READING_DIRECTION_RIGHT_TO_LEFT
                          : DWRITE_READING_DIRECTION_LEFT_TO_RIGHT;
  if (FAILED(Microsoft::WRL::MakeAndInitialize<gfx::win::TextAnalysisSource>(
          text_analysis.Receive(), text, locale.c_str(),
          number_substitution.get(), reading_direction))) {
    return false;
  }
  base::string16 original_name = base::UTF8ToUTF16(font.GetFontName());
  DWRITE_FONT_STYLE font_style = DWRITE_FONT_STYLE_NORMAL;
  if (font.GetStyle() & Font::ITALIC)
    font_style = DWRITE_FONT_STYLE_ITALIC;
  if (FAILED(fallback->MapCharacters(
          text_analysis.get(), 0, text_length, nullptr, original_name.c_str(),
          static_cast<DWRITE_FONT_WEIGHT>(font.GetWeight()), font_style,
          DWRITE_FONT_STRETCH_NORMAL, &mapped_length, mapped_font.Receive(),
          &scale))) {
    return false;
  }

  if (mapped_font) {
    base::string16 name;
    if (FAILED(GetFamilyNameFromDirectWriteFont(mapped_font.get(), &name)))
      return false;
    *result = Font(base::UTF16ToUTF8(name), font.GetFontSize() * scale);
    return true;
  }
  return false;
}

}  // namespace gfx
