// Copyright 2020 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "core/fxge/win32/cwin32_platform.h"

#include <iterator>
#include <memory>
#include <utility>

#include "core/fxcrt/fx_codepage.h"
#include "core/fxge/cfx_folderfontinfo.h"
#include "core/fxge/cfx_gemodule.h"
#include "third_party/base/check.h"
#include "third_party/base/numerics/safe_conversions.h"
#include "third_party/base/span.h"
#include "third_party/base/win/scoped_select_object.h"
#include "third_party/base/win/win_util.h"

namespace {

using ScopedSelectObject = pdfium::base::win::ScopedSelectObject;

struct Variant {
  const char* m_pFaceName;
  const char* m_pVariantName;  // Note: UTF-16LE terminator required.
};

constexpr Variant kVariantNames[] = {
    {"DFKai-SB", "\x19\x6A\x77\x69\xD4\x9A\x00\x00"},
};

struct Substs {
  const char* m_pName;
  const char* m_pWinName;
  bool m_bBold;
  bool m_bItalic;
};

constexpr Substs kBase14Substs[] = {
    {"Courier", "Courier New", false, false},
    {"Courier-Bold", "Courier New", true, false},
    {"Courier-BoldOblique", "Courier New", true, true},
    {"Courier-Oblique", "Courier New", false, true},
    {"Helvetica", "Arial", false, false},
    {"Helvetica-Bold", "Arial", true, false},
    {"Helvetica-BoldOblique", "Arial", true, true},
    {"Helvetica-Oblique", "Arial", false, true},
    {"Times-Roman", "Times New Roman", false, false},
    {"Times-Bold", "Times New Roman", true, false},
    {"Times-BoldItalic", "Times New Roman", true, true},
    {"Times-Italic", "Times New Roman", false, true},
};

struct FontNameMap {
  const char* m_pSubFontName;
  const char* m_pSrcFontName;
};

constexpr FontNameMap kJpFontNameMap[] = {
    {"MS Mincho", "Heiseimin-W3"},
    {"MS Gothic", "Jun101-Light"},
};

bool GetSubFontName(ByteString* name) {
  for (size_t i = 0; i < std::size(kJpFontNameMap); ++i) {
    if (!FXSYS_stricmp(name->c_str(), kJpFontNameMap[i].m_pSrcFontName)) {
      *name = kJpFontNameMap[i].m_pSubFontName;
      return true;
    }
  }
  return false;
}

// Wraps CreateFontA() so callers don't have to specify all the arguments.
HFONT Win32CreateFont(int weight,
                      bool italic,
                      FX_Charset charset,
                      int pitch_family,
                      const char* face) {
  return ::CreateFontA(-10, 0, 0, 0, weight, italic, 0, 0,
                       static_cast<int>(charset), OUT_TT_ONLY_PRECIS, 0, 0,
                       pitch_family, face);
}

class CFX_Win32FallbackFontInfo final : public CFX_FolderFontInfo {
 public:
  CFX_Win32FallbackFontInfo() = default;
  ~CFX_Win32FallbackFontInfo() override = default;

  // CFX_FolderFontInfo:
  void* MapFont(int weight,
                bool bItalic,
                FX_Charset charset,
                int pitch_family,
                const ByteString& face) override;
};

class CFX_Win32FontInfo final : public SystemFontInfoIface {
 public:
  CFX_Win32FontInfo();
  ~CFX_Win32FontInfo() override;

  // SystemFontInfoIface:
  bool EnumFontList(CFX_FontMapper* pMapper) override;
  void* MapFont(int weight,
                bool bItalic,
                FX_Charset charset,
                int pitch_family,
                const ByteString& face) override;
  void* GetFont(const ByteString& face) override { return nullptr; }
  size_t GetFontData(void* hFont,
                     uint32_t table,
                     pdfium::span<uint8_t> buffer) override;
  bool GetFaceName(void* hFont, ByteString* name) override;
  bool GetFontCharset(void* hFont, FX_Charset* charset) override;
  void DeleteFont(void* hFont) override;

  void AddInstalledFont(const LOGFONTA* plf, uint32_t font_type);

 private:
  bool IsSupportedFont(const LOGFONTA* plf);
  void GetGBPreference(ByteString& face, int weight, int pitch_family);
  void GetJapanesePreference(ByteString& face, int weight, int pitch_family);
  ByteString FindFont(const ByteString& name);
  void* GetFontFromList(int weight,
                        bool italic,
                        FX_Charset charset,
                        int pitch_family,
                        pdfium::span<const char* const> font_faces);

