// Copyright 2014 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/fxcrt/fx_system.h"

#define FPF_SKIAMATCHWEIGHT_NAME1 62
#define FPF_SKIAMATCHWEIGHT_NAME2 60
#define FPF_SKIAMATCHWEIGHT_1 16
#define FPF_SKIAMATCHWEIGHT_2 8

#include <algorithm>

#include "core/fxcrt/fx_ext.h"
#include "core/fxcrt/fx_memory.h"
#include "core/fxge/android/fpf_skiafont.h"
#include "core/fxge/android/fpf_skiafontmgr.h"
#include "core/fxge/fx_freetype.h"

#ifdef __cplusplus
extern "C" {
#endif
static unsigned long FPF_SkiaStream_Read(FXFT_Stream stream,
                                         unsigned long offset,
                                         unsigned char* buffer,
                                         unsigned long count) {
  IFX_FileRead* pFileRead = (IFX_FileRead*)stream->descriptor.pointer;
  if (!pFileRead)
    return 0;
  if (count > 0) {
    if (!pFileRead->ReadBlock(buffer, (FX_FILESIZE)offset, (size_t)count))
      return 0;
  }
  return count;
}

static void FPF_SkiaStream_Close(FXFT_Stream stream) {}
#ifdef __cplusplus
};
#endif

