// 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/include/fxge/fx_freetype.h"
#include "core/include/fxge/fx_ge.h"
#include "core/src/fxge/ge/fx_text_int.h"

#define EM_ADJUST(em, a) (em == 0 ? (a) : (a)*1000 / em)

#ifdef PDF_ENABLE_XFA
extern void _FPDFAPI_GetInternalFontData(int id1,
                                         const uint8_t*& data,
                                         FX_DWORD& size);
#endif  // PDF_ENABLE_XFA

namespace {

#ifdef PDF_ENABLE_XFA
const FX_DWORD g_EncodingID[] = {
  FXFM_ENCODING_MS_SYMBOL,
  FXFM_ENCODING_UNICODE,
  FXFM_ENCODING_MS_SJIS,
  FXFM_ENCODING_MS_GB2312,
  FXFM_ENCODING_MS_BIG5,
  FXFM_ENCODING_MS_WANSUNG,
  FXFM_ENCODING_MS_JOHAB,
  FXFM_ENCODING_ADOBE_STANDARD,
  FXFM_ENCODING_ADOBE_EXPERT,
  FXFM_ENCODING_ADOBE_CUSTOM,
  FXFM_ENCODING_ADOBE_LATIN_1,
  FXFM_ENCODING_OLD_LATIN_2,
  FXFM_ENCODING_APPLE_ROMAN,
};

CFX_UnicodeEncodingEx* _FXFM_CreateFontEncoding(CFX_Font* pFont,
                                                FX_DWORD nEncodingID) {
  if (FXFT_Select_Charmap(pFont->GetFace(), nEncodingID))
    return nullptr;
  return new CFX_UnicodeEncodingEx(pFont, nEncodingID);
}
#endif  // PDF_ENABLE_XFA

FXFT_Face FT_LoadFont(const uint8_t* pData, int size) {
  return CFX_GEModule::Get()->GetFontMgr()->GetFixedFace(pData, size, 0);
}

}  // namespace

CFX_Font::CFX_Font() {
  m_pSubstFont = NULL;
  m_Face = NULL;
  m_bEmbedded = FALSE;
  m_bVertical = FALSE;
  m_pFontData = NULL;
  m_pFontDataAllocation = NULL;
  m_dwSize = 0;
  m_pGsubData = NULL;
  m_pPlatformFont = NULL;
  m_pPlatformFontCollection = NULL;
  m_pDwFont = NULL;
  m_hHandle = NULL;
  m_bDwLoaded = FALSE;
#ifdef PDF_ENABLE_XFA
  m_bLogic = FALSE;
  m_pOwnedStream = NULL;
#endif  // PDF_ENABLE_XFA
}

#ifdef PDF_ENABLE_XFA
FX_BOOL CFX_Font::LoadClone(const CFX_Font* pFont) {
  if (pFont == NULL) {
    return FALSE;
  }
  m_bLogic = TRUE;
  if (pFont->m_pSubstFont) {
    m_pSubstFont = new CFX_SubstFont;
    m_pSubstFont->m_Charset = pFont->m_pSubstFont->m_Charset;
    m_pSubstFont->m_ExtHandle = pFont->m_pSubstFont->m_ExtHandle;
    m_pSubstFont->m_SubstFlags = pFont->m_pSubstFont->m_SubstFlags;
    m_pSubstFont->m_Weight = pFont->m_pSubstFont->m_Weight;
    m_pSubstFont->m_Family = pFont->m_pSubstFont->m_Family;
    m_pSubstFont->m_ItalicAngle = pFont->m_pSubstFont->m_ItalicAngle;
  }
  if (pFont->m_OtfFontData.GetSize()) {
    m_OtfFontData.AttachData(pFont->m_OtfFontData.GetBuffer(),
                             pFont->m_OtfFontData.GetSize());
  }
  m_Face = pFont->m_Face;
  m_bEmbedded = pFont->m_bEmbedded;
  m_bVertical = pFont->m_bVertical;
  m_dwSize = pFont->m_dwSize;
  m_pFontData = pFont->m_pFontData;
  m_pGsubData = pFont->m_pGsubData;
  m_pPlatformFont = pFont->m_pPlatformFont;
  m_pPlatformFontCollection = pFont->m_pPlatformFontCollection;
  m_pDwFont = pFont->m_pDwFont;
  m_hHandle = pFont->m_hHandle;
  m_bDwLoaded = pFont->m_bDwLoaded;
  m_pOwnedStream = pFont->m_pOwnedStream;
  return TRUE;
}
#endif  // PDF_ENABLE_XFA

