// 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->SingleFace();
}

FXFT_Face CFX_FontMgr::AddCachedFace(const ByteString& face_name,
                                     int weight,
                                     bool bItalic,
                                     uint8_t* pData,
                                     uint32_t size,
                                     int face_index) {
  InitFTLibrary();

  FXFT_Face face = nullptr;
  int ret = FXFT_New_Memory_Face(m_FTLibrary, pData, 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>(pData, face);
  CTTFontDesc* pResult = pFontDesc.get();
  m_FaceMap[KeyNameFromFace(face_name, weight, bItalic)] = std::move(pFontDesc);
  return pResult->SingleFace();
}

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->TTCFace(face_index)) {
    pFontDesc->SetTTCFace(
        face_index, GetFixedFace(pFontDesc->FontData(), ttc_size, face_index));
  }
  pFontDesc->AddRef();
  return pFontDesc->TTCFace(face_index);
}

FXFT_Face CFX_FontMgr::AddCachedTTCFace(int ttc_size,
                                        uint32_t checksum,
                                        uint8_t* pData,
                                        uint32_t size,
                                        int font_offset) {
  int face_index = GetTTCIndex(pData, ttc_size, font_offset);
  FXFT_Face face = GetFixedFace(pData, ttc_size, face_index);
  auto pFontDesc = pdfium::MakeUnique<CTTFontDesc>(pData, 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;
}