namespace {

struct FPF_SKIAFONTMAP {
  uint32_t dwFamily;
  uint32_t dwSubSt;
};

const FPF_SKIAFONTMAP g_SkiaFontmap[] = {
    {0x58c5083, 0xc8d2e345},  {0x5dfade2, 0xe1633081},
    {0x684317d, 0xe1633081},  {0x14ee2d13, 0xc8d2e345},
    {0x3918fe2d, 0xbbeeec72}, {0x3b98b31c, 0xe1633081},
    {0x3d49f40e, 0xe1633081}, {0x432c41c5, 0xe1633081},
    {0x491b6ad0, 0xe1633081}, {0x5612cab1, 0x59b9f8f1},
    {0x779ce19d, 0xc8d2e345}, {0x7cc9510b, 0x59b9f8f1},
    {0x83746053, 0xbbeeec72}, {0xaaa60c03, 0xbbeeec72},
    {0xbf85ff26, 0xe1633081}, {0xc04fe601, 0xbbeeec72},
    {0xca3812d5, 0x59b9f8f1}, {0xca383e15, 0x59b9f8f1},
    {0xcad5eaf6, 0x59b9f8f1}, {0xcb7a04c8, 0xc8d2e345},
    {0xfb4ce0de, 0xe1633081},
};

const FPF_SKIAFONTMAP g_SkiaSansFontMap[] = {
    {0x58c5083, 0xd5b8d10f},  {0x14ee2d13, 0xd5b8d10f},
    {0x779ce19d, 0xd5b8d10f}, {0xcb7a04c8, 0xd5b8d10f},
    {0xfb4ce0de, 0xd5b8d10f},
};

uint32_t FPF_SkiaGetSubstFont(uint32_t dwHash,
                              const FPF_SKIAFONTMAP* skFontMap,
                              size_t length) {
  const FPF_SKIAFONTMAP* pEnd = skFontMap + length;
  const FPF_SKIAFONTMAP* pFontMap = std::lower_bound(
      skFontMap, pEnd, dwHash, [](const FPF_SKIAFONTMAP& item, uint32_t hash) {
        return item.dwFamily < hash;
      });
  if (pFontMap < pEnd && pFontMap->dwFamily == dwHash)
    return pFontMap->dwSubSt;
  return 0;
}

uint32_t FPF_GetHashCode_StringA(const FX_CHAR* pStr, int32_t iLength) {
  if (!pStr)
    return 0;
  if (iLength < 0)
    iLength = FXSYS_strlen(pStr);
  const FX_CHAR* pStrEnd = pStr + iLength;
  uint32_t uHashCode = 0;
  while (pStr < pStrEnd)
    uHashCode = 31 * uHashCode + FXSYS_tolower(*pStr++);
  return uHashCode;
}

enum FPF_SKIACHARSET {
  FPF_SKIACHARSET_Ansi = 1 << 0,
  FPF_SKIACHARSET_Default = 1 << 1,
  FPF_SKIACHARSET_Symbol = 1 << 2,
  FPF_SKIACHARSET_ShiftJIS = 1 << 3,
  FPF_SKIACHARSET_Korean = 1 << 4,
  FPF_SKIACHARSET_Johab = 1 << 5,
  FPF_SKIACHARSET_GB2312 = 1 << 6,
  FPF_SKIACHARSET_BIG5 = 1 << 7,
  FPF_SKIACHARSET_Greek = 1 << 8,
  FPF_SKIACHARSET_Turkish = 1 << 9,
  FPF_SKIACHARSET_Vietnamese = 1 << 10,
  FPF_SKIACHARSET_Hebrew = 1 << 11,
  FPF_SKIACHARSET_Arabic = 1 << 12,
  FPF_SKIACHARSET_Baltic = 1 << 13,
  FPF_SKIACHARSET_Cyrillic = 1 << 14,
  FPF_SKIACHARSET_Thai = 1 << 15,
  FPF_SKIACHARSET_EeasternEuropean = 1 << 16,
  FPF_SKIACHARSET_PC = 1 << 17,
  FPF_SKIACHARSET_OEM = 1 << 18,
};

uint32_t FPF_SkiaGetCharset(uint8_t uCharset) {
  switch (uCharset) {
    case FXFONT_ANSI_CHARSET:
      return FPF_SKIACHARSET_Ansi;
    case FXFONT_DEFAULT_CHARSET:
      return FPF_SKIACHARSET_Default;
    case FXFONT_SYMBOL_CHARSET:
      return FPF_SKIACHARSET_Symbol;
    case FXFONT_SHIFTJIS_CHARSET:
      return FPF_SKIACHARSET_ShiftJIS;
    case FXFONT_HANGUL_CHARSET:
      return FPF_SKIACHARSET_Korean;
    case FXFONT_GB2312_CHARSET:
      return FPF_SKIACHARSET_GB2312;
    case FXFONT_CHINESEBIG5_CHARSET:
      return FPF_SKIACHARSET_BIG5;
    case FXFONT_GREEK_CHARSET:
      return FPF_SKIACHARSET_Greek;
    case FXFONT_TURKISH_CHARSET:
      return FPF_SKIACHARSET_Turkish;
    case FXFONT_HEBREW_CHARSET:
      return FPF_SKIACHARSET_Hebrew;
    case FXFONT_ARABIC_CHARSET:
      return FPF_SKIACHARSET_Arabic;
    case FXFONT_BALTIC_CHARSET:
      return FPF_SKIACHARSET_Baltic;
    case FXFONT_RUSSIAN_CHARSET:
      return FPF_SKIACHARSET_Cyrillic;
    case FXFONT_THAI_CHARSET:
      return FPF_SKIACHARSET_Thai;
    case FXFONT_EASTEUROPE_CHARSET:
      return FPF_SKIACHARSET_EeasternEuropean;
  }
  return FPF_SKIACHARSET_Default;
}

uint32_t FPF_SKIANormalizeFontName(const CFX_ByteStringC& bsfamily) {
  uint32_t dwHash = 0;
  int32_t iLength = bsfamily.GetLength();
  const FX_CHAR* pBuffer = bsfamily.c_str();
  for (int32_t i = 0; i < iLength; i++) {
    FX_CHAR ch = pBuffer[i];
    if (ch == ' ' || ch == '-' || ch == ',')
      continue;
    dwHash = 31 * dwHash + FXSYS_tolower(ch);
  }
  return dwHash;
}

uint32_t FPF_SKIAGetFamilyHash(const CFX_ByteStringC& bsFamily,
                               uint32_t dwStyle,
                               uint8_t uCharset) {
  CFX_ByteString bsFont(bsFamily);
  if (dwStyle & FXFONT_BOLD)
    bsFont += "Bold";
  if (dwStyle & FXFONT_ITALIC)
    bsFont += "Italic";
  if (dwStyle & FXFONT_SERIF)
    bsFont += "Serif";
  bsFont += uCharset;
  return FPF_GetHashCode_StringA(bsFont.c_str(), bsFont.GetLength());
}

bool FPF_SkiaIsCJK(uint8_t uCharset) {
  return (uCharset == FXFONT_GB2312_CHARSET) ||
         (uCharset == FXFONT_CHINESEBIG5_CHARSET) ||
         (uCharset == FXFONT_HANGUL_CHARSET) ||
         (uCharset == FXFONT_SHIFTJIS_CHARSET);
}

bool FPF_SkiaMaybeSymbol(const CFX_ByteStringC& bsFacename) {
  CFX_ByteString bsName(bsFacename);
  bsName.MakeLower();
  return bsName.Find("symbol") > -1;
}

bool FPF_SkiaMaybeArabic(const CFX_ByteStringC& bsFacename) {
  CFX_ByteString bsName(bsFacename);
  bsName.MakeLower();
  return bsName.Find("arabic") > -1;
}

const uint32_t g_FPFSkiaFontCharsets[] = {
    FPF_SKIACHARSET_Ansi,
    FPF_SKIACHARSET_EeasternEuropean,
    FPF_SKIACHARSET_Cyrillic,
    FPF_SKIACHARSET_Greek,
    FPF_SKIACHARSET_Turkish,
    FPF_SKIACHARSET_Hebrew,
    FPF_SKIACHARSET_Arabic,
    FPF_SKIACHARSET_Baltic,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    FPF_SKIACHARSET_Thai,
    FPF_SKIACHARSET_ShiftJIS,
    FPF_SKIACHARSET_GB2312,
    FPF_SKIACHARSET_Korean,
    FPF_SKIACHARSET_BIG5,
    FPF_SKIACHARSET_Johab,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    FPF_SKIACHARSET_OEM,
    FPF_SKIACHARSET_Symbol,
};

uint32_t FPF_SkiaGetFaceCharset(TT_OS2* pOS2) {
  uint32_t dwCharset = 0;
  if (pOS2) {
    for (int32_t i = 0; i < 32; i++) {
      if (pOS2->ulCodePageRange1 & (1 << i))
        dwCharset |= g_FPFSkiaFontCharsets[i];
    }
  }
  dwCharset |= FPF_SKIACHARSET_Default;
  return dwCharset;
}

}  // namespace