CFX_Font::~CFX_Font() {
  delete m_pSubstFont;
  FX_Free(m_pFontDataAllocation);
#ifdef PDF_ENABLE_XFA
  if (m_bLogic) {
    m_OtfFontData.DetachBuffer();
    return;
  }
#endif  // PDF_ENABLE_XFA
  if (m_Face) {
#ifndef PDF_ENABLE_XFA
    if (FXFT_Get_Face_External_Stream(m_Face)) {
      FXFT_Clear_Face_External_Stream(m_Face);
    }
#endif  // PDF_ENABLE_XFA
    if (m_bEmbedded) {
      DeleteFace();
    } else {
      CFX_GEModule::Get()->GetFontMgr()->ReleaseFace(m_Face);
    }
  }
#ifdef PDF_ENABLE_XFA
  FX_Free(m_pOwnedStream);
#endif  // PDF_ENABLE_XFA
  FX_Free(m_pGsubData);
#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
  ReleasePlatformResource();
#endif
}
void CFX_Font::DeleteFace() {
  FXFT_Done_Face(m_Face);
  m_Face = NULL;
}
void CFX_Font::LoadSubst(const CFX_ByteString& face_name,
                         FX_BOOL bTrueType,
                         FX_DWORD flags,
                         int weight,
                         int italic_angle,
                         int CharsetCP,
                         FX_BOOL bVertical) {
  m_bEmbedded = FALSE;
  m_bVertical = bVertical;
  m_pSubstFont = new CFX_SubstFont;
  m_Face = CFX_GEModule::Get()->GetFontMgr()->FindSubstFont(
      face_name, bTrueType, flags, weight, italic_angle, CharsetCP,
      m_pSubstFont);
#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
  if (m_pSubstFont->m_ExtHandle) {
    m_pPlatformFont = m_pSubstFont->m_ExtHandle;
    m_pSubstFont->m_ExtHandle = NULL;
  }
#endif
  if (m_Face) {
    m_pFontData = FXFT_Get_Face_Stream_Base(m_Face);
    m_dwSize = FXFT_Get_Face_Stream_Size(m_Face);
  }
}
#ifdef PDF_ENABLE_XFA
extern "C" {
unsigned long _FTStreamRead(FXFT_Stream stream,
                            unsigned long offset,
                            unsigned char* buffer,
                            unsigned long count) {
  if (count == 0) {
    return 0;
  }
  IFX_FileRead* pFile = (IFX_FileRead*)stream->descriptor.pointer;
  int res = pFile->ReadBlock(buffer, offset, count);
  if (res) {
    return count;
  }
  return 0;
}
void _FTStreamClose(FXFT_Stream stream) {}
};
FX_BOOL _LoadFile(FXFT_Library library,
                  FXFT_Face* Face,
                  IFX_FileRead* pFile,
                  FXFT_Stream* stream,
                  int32_t faceIndex = 0) {
  FXFT_Stream stream1 = (FXFT_Stream)FX_Alloc(uint8_t, sizeof(FXFT_StreamRec));
  stream1->base = NULL;
  stream1->size = (unsigned long)pFile->GetSize();
  stream1->pos = 0;
  stream1->descriptor.pointer = pFile;
  stream1->close = _FTStreamClose;
  stream1->read = _FTStreamRead;
  FXFT_Open_Args args;
  args.flags = FT_OPEN_STREAM;
  args.stream = stream1;
  if (FXFT_Open_Face(library, &args, faceIndex, Face)) {
    FX_Free(stream1);
    return FALSE;
  }
  if (stream) {
    *stream = stream1;
  }
  return TRUE;
}

