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

#include <memory>
#include <utility>

#include "core/fxge/cfx_fontmapper.h"
#include "core/fxge/cfx_substfont.h"
#include "core/fxge/cttfontdesc.h"
#include "core/fxge/fontdata/chromefontdata/chromefontdata.h"
#include "core/fxge/fx_font.h"
#include "core/fxge/systemfontinfo_iface.h"
#include "third_party/base/ptr_util.h"

namespace {

struct BuiltinFont {
  const uint8_t* m_pFontData;
  uint32_t m_dwSize;
};

const BuiltinFont g_FoxitFonts[14] = {
    {g_FoxitFixedFontData, 17597},
    {g_FoxitFixedBoldFontData, 18055},
    {g_FoxitFixedBoldItalicFontData, 19151},
    {g_FoxitFixedItalicFontData, 18746},
    {g_FoxitSansFontData, 15025},
    {g_FoxitSansBoldFontData, 16344},
    {g_FoxitSansBoldItalicFontData, 16418},
    {g_FoxitSansItalicFontData, 16339},
    {g_FoxitSerifFontData, 19469},
    {g_FoxitSerifBoldFontData, 19395},
    {g_FoxitSerifBoldItalicFontData, 20733},
    {g_FoxitSerifItalicFontData, 21227},
    {g_FoxitSymbolFontData, 16729},
    {g_FoxitDingbatsFontData, 29513},
};

const BuiltinFont g_MMFonts[2] = {
    {g_FoxitSerifMMFontData, 113417},
    {g_FoxitSansMMFontData, 66919},
};

ByteString KeyNameFromFace(const ByteString& face_name,
                           int weight,
                           bool bItalic) {
  ByteString key(face_name);
  key += ',';
  key += ByteString::FormatInteger(weight);
  key += bItalic ? 'I' : 'N';
  return key;
}

ByteString KeyNameFromSize(int ttc_size, uint32_t checksum) {
  return ByteString::Format("%d:%d", ttc_size, checksum);
}

int GetTTCIndex(const uint8_t* pFontData,
                uint32_t ttc_size,
                uint32_t font_offset) {
  const uint8_t* p = pFontData + 8;
  uint32_t nfont = GET_TT_LONG(p);
  uint32_t index;
  for (index = 0; index < nfont; index++) {
    p = pFontData + 12 + index * 4;
    if (GET_TT_LONG(p) == font_offset)
      break;
  }
  return index < nfont ? index : 0;
}

}  // namespace

CFX_FontMgr::CFX_FontMgr()
    : m_FTLibrary(nullptr), m_FTLibrarySupportsHinting(false) {
  m_pBuiltinMapper = pdfium::MakeUnique<CFX_FontMapper>(this);
}

CFX_FontMgr::~CFX_FontMgr() {
  // |m_FaceMap| and |m_pBuiltinMapper| reference |m_FTLibrary|, so they must
  // be destroyed first.
  m_FaceMap.clear();
  m_pBuiltinMapper.reset();
  FXFT_Done_FreeType(m_FTLibrary);
}

void CFX_FontMgr::InitFTLibrary() {
  if (m_FTLibrary)
    return;

  FXFT_Init_FreeType(&m_FTLibrary);
  m_FTLibrarySupportsHinting =
      SetLcdFilterMode() || FreeTypeVersionSupportsHinting();
}

void CFX_FontMgr::SetSystemFontInfo(
    std::unique_ptr<SystemFontInfoIface> pFontInfo) {
  m_pBuiltinMapper->SetSystemFontInfo(std::move(pFontInfo));
}

FXFT_Face CFX_FontMgr::FindSubstFont(const ByteString& face_name,
                                     bool bTrueType,
                                     uint32_t flags,
                                     int weight,
                                     int italic_angle,
                                     int CharsetCP,
                                     CFX_SubstFont* pSubstFont) {
  InitFTLibrary();
  return m_pBuiltinMapper->FindSubstFont(face_name, bTrueType, flags, weight,
                                         italic_angle, CharsetCP, pSubstFont);
}

FXFT_Face CFX_FontMgr::GetCachedFace(const ByteString& face_name,
                                     int weight,
                                     bool bItalic,
                                     uint8_t** pFontData) {
  auto it = m_FaceMap.find(KeyNameFromFace(face_name, weight, bItalic));
  if (it == m_FaceMap.end())
    return nullptr;

  CTTFontDesc* pFontDesc = it->second.get();
  *pFontData = pFontDesc->FontData();
  pFontDesc->AddRef();
  return pFontDesc->GetFace(0);
}