CFPF_SkiaFontMgr::CFPF_SkiaFontMgr() : m_bLoaded(false), m_FTLibrary(nullptr) {}

CFPF_SkiaFontMgr::~CFPF_SkiaFontMgr() {
  for (const auto& pair : m_FamilyFonts) {
    if (pair.second)
      pair.second->Release();
  }
  m_FamilyFonts.clear();
  for (auto it = m_FontFaces.begin(); it != m_FontFaces.end(); ++it)
    delete *it;
  m_FontFaces.clear();
  if (m_FTLibrary)
    FXFT_Done_FreeType(m_FTLibrary);
}

bool CFPF_SkiaFontMgr::InitFTLibrary() {
  if (!m_FTLibrary)
    FXFT_Init_FreeType(&m_FTLibrary);
  return !!m_FTLibrary;
}

void CFPF_SkiaFontMgr::LoadSystemFonts() {
  if (m_bLoaded)
    return;
  ScanPath("/system/fonts");
  m_bLoaded = true;
}

CFPF_SkiaFont* CFPF_SkiaFontMgr::CreateFont(const CFX_ByteStringC& bsFamilyname,
                                            uint8_t uCharset,
                                            uint32_t dwStyle,
                                            uint32_t dwMatch) {
  uint32_t dwHash = FPF_SKIAGetFamilyHash(bsFamilyname, dwStyle, uCharset);
  auto it = m_FamilyFonts.find(dwHash);
  if (it != m_FamilyFonts.end() && it->second)
    return it->second->Retain();

  uint32_t dwFaceName = FPF_SKIANormalizeFontName(bsFamilyname);
  uint32_t dwSubst = FPF_SkiaGetSubstFont(dwFaceName, g_SkiaFontmap,
                                          FX_ArraySize(g_SkiaFontmap));
  uint32_t dwSubstSans = FPF_SkiaGetSubstFont(dwFaceName, g_SkiaSansFontMap,
                                              FX_ArraySize(g_SkiaSansFontMap));
  bool bMaybeSymbol = FPF_SkiaMaybeSymbol(bsFamilyname);
  if (uCharset != FXFONT_ARABIC_CHARSET && FPF_SkiaMaybeArabic(bsFamilyname)) {
    uCharset = FXFONT_ARABIC_CHARSET;
  } else if (uCharset == FXFONT_ANSI_CHARSET &&
             (dwMatch & FPF_MATCHFONT_REPLACEANSI)) {
    uCharset = FXFONT_DEFAULT_CHARSET;
  }
  int32_t nExpectVal = FPF_SKIAMATCHWEIGHT_NAME1 + FPF_SKIAMATCHWEIGHT_1 * 3 +
                       FPF_SKIAMATCHWEIGHT_2 * 2;
  CFPF_SkiaFontDescriptor* pBestFontDes = nullptr;
  int32_t nMax = -1;
  int32_t nGlyphNum = 0;
  for (auto it = m_FontFaces.rbegin(); it != m_FontFaces.rend(); ++it) {
    CFPF_SkiaPathFont* pFontDes = static_cast<CFPF_SkiaPathFont*>(*it);
    if (!(pFontDes->m_dwCharsets & FPF_SkiaGetCharset(uCharset)))
      continue;
    int32_t nFind = 0;
    uint32_t dwSysFontName = FPF_SKIANormalizeFontName(pFontDes->m_pFamily);
    if (dwFaceName == dwSysFontName)
      nFind += FPF_SKIAMATCHWEIGHT_NAME1;
    bool bMatchedName = (nFind == FPF_SKIAMATCHWEIGHT_NAME1);
    if ((dwStyle & FXFONT_BOLD) == (pFontDes->m_dwStyle & FXFONT_BOLD))
      nFind += FPF_SKIAMATCHWEIGHT_1;
    if ((dwStyle & FXFONT_ITALIC) == (pFontDes->m_dwStyle & FXFONT_ITALIC))
      nFind += FPF_SKIAMATCHWEIGHT_1;
    if ((dwStyle & FXFONT_FIXED_PITCH) ==
        (pFontDes->m_dwStyle & FXFONT_FIXED_PITCH)) {
      nFind += FPF_SKIAMATCHWEIGHT_2;
    }
    if ((dwStyle & FXFONT_SERIF) == (pFontDes->m_dwStyle & FXFONT_SERIF))
      nFind += FPF_SKIAMATCHWEIGHT_1;
    if ((dwStyle & FXFONT_SCRIPT) == (pFontDes->m_dwStyle & FXFONT_SCRIPT))
      nFind += FPF_SKIAMATCHWEIGHT_2;
    if (dwSubst == dwSysFontName || dwSubstSans == dwSysFontName) {
      nFind += FPF_SKIAMATCHWEIGHT_NAME2;
      bMatchedName = true;
    }
    if (uCharset == FXFONT_DEFAULT_CHARSET || bMaybeSymbol) {
      if (nFind > nMax && bMatchedName) {
        nMax = nFind;
        pBestFontDes = *it;
      }
    } else if (FPF_SkiaIsCJK(uCharset)) {
      if (bMatchedName || pFontDes->m_iGlyphNum > nGlyphNum) {
        pBestFontDes = *it;
        nGlyphNum = pFontDes->m_iGlyphNum;
      }
    } else if (nFind > nMax) {
      nMax = nFind;
      pBestFontDes = *it;
    }
    if (nExpectVal <= nFind) {
      pBestFontDes = *it;
      break;
    }
  }
  if (pBestFontDes) {
    CFPF_SkiaFont* pFont = new CFPF_SkiaFont;
    if (pFont->InitFont(this, pBestFontDes, bsFamilyname, dwStyle, uCharset)) {
      m_FamilyFonts[dwHash] = pFont;
      return pFont->Retain();
    }
    pFont->Release();
  }
  return nullptr;
}