FX_BOOL CFX_Font::LoadFile(IFX_FileRead* pFile,
                           int nFaceIndex,
                           int* pFaceCount) {
  m_bEmbedded = FALSE;

  CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
  pFontMgr->InitFTLibrary();
  FXFT_Library library = pFontMgr->GetFTLibrary();

  FXFT_Stream stream = nullptr;
  if (!_LoadFile(library, &m_Face, pFile, &stream, nFaceIndex))
    return FALSE;

  if (pFaceCount)
    *pFaceCount = (int)m_Face->num_faces;
  m_pOwnedStream = stream;
  FXFT_Set_Pixel_Sizes(m_Face, 0, 64);
  return TRUE;
}
#endif  // PDF_ENABLE_XFA

int CFX_Font::GetGlyphWidth(FX_DWORD glyph_index) {
  if (!m_Face) {
    return 0;
  }
  if (m_pSubstFont && (m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM)) {
    AdjustMMParams(glyph_index, 0, 0);
  }
  int err = FXFT_Load_Glyph(
      m_Face, glyph_index,
      FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
  if (err) {
    return 0;
  }
  int width = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
                        FXFT_Get_Glyph_HoriAdvance(m_Face));
  return width;
}

FX_BOOL CFX_Font::LoadEmbedded(const uint8_t* data, FX_DWORD size) {
  m_pFontDataAllocation = FX_Alloc(uint8_t, size);
  FXSYS_memcpy(m_pFontDataAllocation, data, size);
  m_Face = FT_LoadFont(m_pFontDataAllocation, size);
  m_pFontData = m_pFontDataAllocation;
  m_bEmbedded = TRUE;
  m_dwSize = size;
  return m_Face != NULL;
}

FX_BOOL CFX_Font::IsTTFont() const {
  if (!m_Face)
    return FALSE;
  return FXFT_Is_Face_TT_OT(m_Face) == FXFT_FACE_FLAG_SFNT;
}

int CFX_Font::GetAscent() const {
  if (!m_Face)
    return 0;
  return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
                   FXFT_Get_Face_Ascender(m_Face));
}

int CFX_Font::GetDescent() const {
  if (!m_Face)
    return 0;
  return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
                   FXFT_Get_Face_Descender(m_Face));
}

