// Copyright 2014 The PDFium Authors
// 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 "public/fpdf_sysfontinfo.h"

#include <stddef.h>

#include <memory>
#include <utility>

#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/fx_codepage.h"
#include "core/fxcrt/numerics/safe_conversions.h"
#include "core/fxcrt/span.h"
#include "core/fxcrt/stl_util.h"
#include "core/fxcrt/unowned_ptr.h"
#include "core/fxge/cfx_font.h"
#include "core/fxge/cfx_fontmapper.h"
#include "core/fxge/cfx_fontmgr.h"
#include "core/fxge/cfx_gemodule.h"
#include "core/fxge/fx_font.h"
#include "core/fxge/systemfontinfo_iface.h"

#ifdef PDF_ENABLE_XFA
#include "xfa/fgas/font/cfgas_fontmgr.h"
#include "xfa/fgas/font/cfgas_gemodule.h"
#endif

static_assert(FXFONT_ANSI_CHARSET == static_cast<int>(FX_Charset::kANSI));
static_assert(FXFONT_DEFAULT_CHARSET == static_cast<int>(FX_Charset::kDefault));
static_assert(FXFONT_SYMBOL_CHARSET == static_cast<int>(FX_Charset::kSymbol));
static_assert(FXFONT_SHIFTJIS_CHARSET ==
              static_cast<int>(FX_Charset::kShiftJIS));
static_assert(FXFONT_HANGEUL_CHARSET == static_cast<int>(FX_Charset::kHangul));
static_assert(FXFONT_GB2312_CHARSET ==
              static_cast<int>(FX_Charset::kChineseSimplified));
static_assert(FXFONT_CHINESEBIG5_CHARSET ==
              static_cast<int>(FX_Charset::kChineseTraditional));
static_assert(FXFONT_GREEK_CHARSET ==
              static_cast<int>(FX_Charset::kMSWin_Greek));
static_assert(FXFONT_VIETNAMESE_CHARSET ==
              static_cast<int>(FX_Charset::kMSWin_Vietnamese));
static_assert(FXFONT_HEBREW_CHARSET ==
              static_cast<int>(FX_Charset::kMSWin_Hebrew));
static_assert(FXFONT_ARABIC_CHARSET ==
              static_cast<int>(FX_Charset::kMSWin_Arabic));
static_assert(FXFONT_CYRILLIC_CHARSET ==
              static_cast<int>(FX_Charset::kMSWin_Cyrillic));
static_assert(FXFONT_THAI_CHARSET == static_cast<int>(FX_Charset::kThai));
static_assert(FXFONT_EASTERNEUROPEAN_CHARSET ==
              static_cast<int>(FX_Charset::kMSWin_EasternEuropean));
static_assert(pdfium::kFontPitchFamilyFixed == FXFONT_FF_FIXEDPITCH);
static_assert(pdfium::kFontPitchFamilyRoman == FXFONT_FF_ROMAN);
static_assert(pdfium::kFontPitchFamilyScript == FXFONT_FF_SCRIPT);
static_assert(offsetof(CFX_Font::CharsetFontMap, charset) ==
              offsetof(FPDF_CharsetFontMap, charset));
static_assert(offsetof(CFX_Font::CharsetFontMap, fontname) ==
              offsetof(FPDF_CharsetFontMap, fontname));
static_assert(sizeof(CFX_Font::CharsetFontMap) == sizeof(FPDF_CharsetFontMap));

static_assert(FXFONT_FW_NORMAL == pdfium::kFontWeightNormal);
static_assert(FXFONT_FW_BOLD == pdfium::kFontWeightBold);

class CFX_ExternalFontInfo final : public SystemFontInfoIface {
 public:
  explicit CFX_ExternalFontInfo(FPDF_SYSFONTINFO* pInfo) : info_(pInfo) {}
  ~CFX_ExternalFontInfo() override {
    if (info_->Release) {
      info_->Release(info_);
    }
  }

  void EnumFontList(CFX_FontMapper* pMapper) override {
    if (info_->EnumFonts) {
      info_->EnumFonts(info_, pMapper);
    }
  }

