// Copyright 2016 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 "core/fxge/cfx_fontmgr.h"

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

#include "core/fxcrt/check_op.h"
#include "core/fxcrt/fixed_size_data_vector.h"
#include "core/fxge/cfx_fontmapper.h"
#include "core/fxge/cfx_substfont.h"
#include "core/fxge/fontdata/chromefontdata/chromefontdata.h"
#include "core/fxge/fx_font.h"
#include "core/fxge/systemfontinfo_iface.h"

namespace {

struct BuiltinFont {
  const uint8_t* m_pFontData;  // Raw, POD struct.
  uint32_t m_dwSize;
};

constexpr BuiltinFont kFoxitFonts[] = {
    {kFoxitFixedFontData, 17597},
    {kFoxitFixedBoldFontData, 18055},
    {kFoxitFixedBoldItalicFontData, 19151},
    {kFoxitFixedItalicFontData, 18746},
    {kFoxitSansFontData, 15025},
    {kFoxitSansBoldFontData, 16344},
    {kFoxitSansBoldItalicFontData, 16418},
    {kFoxitSansItalicFontData, 16339},
    {kFoxitSerifFontData, 19469},
    {kFoxitSerifBoldFontData, 19395},
    {kFoxitSerifBoldItalicFontData, 20733},
    {kFoxitSerifItalicFontData, 21227},
    {kFoxitSymbolFontData, 16729},
    {kFoxitDingbatsFontData, 29513},
};
static_assert(std::size(kFoxitFonts) == CFX_FontMapper::kNumStandardFonts,
              "Wrong font count");

constexpr BuiltinFont kGenericSansFont = {kFoxitSansMMFontData, 66919};
constexpr BuiltinFont kGenericSerifFont = {kFoxitSerifMMFontData, 113417};

FXFT_LibraryRec* FTLibraryInitHelper() {
  FXFT_LibraryRec* pLibrary = nullptr;
  FT_Init_FreeType(&pLibrary);
  return pLibrary;
}

}  // namespace

CFX_FontMgr::FontDesc::FontDesc(FixedSizeDataVector<uint8_t> data)
    : m_pFontData(std::move(data)) {}

CFX_FontMgr::FontDesc::~FontDesc() = default;

void CFX_FontMgr::FontDesc::SetFace(size_t index, CFX_Face* face) {
  CHECK_LT(index, std::size(m_TTCFaces));
  m_TTCFaces[index].Reset(face);
}

CFX_Face* CFX_FontMgr::FontDesc::GetFace(size_t index) const {
  CHECK_LT(index, std::size(m_TTCFaces));
  return m_TTCFaces[index].Get();
}

CFX_FontMgr::CFX_FontMgr()
    : m_FTLibrary(FTLibraryInitHelper()),
      m_pBuiltinMapper(std::make_unique<CFX_FontMapper>(this)),
      m_FTLibrarySupportsHinting(SetLcdFilterMode() ||
                                 FreeTypeVersionSupportsHinting()) {}

CFX_FontMgr::~CFX_FontMgr() = default;

RetainPtr<CFX_FontMgr::FontDesc> CFX_FontMgr::GetCachedFontDesc(
    const ByteString& face_name,
    int weight,
    bool bItalic) {
  auto it = m_FaceMap.find({face_name, weight, bItalic});
  return it != m_FaceMap.end() ? pdfium::WrapRetain(it->second.Get()) : nullptr;
}

RetainPtr<CFX_FontMgr::FontDesc> CFX_FontMgr::AddCachedFontDesc(
    const ByteString& face_name,
    int weight,
    bool bItalic,
    FixedSizeDataVector<uint8_t> data) {
  auto pFontDesc = pdfium::MakeRetain<FontDesc>(std::move(data));
  m_FaceMap[{face_name, weight, bItalic}].Reset(pFontDesc.Get());
  return pFontDesc;
}

RetainPtr<CFX_FontMgr::FontDesc> CFX_FontMgr::GetCachedTTCFontDesc(
    size_t ttc_size,
    uint32_t checksum) {
  auto it = m_TTCFaceMap.find({ttc_size, checksum});
  return it != m_TTCFaceMap.end() ? pdfium::WrapRetain(it->second.Get())
                                  : nullptr;
}

RetainPtr<CFX_FontMgr::FontDesc> CFX_FontMgr::AddCachedTTCFontDesc(
    size_t ttc_size,
    uint32_t checksum,
    FixedSizeDataVector<uint8_t> data) {
  auto pNewDesc = pdfium::MakeRetain<FontDesc>(std::move(data));
  m_TTCFaceMap[{ttc_size, checksum}].Reset(pNewDesc.Get());
  return pNewDesc;
}

RetainPtr<CFX_Face> CFX_FontMgr::NewFixedFace(RetainPtr<FontDesc> pDesc,
                                              pdfium::span<const uint8_t> span,
                                              size_t face_index) {
  RetainPtr<CFX_Face> face =
      CFX_Face::New(m_FTLibrary.get(), std::move(pDesc), span,
                    static_cast<FT_Long>(face_index));
  if (!face || !face->SetPixelSize(64, 64)) {
    return nullptr;
  }

  return face;
}

// static
pdfium::span<const uint8_t> CFX_FontMgr::GetStandardFont(size_t index) {
  CHECK_LT(index, std::size(kFoxitFonts));
  return pdfium::make_span(kFoxitFonts[index].m_pFontData,
                           kFoxitFonts[index].m_dwSize);
}

// static
pdfium::span<const uint8_t> CFX_FontMgr::GetGenericSansFont() {
  return pdfium::make_span(kGenericSansFont.m_pFontData,
                           kGenericSansFont.m_dwSize);
}

// static
pdfium::span<const uint8_t> CFX_FontMgr::GetGenericSerifFont() {
  return pdfium::make_span(kGenericSerifFont.m_pFontData,
                           kGenericSerifFont.m_dwSize);
}

bool CFX_FontMgr::FreeTypeVersionSupportsHinting() const {
  FT_Int major;
  FT_Int minor;
  FT_Int patch;
  FT_Library_Version(m_FTLibrary.get(), &major, &minor, &patch);
  // Freetype versions >= 2.8.1 support hinting even if subpixel rendering is
  // disabled. https://sourceforge.net/projects/freetype/files/freetype2/2.8.1/
  return major > 2 || (major == 2 && minor > 8) ||
         (major == 2 && minor == 8 && patch >= 1);
}

bool CFX_FontMgr::SetLcdFilterMode() const {
  return FT_Library_SetLcdFilter(m_FTLibrary.get(), FT_LCD_FILTER_DEFAULT) !=
         FT_Err_Unimplemented_Feature;
}