FX_BOOL CFX_Font::GetGlyphBBox(FX_DWORD glyph_index, FX_RECT& bbox) {
  if (!m_Face)
    return FALSE;

  if (FXFT_Is_Face_Tricky(m_Face)) {
    int error = FXFT_Set_Char_Size(m_Face, 0, 1000 * 64, 72, 72);
    if (error) {
      return FALSE;
    }
    error = FXFT_Load_Glyph(m_Face, glyph_index,
                            FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
    if (error) {
      return FALSE;
    }
    FXFT_BBox cbox;
    FT_Glyph glyph;
    error = FXFT_Get_Glyph(((FXFT_Face)m_Face)->glyph, &glyph);
    if (error) {
      return FALSE;
    }
    FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox);
    int pixel_size_x = ((FXFT_Face)m_Face)->size->metrics.x_ppem,
        pixel_size_y = ((FXFT_Face)m_Face)->size->metrics.y_ppem;
    if (pixel_size_x == 0 || pixel_size_y == 0) {
      bbox.left = cbox.xMin;
      bbox.right = cbox.xMax;
      bbox.top = cbox.yMax;
      bbox.bottom = cbox.yMin;
    } else {
      bbox.left = cbox.xMin * 1000 / pixel_size_x;
      bbox.right = cbox.xMax * 1000 / pixel_size_x;
      bbox.top = cbox.yMax * 1000 / pixel_size_y;
      bbox.bottom = cbox.yMin * 1000 / pixel_size_y;
    }
    if (bbox.top > FXFT_Get_Face_Ascender(m_Face)) {
      bbox.top = FXFT_Get_Face_Ascender(m_Face);
    }
    if (bbox.bottom < FXFT_Get_Face_Descender(m_Face)) {
      bbox.bottom = FXFT_Get_Face_Descender(m_Face);
    }
    FT_Done_Glyph(glyph);
    return FXFT_Set_Pixel_Sizes(m_Face, 0, 64) == 0;
  }
  if (FXFT_Load_Glyph(
          m_Face, glyph_index,
          FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) {
    return FALSE;
  }
  int em = FXFT_Get_Face_UnitsPerEM(m_Face);
  if (em == 0) {
    bbox.left = FXFT_Get_Glyph_HoriBearingX(m_Face);
    bbox.bottom = FXFT_Get_Glyph_HoriBearingY(m_Face);
    bbox.top = bbox.bottom - FXFT_Get_Glyph_Height(m_Face);
    bbox.right = bbox.left + FXFT_Get_Glyph_Width(m_Face);
  } else {
    bbox.left = FXFT_Get_Glyph_HoriBearingX(m_Face) * 1000 / em;
    bbox.top =
        (FXFT_Get_Glyph_HoriBearingY(m_Face) - FXFT_Get_Glyph_Height(m_Face)) *
        1000 / em;
    bbox.right =
        (FXFT_Get_Glyph_HoriBearingX(m_Face) + FXFT_Get_Glyph_Width(m_Face)) *
        1000 / em;
    bbox.bottom = (FXFT_Get_Glyph_HoriBearingY(m_Face)) * 1000 / em;
  }
  return TRUE;
}

FX_BOOL CFX_Font::IsItalic() const {
  if (!m_Face)
    return FALSE;

  FX_BOOL ret = FXFT_Is_Face_Italic(m_Face) == FXFT_STYLE_FLAG_ITALIC;
  if (!ret) {
    CFX_ByteString str(FXFT_Get_Face_Style_Name(m_Face));
    str.MakeLower();
    if (str.Find("italic") != -1) {
      ret = TRUE;
    }
  }
  return ret;
}

FX_BOOL CFX_Font::IsBold() const {
  if (!m_Face)
    return FALSE;
  return FXFT_Is_Face_Bold(m_Face) == FXFT_STYLE_FLAG_BOLD;
}

FX_BOOL CFX_Font::IsFixedWidth() const {
  if (!m_Face)
    return FALSE;
  return FXFT_Is_Face_fixedwidth(m_Face);
}

CFX_WideString CFX_Font::GetPsName() const {
  if (!m_Face) {
    return CFX_WideString();
  }
  CFX_WideString psName =
      CFX_WideString::FromLocal(FXFT_Get_Postscript_Name(m_Face));
  if (psName.IsEmpty()) {
    psName = CFX_WideString::FromLocal("Untitled");
  }
  return psName;
}
CFX_ByteString CFX_Font::GetFamilyName() const {
  if (!m_Face && !m_pSubstFont) {
    return CFX_ByteString();
  }
  if (m_Face) {
    return CFX_ByteString(FXFT_Get_Face_Family_Name(m_Face));
  }
  return m_pSubstFont->m_Family;
}
CFX_ByteString CFX_Font::GetFaceName() const {
  if (!m_Face && !m_pSubstFont) {
    return CFX_ByteString();
  }
  if (m_Face) {
    CFX_ByteString facename;
    CFX_ByteString style = CFX_ByteString(FXFT_Get_Face_Style_Name(m_Face));
    facename = GetFamilyName();
    if (facename.IsEmpty()) {
      facename = "Untitled";
    }
    if (!style.IsEmpty() && style != "Regular") {
      facename += " " + style;
    }
    return facename;
  }
  return m_pSubstFont->m_Family;
}
FX_BOOL CFX_Font::GetBBox(FX_RECT& bbox) {
  if (!m_Face) {
    return FALSE;
  }
  int em = FXFT_Get_Face_UnitsPerEM(m_Face);
  if (em == 0) {
    bbox.left = FXFT_Get_Face_xMin(m_Face);
    bbox.bottom = FXFT_Get_Face_yMax(m_Face);
    bbox.top = FXFT_Get_Face_yMin(m_Face);
    bbox.right = FXFT_Get_Face_xMax(m_Face);
  } else {
    bbox.left = FXFT_Get_Face_xMin(m_Face) * 1000 / em;
    bbox.top = FXFT_Get_Face_yMin(m_Face) * 1000 / em;
    bbox.right = FXFT_Get_Face_xMax(m_Face) * 1000 / em;
    bbox.bottom = FXFT_Get_Face_yMax(m_Face) * 1000 / em;
  }
  return TRUE;
}

int CFX_Font::GetHeight() const {
  if (!m_Face)
    return 0;

  return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
                   FXFT_Get_Face_Height(m_Face));
}

int CFX_Font::GetMaxAdvanceWidth() const {
  if (!m_Face)
    return 0;

  return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
                   FXFT_Get_Face_MaxAdvanceWidth(m_Face));
}