  void* MapFont(int weight,
                bool bItalic,
                FX_Charset charset,
                int pitch_family,
                const ByteString& face) override {
    if (!info_->MapFont) {
      return nullptr;
    }

    int iExact;
    return info_->MapFont(info_, weight, bItalic, static_cast<int>(charset),
                          pitch_family, face.c_str(), &iExact);
  }

  void* GetFont(const ByteString& family) override {
    if (!info_->GetFont) {
      return nullptr;
    }
    return info_->GetFont(info_, family.c_str());
  }

  size_t GetFontData(void* hFont,
                     uint32_t table,
                     pdfium::span<uint8_t> buffer) override {
    if (!info_->GetFontData) {
      return 0;
    }
    return info_->GetFontData(info_, hFont, table, buffer.data(),
                              fxcrt::CollectionSize<unsigned long>(buffer));
  }

  bool GetFaceName(void* hFont, ByteString* name) override {
    if (!info_->GetFaceName) {
      return false;
    }
    unsigned long size = info_->GetFaceName(info_, hFont, nullptr, 0);
    if (size == 0) {
      return false;
    }
    ByteString result;
    auto result_span = result.GetBuffer(size);
    size = info_->GetFaceName(info_, hFont, result_span.data(), size);
    result.ReleaseBuffer(size);
    *name = std::move(result);
    return true;
  }

  bool GetFontCharset(void* hFont, FX_Charset* charset) override {
    if (!info_->GetFontCharset) {
      return false;
    }

    *charset = FX_GetCharsetFromInt(info_->GetFontCharset(info_, hFont));
    return true;
  }

  void DeleteFont(void* hFont) override {
    if (info_->DeleteFont) {
      info_->DeleteFont(info_, hFont);
    }
  }

 private:
  UnownedPtr<FPDF_SYSFONTINFO> const info_;
};

FPDF_EXPORT void FPDF_CALLCONV FPDF_AddInstalledFont(void* mapper,
                                                     const char* face,
                                                     int charset) {
  CFX_FontMapper* pMapper = static_cast<CFX_FontMapper*>(mapper);
  pMapper->AddInstalledFont(face, FX_GetCharsetFromInt(charset));
}

FPDF_EXPORT void FPDF_CALLCONV
FPDF_SetSystemFontInfo(FPDF_SYSFONTINFO* font_infoExt) {
  auto* mapper = CFX_GEModule::Get()->GetFontMgr()->GetBuiltinMapper();
  if (!font_infoExt) {
    std::unique_ptr<SystemFontInfoIface> info = mapper->TakeSystemFontInfo();
    // Delete `info` when it goes out of scope here.
    return;
  }

  if (font_infoExt->version != 1 && font_infoExt->version != 2) {
    return;
  }

  mapper->SetSystemFontInfo(
      std::make_unique<CFX_ExternalFontInfo>(font_infoExt));

  // Version 1: Enable font enumeration via `EnumFonts()`.
  // Version 2: Skip font enumeration, use per-request matching via `MapFont()`.
  mapper->SetSkipFontEnumeration(font_infoExt->version == 2);

#ifdef PDF_ENABLE_XFA
  CFGAS_GEModule::Get()->GetFontMgr()->EnumFonts();
#endif
}

FPDF_EXPORT const FPDF_CharsetFontMap* FPDF_CALLCONV FPDF_GetDefaultTTFMap() {
  return reinterpret_cast<const FPDF_CharsetFontMap*>(
      CFX_Font::GetDefaultTTFMapSpan().data());
}

FPDF_EXPORT size_t FPDF_CALLCONV FPDF_GetDefaultTTFMapCount() {
  return CFX_Font::GetDefaultTTFMapSpan().size();
}

FPDF_EXPORT const FPDF_CharsetFontMap* FPDF_CALLCONV
FPDF_GetDefaultTTFMapEntry(size_t index) {
  pdfium::span<const CFX_Font::CharsetFontMap> entries =
      CFX_Font::GetDefaultTTFMapSpan();
  return index < entries.size()
             ? reinterpret_cast<const FPDF_CharsetFontMap*>(&entries[index])
             : nullptr;
}

struct FPDF_SYSFONTINFO_DEFAULT final : public FPDF_SYSFONTINFO {
  UnownedPtr<SystemFontInfoIface> font_info_;
};