FXFT_Face CFPF_SkiaFontMgr::GetFontFace(IFX_FileRead* pFileRead,
                                        int32_t iFaceIndex) {
  if (!pFileRead)
    return nullptr;
  if (pFileRead->GetSize() == 0)
    return nullptr;
  if (iFaceIndex < 0)
    return nullptr;
  FXFT_StreamRec streamRec;
  FXSYS_memset(&streamRec, 0, sizeof(FXFT_StreamRec));
  streamRec.size = pFileRead->GetSize();
  streamRec.descriptor.pointer = pFileRead;
  streamRec.read = FPF_SkiaStream_Read;
  streamRec.close = FPF_SkiaStream_Close;
  FXFT_Open_Args args;
  args.flags = FT_OPEN_STREAM;
  args.stream = &streamRec;
  FXFT_Face face;
  if (FXFT_Open_Face(m_FTLibrary, &args, iFaceIndex, &face))
    return nullptr;
  FXFT_Set_Pixel_Sizes(face, 0, 64);
  return face;
}

FXFT_Face CFPF_SkiaFontMgr::GetFontFace(const CFX_ByteStringC& bsFile,
                                        int32_t iFaceIndex) {
  if (bsFile.IsEmpty())
    return nullptr;
  if (iFaceIndex < 0)
    return nullptr;
  FXFT_Open_Args args;
  args.flags = FT_OPEN_PATHNAME;
  args.pathname = const_cast<FT_String*>(bsFile.c_str());
  FXFT_Face face;
  if (FXFT_Open_Face(m_FTLibrary, &args, iFaceIndex, &face))
    return nullptr;
  FXFT_Set_Pixel_Sizes(face, 0, 64);
  return face;
}