int CFX_Font::GetULPos() const {
  if (!m_Face)
    return 0;

  return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
                   FXFT_Get_Face_UnderLinePosition(m_Face));
}

int CFX_Font::GetULthickness() const {
  if (!m_Face)
    return 0;

  return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
                   FXFT_Get_Face_UnderLineThickness(m_Face));
}

CFX_UnicodeEncoding::CFX_UnicodeEncoding(CFX_Font* pFont) : m_pFont(pFont) {
}

CFX_UnicodeEncoding::~CFX_UnicodeEncoding() {
}

FX_DWORD CFX_UnicodeEncoding::GlyphFromCharCode(FX_DWORD charcode) {
  FXFT_Face face = m_pFont->GetFace();
  if (!face)
    return charcode;

  if (FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE) == 0)
    return FXFT_Get_Char_Index(face, charcode);

  if (m_pFont->GetSubstFont() && m_pFont->GetSubstFont()->m_Charset == 2) {
    FX_DWORD index = 0;
    if (FXFT_Select_Charmap(face, FXFT_ENCODING_MS_SYMBOL) == 0)
      index = FXFT_Get_Char_Index(face, charcode);
    if (!index && !FXFT_Select_Charmap(face, FXFT_ENCODING_APPLE_ROMAN))
      return FXFT_Get_Char_Index(face, charcode);
  }
  return charcode;
}

#ifdef PDF_ENABLE_XFA
CFX_UnicodeEncodingEx::CFX_UnicodeEncodingEx(CFX_Font* pFont,
                                             FX_DWORD EncodingID)
    : CFX_UnicodeEncoding(pFont), m_nEncodingID(EncodingID) {
}

CFX_UnicodeEncodingEx::~CFX_UnicodeEncodingEx() {
}

FX_DWORD CFX_UnicodeEncodingEx::GlyphFromCharCode(FX_DWORD charcode) {
  FXFT_Face face = m_pFont->GetFace();
  FT_UInt nIndex = FXFT_Get_Char_Index(face, charcode);
  if (nIndex > 0) {
    return nIndex;
  }
  int nmaps = FXFT_Get_Face_CharmapCount(face);
  int m = 0;
  while (m < nmaps) {
    int nEncodingID =
        FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[m++]);
    if (m_nEncodingID == nEncodingID) {
      continue;
    }
    int error = FXFT_Select_Charmap(face, nEncodingID);
    if (error) {
      continue;
    }
    nIndex = FXFT_Get_Char_Index(face, charcode);
    if (nIndex > 0) {
      m_nEncodingID = nEncodingID;
      return nIndex;
    }
  }
  FXFT_Select_Charmap(face, m_nEncodingID);
  return 0;
}

FX_DWORD CFX_UnicodeEncodingEx::CharCodeFromUnicode(FX_WCHAR Unicode) const {
  if (m_nEncodingID == FXFM_ENCODING_UNICODE ||
      m_nEncodingID == FXFM_ENCODING_MS_SYMBOL) {
    return Unicode;
  }
  FXFT_Face face = m_pFont->GetFace();
  int nmaps = FXFT_Get_Face_CharmapCount(face);
  for (int i = 0; i < nmaps; i++) {
    int nEncodingID =
        FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[i]);
    if (nEncodingID == FXFM_ENCODING_UNICODE ||
        nEncodingID == FXFM_ENCODING_MS_SYMBOL) {
      return Unicode;
    }
  }
  return -1;
}

CFX_UnicodeEncodingEx* FX_CreateFontEncodingEx(CFX_Font* pFont,
                                               FX_DWORD nEncodingID) {
  if (!pFont || !pFont->GetFace())
    return nullptr;

  if (nEncodingID != FXFM_ENCODING_NONE)
    return _FXFM_CreateFontEncoding(pFont, nEncodingID);

  for (size_t i = 0; i < FX_ArraySize(g_EncodingID); ++i) {
    CFX_UnicodeEncodingEx* pFontEncoding =
        _FXFM_CreateFontEncoding(pFont, g_EncodingID[i]);
    if (pFontEncoding) {
      return pFontEncoding;
    }
  }
  return NULL;
}
#endif  // PDF_ENABLE_XFA