  const HDC m_hDC;
  UnownedPtr<CFX_FontMapper> m_pMapper;
  ByteString m_LastFamily;
  ByteString m_KaiTi;
  ByteString m_FangSong;
};

int CALLBACK FontEnumProc(const LOGFONTA* plf,
                          const TEXTMETRICA* lpntme,
                          uint32_t font_type,
                          LPARAM lParam) {
  CFX_Win32FontInfo* pFontInfo = reinterpret_cast<CFX_Win32FontInfo*>(lParam);
  pFontInfo->AddInstalledFont(plf, font_type);
  return 1;
}

CFX_Win32FontInfo::CFX_Win32FontInfo() : m_hDC(CreateCompatibleDC(nullptr)) {}

CFX_Win32FontInfo::~CFX_Win32FontInfo() {
  DeleteDC(m_hDC);
}

bool CFX_Win32FontInfo::IsSupportedFont(const LOGFONTA* plf) {
  HFONT hFont = CreateFontIndirectA(plf);
  bool ret = false;
  size_t font_size = GetFontData(hFont, 0, {});
  if (font_size != GDI_ERROR && font_size >= sizeof(uint32_t)) {
    uint32_t header;
    auto span = pdfium::as_writable_bytes(pdfium::make_span(&header, 1));
    GetFontData(hFont, 0, span);
    header = FXSYS_UINT32_GET_MSBFIRST(span);
    ret = header == FXBSTR_ID('O', 'T', 'T', 'O') ||
          header == FXBSTR_ID('t', 't', 'c', 'f') ||
          header == FXBSTR_ID('t', 'r', 'u', 'e') || header == 0x00010000 ||
          header == 0x00020000 ||
          (header & 0xFFFF0000) == FXBSTR_ID(0x80, 0x01, 0x00, 0x00) ||
          (header & 0xFFFF0000) == FXBSTR_ID('%', '!', 0, 0);
  }
  DeleteFont(hFont);
  return ret;
}

void CFX_Win32FontInfo::AddInstalledFont(const LOGFONTA* plf,
                                         uint32_t font_type) {
  ByteString name(plf->lfFaceName);
  if (name.GetLength() > 0 && name[0] == '@')
    return;

  if (name == m_LastFamily) {
    m_pMapper->AddInstalledFont(name, FX_GetCharsetFromInt(plf->lfCharSet));
    return;
  }
  if (!(font_type & TRUETYPE_FONTTYPE)) {
    if (!(font_type & DEVICE_FONTTYPE) || !IsSupportedFont(plf))
      return;
  }

  m_pMapper->AddInstalledFont(name, FX_GetCharsetFromInt(plf->lfCharSet));
  m_LastFamily = name;
}

bool CFX_Win32FontInfo::EnumFontList(CFX_FontMapper* pMapper) {
  m_pMapper = pMapper;
  LOGFONTA lf;
  memset(&lf, 0, sizeof(LOGFONTA));
  lf.lfCharSet = static_cast<int>(FX_Charset::kDefault);
  lf.lfFaceName[0] = 0;
  lf.lfPitchAndFamily = 0;
  EnumFontFamiliesExA(m_hDC, &lf, reinterpret_cast<FONTENUMPROCA>(FontEnumProc),
                      reinterpret_cast<uintptr_t>(this), 0);
  return true;
}

ByteString CFX_Win32FontInfo::FindFont(const ByteString& name) {
  if (!m_pMapper)
    return name;

  absl::optional<ByteString> maybe_installed =
      m_pMapper->InstalledFontNameStartingWith(name);
  if (maybe_installed.has_value())
    return maybe_installed.value();

  absl::optional<ByteString> maybe_localized =
      m_pMapper->LocalizedFontNameStartingWith(name);
  if (maybe_localized.has_value())
    return maybe_localized.value();

  return ByteString();
}

void* CFX_Win32FontInfo::GetFontFromList(
    int weight,
    bool italic,
    FX_Charset charset,
    int pitch_family,
    pdfium::span<const char* const> font_faces) {
  DCHECK(!font_faces.empty());

  // Initialization not needed because of DCHECK() above and the assignment in
  // the for-loop below.
  HFONT font;
  for (const char* face : font_faces) {
    font = Win32CreateFont(weight, italic, charset, pitch_family, face);
    ByteString actual_face;
    if (GetFaceName(font, &actual_face) && actual_face.EqualNoCase(face))
      break;
  }
  return font;
}

void* CFX_Win32FallbackFontInfo::MapFont(int weight,
                                         bool bItalic,
                                         FX_Charset charset,
                                         int pitch_family,
                                         const ByteString& face) {
  void* font = GetSubstFont(face);
  if (font)
    return font;

  bool bCJK = true;
  switch (charset) {
    case FX_Charset::kShiftJIS:
    case FX_Charset::kChineseSimplified:
    case FX_Charset::kChineseTraditional:
    case FX_Charset::kHangul:
      break;
    default:
      bCJK = false;
      break;
  }
  return FindFont(weight, bItalic, charset, pitch_family, face, !bCJK);
}

void CFX_Win32FontInfo::GetGBPreference(ByteString& face,
                                        int weight,
                                        int pitch_family) {
  if (face.Contains("KaiTi") || face.Contains("\xbf\xac")) {
    if (m_KaiTi.IsEmpty()) {
      m_KaiTi = FindFont("KaiTi");
      if (m_KaiTi.IsEmpty()) {
        m_KaiTi = "SimSun";
      }
    }
    face = m_KaiTi;
  } else if (face.Contains("FangSong") || face.Contains("\xb7\xc2\xcb\xce")) {
    if (m_FangSong.IsEmpty()) {
      m_FangSong = FindFont("FangSong");
      if (m_FangSong.IsEmpty()) {
        m_FangSong = "SimSun";
      }
    }
    face = m_FangSong;
  } else if (face.Contains("SimSun") || face.Contains("\xcb\xce")) {
    face = "SimSun";
  } else if (face.Contains("SimHei") || face.Contains("\xba\xda")) {
    face = "SimHei";
  } else if (!(pitch_family & FF_ROMAN) && weight > 550) {
    face = "SimHei";
  } else {
    face = "SimSun";
  }
}

void CFX_Win32FontInfo::GetJapanesePreference(ByteString& face,
                                              int weight,
                                              int pitch_family) {
  if (face.Contains("Gothic") ||
      face.Contains("\x83\x53\x83\x56\x83\x62\x83\x4e")) {
    if (face.Contains("PGothic") ||
        face.Contains("\x82\x6f\x83\x53\x83\x56\x83\x62\x83\x4e")) {
      face = "MS PGothic";
    } else if (face.Contains("UI Gothic")) {
      face = "MS UI Gothic";
    } else {
      if (face.Contains("HGSGothicM") || face.Contains("HGMaruGothicMPRO")) {
        face = "MS PGothic";
      } else {
        face = "MS Gothic";
      }
    }
    return;
  }
  if (face.Contains("Mincho") || face.Contains("\x96\xbe\x92\xa9")) {
    if (face.Contains("PMincho") || face.Contains("\x82\x6f\x96\xbe\x92\xa9")) {
      face = "MS PMincho";
    } else {
      face = "MS Mincho";
    }
    return;
  }
  if (GetSubFontName(&face))
    return;

  if (!(pitch_family & FF_ROMAN) && weight > 400) {
    face = "MS PGothic";
  } else {
    face = "MS PMincho";
  }
}

void* CFX_Win32FontInfo::MapFont(int weight,
                                 bool bItalic,
                                 FX_Charset charset,
                                 int pitch_family,
                                 const ByteString& face) {
  ByteString new_face = face;
  for (int iBaseFont = 0; iBaseFont < 12; iBaseFont++) {
    if (new_face == ByteStringView(kBase14Substs[iBaseFont].m_pName)) {
      new_face = kBase14Substs[iBaseFont].m_pWinName;
      weight = kBase14Substs[iBaseFont].m_bBold ? FW_BOLD : FW_NORMAL;
      bItalic = kBase14Substs[iBaseFont].m_bItalic;
      break;
    }
  }
  if (charset == FX_Charset::kANSI || charset == FX_Charset::kSymbol)
    charset = FX_Charset::kDefault;

  int subst_pitch_family = pitch_family;
  switch (charset) {
    case FX_Charset::kShiftJIS:
      subst_pitch_family = FF_ROMAN;
      break;
    case FX_Charset::kChineseTraditional:
    case FX_Charset::kHangul:
    case FX_Charset::kChineseSimplified:
      subst_pitch_family = 0;
      break;
  }
  HFONT hFont = Win32CreateFont(weight, bItalic, charset, subst_pitch_family,
                                new_face.c_str());
  ByteString actual_new_face;
  if (GetFaceName(hFont, &actual_new_face) &&
      new_face.EqualNoCase(actual_new_face.AsStringView())) {
    return hFont;
  }

  WideString wsFace = WideString::FromDefANSI(actual_new_face.AsStringView());
  for (const Variant& variant : kVariantNames) {
    if (new_face != variant.m_pFaceName)
      continue;

    const auto* pName =
        reinterpret_cast<const unsigned short*>(variant.m_pVariantName);
    size_t len = WideString::WStringLength(pName);
    WideString wsName = WideString::FromUTF16LE(pName, len);
    if (wsFace == wsName)
      return hFont;
  }
  ::DeleteObject(hFont);
  if (charset == FX_Charset::kDefault)
    return nullptr;

  switch (charset) {
    case FX_Charset::kShiftJIS:
      GetJapanesePreference(new_face, weight, pitch_family);
      break;
    case FX_Charset::kChineseSimplified:
      GetGBPreference(new_face, weight, pitch_family);
      break;
    case FX_Charset::kHangul:
      new_face = "Gulim";
      break;
    case FX_Charset::kChineseTraditional:
      static const char* const kMonospaceFonts[] = {"Microsoft YaHei",
                                                    "MingLiU"};
      static const char* const kProportionalFonts[] = {"Microsoft JHengHei",
                                                       "PMingLiU"};
      pdfium::span<const char* const> candidate_fonts =
          new_face.Contains("MSung") ? kMonospaceFonts : kProportionalFonts;
      return GetFontFromList(weight, bItalic, charset, subst_pitch_family,
                             candidate_fonts);
  }
  return Win32CreateFont(weight, bItalic, charset, subst_pitch_family,
                         new_face.c_str());
}

void CFX_Win32FontInfo::DeleteFont(void* hFont) {
  ::DeleteObject(hFont);
}

size_t CFX_Win32FontInfo::GetFontData(void* hFont,
                                      uint32_t table,
                                      pdfium::span<uint8_t> buffer) {
  ScopedSelectObject select_object(m_hDC, static_cast<HFONT>(hFont));
  table = FXSYS_UINT32_GET_MSBFIRST(reinterpret_cast<uint8_t*>(&table));
  size_t size = ::GetFontData(m_hDC, table, 0, buffer.data(),
                              pdfium::base::checked_cast<DWORD>(buffer.size()));
  return size != GDI_ERROR ? size : 0;
}

bool CFX_Win32FontInfo::GetFaceName(void* hFont, ByteString* name) {
  ScopedSelectObject select_object(m_hDC, static_cast<HFONT>(hFont));
  char facebuf[100];
  if (::GetTextFaceA(m_hDC, std::size(facebuf), facebuf) == 0)
    return false;

  *name = facebuf;
  return true;
}

bool CFX_Win32FontInfo::GetFontCharset(void* hFont, FX_Charset* charset) {
  ScopedSelectObject select_object(m_hDC, static_cast<HFONT>(hFont));
  TEXTMETRIC tm;
  ::GetTextMetrics(m_hDC, &tm);
  *charset = FX_GetCharsetFromInt(tm.tmCharSet);
  return true;
}

}  // namespace