FXFT_Face CFX_FontMgr::AddCachedFace(
    const ByteString& face_name,
    int weight,
    bool bItalic,
    std::unique_ptr<uint8_t, FxFreeDeleter> pData,
    uint32_t size,
    int face_index) {
  InitFTLibrary();

  FXFT_Face face = nullptr;
  int ret =
      FXFT_New_Memory_Face(m_FTLibrary, pData.get(), size, face_index, &face);
  if (ret)
    return nullptr;

  ret = FXFT_Set_Pixel_Sizes(face, 64, 64);
  if (ret)
    return nullptr;

  auto pFontDesc = pdfium::MakeUnique<CTTFontDesc>(std::move(pData));
  pFontDesc->SetFace(0, face);
  CTTFontDesc* pResult = pFontDesc.get();
  m_FaceMap[KeyNameFromFace(face_name, weight, bItalic)] = std::move(pFontDesc);
  return pResult->GetFace(0);
}

FXFT_Face CFX_FontMgr::GetCachedTTCFace(int ttc_size,
                                        uint32_t checksum,
                                        int font_offset,
                                        uint8_t** pFontData) {
  auto it = m_FaceMap.find(KeyNameFromSize(ttc_size, checksum));
  if (it == m_FaceMap.end())
    return nullptr;

  CTTFontDesc* pFontDesc = it->second.get();
  *pFontData = pFontDesc->FontData();
  int face_index = GetTTCIndex(pFontDesc->FontData(), ttc_size, font_offset);
  if (!pFontDesc->GetFace(face_index)) {
    pFontDesc->SetFace(
        face_index, GetFixedFace(pFontDesc->FontData(), ttc_size, face_index));
  }
  pFontDesc->AddRef();
  return pFontDesc->GetFace(face_index);
}

FXFT_Face CFX_FontMgr::AddCachedTTCFace(
    int ttc_size,
    uint32_t checksum,
    std::unique_ptr<uint8_t, FxFreeDeleter> pData,
    uint32_t size,
    int font_offset) {
  int face_index = GetTTCIndex(pData.get(), ttc_size, font_offset);
  FXFT_Face face = GetFixedFace(pData.get(), ttc_size, face_index);
  auto pFontDesc = pdfium::MakeUnique<CTTFontDesc>(std::move(pData));
  pFontDesc->SetFace(face_index, face);
  m_FaceMap[KeyNameFromSize(ttc_size, checksum)] = std::move(pFontDesc);
  return face;
}

FXFT_Face CFX_FontMgr::GetFixedFace(const uint8_t* pData,
                                    uint32_t size,
                                    int face_index) {
  InitFTLibrary();
  FXFT_Face face = nullptr;
  if (FXFT_New_Memory_Face(m_FTLibrary, pData, size, face_index, &face))
    return nullptr;
  return FXFT_Set_Pixel_Sizes(face, 64, 64) ? nullptr : face;
}

FXFT_Face CFX_FontMgr::GetFileFace(const char* filename, int face_index) {
  InitFTLibrary();
  FXFT_Face face = nullptr;
  if (FXFT_New_Face(m_FTLibrary, filename, face_index, &face))
    return nullptr;
  return FXFT_Set_Pixel_Sizes(face, 64, 64) ? nullptr : face;
}

void CFX_FontMgr::ReleaseFace(FXFT_Face face) {
  if (!face)
    return;
  bool bNeedFaceDone = true;
  for (auto it = m_FaceMap.begin(); it != m_FaceMap.end(); ++it) {
    CTTFontDesc::ReleaseStatus nRet = it->second->ReleaseFace(face);
    if (nRet == CTTFontDesc::kNotAppropriate)
      continue;
    bNeedFaceDone = false;
    if (nRet == CTTFontDesc::kReleased)
      m_FaceMap.erase(it);
    break;
  }
  if (bNeedFaceDone && !m_pBuiltinMapper->IsBuiltinFace(face))
    FXFT_Done_Face(face);
}

bool CFX_FontMgr::GetBuiltinFont(size_t index,
                                 const uint8_t** pFontData,
                                 uint32_t* size) {
  if (index < FX_ArraySize(g_FoxitFonts)) {
    *pFontData = g_FoxitFonts[index].m_pFontData;
    *size = g_FoxitFonts[index].m_dwSize;
    return true;
  }
  size_t mm_index = index - FX_ArraySize(g_FoxitFonts);
  if (mm_index < FX_ArraySize(g_MMFonts)) {
    *pFontData = g_MMFonts[mm_index].m_pFontData;
    *size = g_MMFonts[mm_index].m_dwSize;
    return true;
  }
  return false;
}

bool CFX_FontMgr::FreeTypeVersionSupportsHinting() const {
  FT_Int major;
  FT_Int minor;
  FT_Int patch;
  FXFT_Library_Version(m_FTLibrary, &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 FXFT_Library_SetLcdFilter(m_FTLibrary, FT_LCD_FILTER_DEFAULT) !=
         FT_Err_Unimplemented_Feature;
}