static void DefaultRelease(struct _FPDF_SYSFONTINFO* pThis) {
  auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
  pDefault->font_info_.ClearAndDelete();
}

static void DefaultEnumFonts(struct _FPDF_SYSFONTINFO* pThis, void* pMapper) {
  auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
  pDefault->font_info_->EnumFontList(static_cast<CFX_FontMapper*>(pMapper));
}

static void* DefaultMapFont(struct _FPDF_SYSFONTINFO* pThis,
                            int weight,
                            FPDF_BOOL use_italic,
                            int charset,
                            int pitch_family,
                            const char* family,
                            FPDF_BOOL* /*exact*/) {
  auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
  return pDefault->font_info_->MapFont(weight, !!use_italic,
                                       FX_GetCharsetFromInt(charset),
                                       pitch_family, family);
}

void* DefaultGetFont(struct _FPDF_SYSFONTINFO* pThis, const char* family) {
  auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
  return pDefault->font_info_->GetFont(family);
}

// TODO(tsepez): should be UNSAFE_BUFFER_USAGE.
static unsigned long DefaultGetFontData(struct _FPDF_SYSFONTINFO* pThis,
                                        void* hFont,
                                        unsigned int table,
                                        unsigned char* buffer,
                                        unsigned long buf_size) {
  auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
  // SAFETY: required from caller.
  return pdfium::checked_cast<unsigned long>(pDefault->font_info_->GetFontData(
      hFont, table, UNSAFE_BUFFERS(pdfium::span(buffer, buf_size))));
}

// TODO(tsepez): should be UNSAFE_BUFFER_USAGE.
static unsigned long DefaultGetFaceName(struct _FPDF_SYSFONTINFO* pThis,
                                        void* hFont,
                                        char* buffer,
                                        unsigned long buf_size) {
  ByteString name;
  auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
  if (!pDefault->font_info_->GetFaceName(hFont, &name)) {
    return 0;
  }

  const unsigned long copy_length =
      pdfium::checked_cast<unsigned long>(name.GetLength() + 1);
  if (copy_length <= buf_size) {
    UNSAFE_TODO(strncpy(buffer, name.c_str(),
                        copy_length * sizeof(ByteString::CharType)));
  }
  return copy_length;
}

static int DefaultGetFontCharset(struct _FPDF_SYSFONTINFO* pThis, void* hFont) {
  FX_Charset charset;
  auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
  if (!pDefault->font_info_->GetFontCharset(hFont, &charset)) {
    return 0;
  }
  return static_cast<int>(charset);
}

static void DefaultDeleteFont(struct _FPDF_SYSFONTINFO* pThis, void* hFont) {
  auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
  pDefault->font_info_->DeleteFont(hFont);
}

FPDF_EXPORT FPDF_SYSFONTINFO* FPDF_CALLCONV FPDF_GetDefaultSystemFontInfo() {
  std::unique_ptr<SystemFontInfoIface> font_info =
      CFX_GEModule::Get()->GetPlatform()->CreateDefaultSystemFontInfo();
  if (!font_info) {
    return nullptr;
  }

  FPDF_SYSFONTINFO_DEFAULT* font_infoExt =
      FX_Alloc(FPDF_SYSFONTINFO_DEFAULT, 1);
  font_infoExt->DeleteFont = DefaultDeleteFont;
  font_infoExt->EnumFonts = DefaultEnumFonts;
  font_infoExt->GetFaceName = DefaultGetFaceName;
  font_infoExt->GetFont = DefaultGetFont;
  font_infoExt->GetFontCharset = DefaultGetFontCharset;
  font_infoExt->GetFontData = DefaultGetFontData;
  font_infoExt->MapFont = DefaultMapFont;
  font_infoExt->Release = DefaultRelease;
  font_infoExt->version = 1;
  font_infoExt->font_info_ = font_info.release();
  return font_infoExt;
}

FPDF_EXPORT void FPDF_CALLCONV
FPDF_FreeDefaultSystemFontInfo(FPDF_SYSFONTINFO* font_info) {
  FX_Free(static_cast<FPDF_SYSFONTINFO_DEFAULT*>(font_info));
}