CWin32Platform::CWin32Platform() = default;

CWin32Platform::~CWin32Platform() = default;

void CWin32Platform::Init() {
  if (pdfium::base::win::IsUser32AndGdi32Available())
    m_GdiplusExt.Load();
}

std::unique_ptr<SystemFontInfoIface>
CWin32Platform::CreateDefaultSystemFontInfo() {
  auto** user_paths = CFX_GEModule::Get()->GetUserFontPaths();
  if (user_paths) {
    auto font_info = std::make_unique<CFX_Win32FallbackFontInfo>();
    for (; *user_paths; user_paths++)
      font_info->AddPath(*user_paths);
    return std::move(font_info);
  }

  if (pdfium::base::win::IsUser32AndGdi32Available())
    return std::make_unique<CFX_Win32FontInfo>();

  // Select the fallback font information class if GDI is disabled.
  auto fallback_info = std::make_unique<CFX_Win32FallbackFontInfo>();
  // Construct the font path manually, SHGetKnownFolderPath won't work under
  // a restrictive sandbox.
  CHAR windows_path[MAX_PATH] = {};
  DWORD path_len = ::GetWindowsDirectoryA(windows_path, MAX_PATH);
  if (path_len > 0 && path_len < MAX_PATH) {
    ByteString fonts_path(windows_path);
    fonts_path += "\\Fonts";
    fallback_info->AddPath(fonts_path);
  }
  return fallback_info;
}

// static
std::unique_ptr<CFX_GEModule::PlatformIface>
CFX_GEModule::PlatformIface::Create() {
  return std::make_unique<CWin32Platform>();
}