FXFT_Face CFPF_SkiaFontMgr::GetFontFace(const uint8_t* pBuffer,
                                        size_t szBuffer,
                                        int32_t iFaceIndex) {
  if (!pBuffer || szBuffer < 1)
    return nullptr;
  if (iFaceIndex < 0)
    return nullptr;
  FXFT_Open_Args args;
  args.flags = FT_OPEN_MEMORY;
  args.memory_base = pBuffer;
  args.memory_size = szBuffer;
  FXFT_Face face;
  if (FXFT_Open_Face(m_FTLibrary, &args, iFaceIndex, &face))
    return nullptr;
  FXFT_Set_Pixel_Sizes(face, 0, 64);
  return face;
}

void CFPF_SkiaFontMgr::ScanPath(const CFX_ByteString& path) {
  DIR* handle = FX_OpenFolder(path.c_str());
  if (!handle)
    return;
  CFX_ByteString filename;
  bool bFolder = false;
  while (FX_GetNextFile(handle, &filename, &bFolder)) {
    if (bFolder) {
      if (filename == "." || filename == "..")
        continue;
    } else {
      CFX_ByteString ext = filename.Right(4);
      ext.MakeLower();
      if (ext != ".ttf" && ext != ".ttc" && ext != ".otf")
        continue;
    }
    CFX_ByteString fullpath(path);
    fullpath += "/";
    fullpath += filename;
    if (bFolder)
      ScanPath(fullpath);
    else
      ScanFile(fullpath);
  }
  FX_CloseFolder(handle);
}

void CFPF_SkiaFontMgr::ScanFile(const CFX_ByteString& file) {
  FXFT_Face face = GetFontFace(file.AsStringC());
  if (!face)
    return;
  CFPF_SkiaPathFont* pFontDesc = new CFPF_SkiaPathFont;
  pFontDesc->SetPath(file.c_str());
  ReportFace(face, pFontDesc);
  m_FontFaces.push_back(pFontDesc);
  FXFT_Done_Face(face);
}

void CFPF_SkiaFontMgr::ReportFace(FXFT_Face face,
                                  CFPF_SkiaFontDescriptor* pFontDesc) {
  if (!face || !pFontDesc)
    return;
  pFontDesc->SetFamily(FXFT_Get_Face_Family_Name(face));
  if (FXFT_Is_Face_Bold(face))
    pFontDesc->m_dwStyle |= FXFONT_BOLD;
  if (FXFT_Is_Face_Italic(face))
    pFontDesc->m_dwStyle |= FXFONT_ITALIC;
  if (FT_IS_FIXED_WIDTH(face))
    pFontDesc->m_dwStyle |= FXFONT_FIXED_PITCH;
  TT_OS2* pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(face, ft_sfnt_os2);
  if (pOS2) {
    if (pOS2->ulCodePageRange1 & (1 << 31))
      pFontDesc->m_dwStyle |= FXFONT_SYMBOLIC;
    if (pOS2->panose[0] == 2) {
      uint8_t uSerif = pOS2->panose[1];
      if ((uSerif > 1 && uSerif < 10) || uSerif > 13)
        pFontDesc->m_dwStyle |= FXFONT_SERIF;
    }
  }
  if (pOS2 && (pOS2->ulCodePageRange1 & (1 << 31)))
    pFontDesc->m_dwStyle |= FXFONT_SYMBOLIC;
  pFontDesc->m_dwCharsets = FPF_SkiaGetFaceCharset(pOS2);
  pFontDesc->m_iFaceIndex = face->face_index;
  pFontDesc->m_iGlyphNum = face->num_glyphs;
}
