// 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/fpdfapi/fpdf_font/include/cpdf_font.h"

#include <memory>

#include "core/fpdfapi/fpdf_font/cpdf_truetypefont.h"
#include "core/fpdfapi/fpdf_font/cpdf_type1font.h"
#include "core/fpdfapi/fpdf_font/cpdf_type3font.h"
#include "core/fpdfapi/fpdf_font/font_int.h"
#include "core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h"
#include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h"
#include "core/fpdfapi/fpdf_page/pageint.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_name.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
#include "core/fpdfapi/include/cpdf_modulemgr.h"
#include "core/fxge/include/fx_freetype.h"

namespace {

const uint8_t ChineseFontNames[][5] = {{0xCB, 0xCE, 0xCC, 0xE5, 0x00},
                                       {0xBF, 0xAC, 0xCC, 0xE5, 0x00},
                                       {0xBA, 0xDA, 0xCC, 0xE5, 0x00},
                                       {0xB7, 0xC2, 0xCB, 0xCE, 0x00},
                                       {0xD0, 0xC2, 0xCB, 0xCE, 0x00}};

FX_BOOL GetPredefinedEncoding(int& basemap, const CFX_ByteString& value) {
  if (value == "WinAnsiEncoding")
    basemap = PDFFONT_ENCODING_WINANSI;
  else if (value == "MacRomanEncoding")
    basemap = PDFFONT_ENCODING_MACROMAN;
  else if (value == "MacExpertEncoding")
    basemap = PDFFONT_ENCODING_MACEXPERT;
  else if (value == "PDFDocEncoding")
    basemap = PDFFONT_ENCODING_PDFDOC;
  else
    return FALSE;
  return TRUE;
}

}  // namespace

CPDF_Font::CPDF_Font()
    : m_pFontFile(nullptr),
      m_pFontDict(nullptr),
      m_pToUnicodeMap(nullptr),
      m_bToUnicodeLoaded(FALSE),
      m_Flags(0),
      m_StemV(0),
      m_Ascent(0),
      m_Descent(0),
      m_ItalicAngle(0) {}

CPDF_Font::~CPDF_Font() {
  delete m_pToUnicodeMap;
  m_pToUnicodeMap = NULL;

  if (m_pFontFile) {
    m_pDocument->GetPageData()->ReleaseFontFileStreamAcc(
        const_cast<CPDF_Stream*>(m_pFontFile->GetStream()->AsStream()));
  }
}

bool CPDF_Font::IsType1Font() const {
  return false;
}

bool CPDF_Font::IsTrueTypeFont() const {
  return false;
}

bool CPDF_Font::IsType3Font() const {
  return false;
}

bool CPDF_Font::IsCIDFont() const {
  return false;
}

const CPDF_Type1Font* CPDF_Font::AsType1Font() const {
  return nullptr;
}

CPDF_Type1Font* CPDF_Font::AsType1Font() {
  return nullptr;
}

const CPDF_TrueTypeFont* CPDF_Font::AsTrueTypeFont() const {
  return nullptr;
}

CPDF_TrueTypeFont* CPDF_Font::AsTrueTypeFont() {
  return nullptr;
}

const CPDF_Type3Font* CPDF_Font::AsType3Font() const {
  return nullptr;
}

CPDF_Type3Font* CPDF_Font::AsType3Font() {
  return nullptr;
}

const CPDF_CIDFont* CPDF_Font::AsCIDFont() const {
  return nullptr;
}

CPDF_CIDFont* CPDF_Font::AsCIDFont() {
  return nullptr;
}

FX_BOOL CPDF_Font::IsUnicodeCompatible() const {
  return FALSE;
}

int CPDF_Font::CountChar(const FX_CHAR* pString, int size) const {
  return size;
}

int CPDF_Font::GetCharSize(uint32_t charcode) const {
  return 1;
}

int CPDF_Font::GlyphFromCharCode(uint32_t charcode, FX_BOOL* pVertGlyph) {
  ASSERT(false);
  return 0;
}

int CPDF_Font::GlyphFromCharCodeExt(uint32_t charcode) {
  return GlyphFromCharCode(charcode);
}

FX_BOOL CPDF_Font::IsVertWriting() const {
  FX_BOOL bVertWriting = FALSE;
  const CPDF_CIDFont* pCIDFont = AsCIDFont();
  if (pCIDFont) {
    bVertWriting = pCIDFont->IsVertWriting();
  } else {
    bVertWriting = m_Font.IsVertical();
  }
  return bVertWriting;
}

int CPDF_Font::AppendChar(FX_CHAR* buf, uint32_t charcode) const {
  *buf = static_cast<FX_CHAR>(charcode);
  return 1;
}

void CPDF_Font::AppendChar(CFX_ByteString& str, uint32_t charcode) const {
  char buf[4];
  int len = AppendChar(buf, charcode);
  if (len == 1) {
    str += buf[0];
  } else {
    str += CFX_ByteString(buf, len);
  }
}

CFX_WideString CPDF_Font::UnicodeFromCharCode(uint32_t charcode) const {
  if (!m_bToUnicodeLoaded)
    ((CPDF_Font*)this)->LoadUnicodeMap();

  if (m_pToUnicodeMap)
    return m_pToUnicodeMap->Lookup(charcode);
  return CFX_WideString();
}

uint32_t CPDF_Font::CharCodeFromUnicode(FX_WCHAR unicode) const {
  if (!m_bToUnicodeLoaded)
    ((CPDF_Font*)this)->LoadUnicodeMap();

  if (m_pToUnicodeMap)
    return m_pToUnicodeMap->ReverseLookup(unicode);
  return 0;
}

void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc) {
  m_Flags = pFontDesc->GetIntegerBy("Flags", PDFFONT_NONSYMBOLIC);
  int ItalicAngle = 0;
  FX_BOOL bExistItalicAngle = FALSE;
  if (pFontDesc->KeyExist("ItalicAngle")) {
    ItalicAngle = pFontDesc->GetIntegerBy("ItalicAngle");
    bExistItalicAngle = TRUE;
  }
  if (ItalicAngle < 0) {
    m_Flags |= PDFFONT_ITALIC;
    m_ItalicAngle = ItalicAngle;
  }
  FX_BOOL bExistStemV = FALSE;
  if (pFontDesc->KeyExist("StemV")) {
    m_StemV = pFontDesc->GetIntegerBy("StemV");
    bExistStemV = TRUE;
  }
  FX_BOOL bExistAscent = FALSE;
  if (pFontDesc->KeyExist("Ascent")) {
    m_Ascent = pFontDesc->GetIntegerBy("Ascent");
    bExistAscent = TRUE;
  }
  FX_BOOL bExistDescent = FALSE;
  if (pFontDesc->KeyExist("Descent")) {
    m_Descent = pFontDesc->GetIntegerBy("Descent");
    bExistDescent = TRUE;
  }
  FX_BOOL bExistCapHeight = FALSE;
  if (pFontDesc->KeyExist("CapHeight")) {
    bExistCapHeight = TRUE;
  }
  if (bExistItalicAngle && bExistAscent && bExistCapHeight && bExistDescent &&
      bExistStemV) {
    m_Flags |= PDFFONT_USEEXTERNATTR;
  }
  if (m_Descent > 10) {
    m_Descent = -m_Descent;
  }
  CPDF_Array* pBBox = pFontDesc->GetArrayBy("FontBBox");
  if (pBBox) {
    m_FontBBox.left = pBBox->GetIntegerAt(0);
    m_FontBBox.bottom = pBBox->GetIntegerAt(1);
    m_FontBBox.right = pBBox->GetIntegerAt(2);
    m_FontBBox.top = pBBox->GetIntegerAt(3);
  }

  CPDF_Stream* pFontFile = pFontDesc->GetStreamBy("FontFile");
  if (!pFontFile)
    pFontFile = pFontDesc->GetStreamBy("FontFile2");
  if (!pFontFile)
    pFontFile = pFontDesc->GetStreamBy("FontFile3");
  if (!pFontFile)
    return;

  m_pFontFile = m_pDocument->LoadFontFile(pFontFile);
  if (!m_pFontFile)
    return;

  const uint8_t* pFontData = m_pFontFile->GetData();
  uint32_t dwFontSize = m_pFontFile->GetSize();
  if (!m_Font.LoadEmbedded(pFontData, dwFontSize)) {
    m_pDocument->GetPageData()->ReleaseFontFileStreamAcc(
        const_cast<CPDF_Stream*>(m_pFontFile->GetStream()->AsStream()));
    m_pFontFile = nullptr;
  }
}

void CPDF_Font::CheckFontMetrics() {
  if (m_FontBBox.top == 0 && m_FontBBox.bottom == 0 && m_FontBBox.left == 0 &&
      m_FontBBox.right == 0) {
    FXFT_Face face = m_Font.GetFace();
    if (face) {
      m_FontBBox.left = TT2PDF(FXFT_Get_Face_xMin(face), face);
      m_FontBBox.bottom = TT2PDF(FXFT_Get_Face_yMin(face), face);
      m_FontBBox.right = TT2PDF(FXFT_Get_Face_xMax(face), face);
      m_FontBBox.top = TT2PDF(FXFT_Get_Face_yMax(face), face);
      m_Ascent = TT2PDF(FXFT_Get_Face_Ascender(face), face);
      m_Descent = TT2PDF(FXFT_Get_Face_Descender(face), face);
    } else {
      FX_BOOL bFirst = TRUE;
      for (int i = 0; i < 256; i++) {
        FX_RECT rect = GetCharBBox(i);
        if (rect.left == rect.right) {
          continue;
        }
        if (bFirst) {
          m_FontBBox = rect;
          bFirst = FALSE;
        } else {
          if (m_FontBBox.top < rect.top) {
            m_FontBBox.top = rect.top;
          }
          if (m_FontBBox.right < rect.right) {
            m_FontBBox.right = rect.right;
          }
          if (m_FontBBox.left > rect.left) {
            m_FontBBox.left = rect.left;
          }
          if (m_FontBBox.bottom > rect.bottom) {
            m_FontBBox.bottom = rect.bottom;
          }
        }
      }
    }
  }
  if (m_Ascent == 0 && m_Descent == 0) {
    FX_RECT rect = GetCharBBox('A');
    m_Ascent = rect.bottom == rect.top ? m_FontBBox.top : rect.top;
    rect = GetCharBBox('g');
    m_Descent = rect.bottom == rect.top ? m_FontBBox.bottom : rect.bottom;
  }
}

void CPDF_Font::LoadUnicodeMap() {
  m_bToUnicodeLoaded = TRUE;
  CPDF_Stream* pStream = m_pFontDict->GetStreamBy("ToUnicode");
  if (!pStream) {
    return;
  }
  m_pToUnicodeMap = new CPDF_ToUnicodeMap;
  m_pToUnicodeMap->Load(pStream);
}

int CPDF_Font::GetStringWidth(const FX_CHAR* pString, int size) {
  int offset = 0;
  int width = 0;
  while (offset < size) {
    uint32_t charcode = GetNextChar(pString, size, offset);
    width += GetCharWidthF(charcode);
  }
  return width;
}

CPDF_Font* CPDF_Font::GetStockFont(CPDF_Document* pDoc,
                                   const CFX_ByteStringC& name) {
  CFX_ByteString fontname(name);
  int font_id = PDF_GetStandardFontName(&fontname);
  if (font_id < 0) {
    return nullptr;
  }
  CPDF_FontGlobals* pFontGlobals =
      CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
  CPDF_Font* pFont = pFontGlobals->Find(pDoc, font_id);
  if (pFont) {
    return pFont;
  }
  CPDF_Dictionary* pDict = new CPDF_Dictionary;
  pDict->SetAtName("Type", "Font");
  pDict->SetAtName("Subtype", "Type1");
  pDict->SetAtName("BaseFont", fontname);
  pDict->SetAtName("Encoding", "WinAnsiEncoding");
  pFont = CPDF_Font::CreateFontF(NULL, pDict);
  pFontGlobals->Set(pDoc, font_id, pFont);
  return pFont;
}

CPDF_Font* CPDF_Font::CreateFontF(CPDF_Document* pDoc,
                                  CPDF_Dictionary* pFontDict) {
  CFX_ByteString type = pFontDict->GetStringBy("Subtype");
  std::unique_ptr<CPDF_Font> pFont;
  if (type == "TrueType") {
    CFX_ByteString tag = pFontDict->GetStringBy("BaseFont").Left(4);
    for (size_t i = 0; i < FX_ArraySize(ChineseFontNames); ++i) {
      if (tag == CFX_ByteString(ChineseFontNames[i], 4)) {
        CPDF_Dictionary* pFontDesc = pFontDict->GetDictBy("FontDescriptor");
        if (!pFontDesc || !pFontDesc->KeyExist("FontFile2"))
          pFont.reset(new CPDF_CIDFont);
        break;
      }
    }
    if (!pFont)
      pFont.reset(new CPDF_TrueTypeFont);
  } else if (type == "Type3") {
    pFont.reset(new CPDF_Type3Font);
  } else if (type == "Type0") {
    pFont.reset(new CPDF_CIDFont);
  } else {
    pFont.reset(new CPDF_Type1Font);
  }
  pFont->m_pFontDict = pFontDict;
  pFont->m_pDocument = pDoc;
  pFont->m_BaseFont = pFontDict->GetStringBy("BaseFont");
  return pFont->Load() ? pFont.release() : nullptr;
}

uint32_t CPDF_Font::GetNextChar(const FX_CHAR* pString,
                                int nStrLen,
                                int& offset) const {
  if (offset < 0 || nStrLen < 1) {
    return 0;
  }
  uint8_t ch = offset < nStrLen ? pString[offset++] : pString[nStrLen - 1];
  return static_cast<uint32_t>(ch);
}

void CPDF_Font::LoadPDFEncoding(CPDF_Object* pEncoding,
                                int& iBaseEncoding,
                                CFX_ByteString*& pCharNames,
                                FX_BOOL bEmbedded,
                                FX_BOOL bTrueType) {
  if (!pEncoding) {
    if (m_BaseFont == "Symbol") {
      iBaseEncoding = bTrueType ? PDFFONT_ENCODING_MS_SYMBOL
                                : PDFFONT_ENCODING_ADOBE_SYMBOL;
    } else if (!bEmbedded && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {
      iBaseEncoding = PDFFONT_ENCODING_WINANSI;
    }
    return;
  }
  if (pEncoding->IsName()) {
    if (iBaseEncoding == PDFFONT_ENCODING_ADOBE_SYMBOL ||
        iBaseEncoding == PDFFONT_ENCODING_ZAPFDINGBATS) {
      return;
    }
    if ((m_Flags & PDFFONT_SYMBOLIC) && m_BaseFont == "Symbol") {
      if (!bTrueType) {
        iBaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL;
      }
      return;
    }
    CFX_ByteString bsEncoding = pEncoding->GetString();
    if (bsEncoding.Compare("MacExpertEncoding") == 0) {
      bsEncoding = "WinAnsiEncoding";
    }
    GetPredefinedEncoding(iBaseEncoding, bsEncoding);
    return;
  }

  CPDF_Dictionary* pDict = pEncoding->AsDictionary();
  if (!pDict)
    return;

  if (iBaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL &&
      iBaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS) {
    CFX_ByteString bsEncoding = pDict->GetStringBy("BaseEncoding");
    if (bsEncoding.Compare("MacExpertEncoding") == 0 && bTrueType) {
      bsEncoding = "WinAnsiEncoding";
    }
    GetPredefinedEncoding(iBaseEncoding, bsEncoding);
  }
  if ((!bEmbedded || bTrueType) && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {
    iBaseEncoding = PDFFONT_ENCODING_STANDARD;
  }
  CPDF_Array* pDiffs = pDict->GetArrayBy("Differences");
  if (!pDiffs) {
    return;
  }
  pCharNames = new CFX_ByteString[256];
  uint32_t cur_code = 0;
  for (uint32_t i = 0; i < pDiffs->GetCount(); i++) {
    CPDF_Object* pElement = pDiffs->GetDirectObjectAt(i);
    if (!pElement)
      continue;

    if (CPDF_Name* pName = pElement->AsName()) {
      if (cur_code < 256)
        pCharNames[cur_code] = pName->GetString();
      cur_code++;
    } else {
      cur_code = pElement->GetInteger();
    }
  }
}

FX_BOOL CPDF_Font::IsStandardFont() const {
  if (!IsType1Font())
    return FALSE;
  if (m_pFontFile)
    return FALSE;
  if (AsType1Font()->GetBase14Font() < 0)
    return FALSE;
  return TRUE;
}

const FX_CHAR* CPDF_Font::GetAdobeCharName(int iBaseEncoding,
                                           const CFX_ByteString* pCharNames,
                                           int charcode) {
  ASSERT(charcode >= 0 && charcode < 256);
  if (charcode < 0 || charcode >= 256)
    return nullptr;

  const FX_CHAR* name = nullptr;
  if (pCharNames)
    name = pCharNames[charcode].c_str();
  if ((!name || name[0] == 0) && iBaseEncoding)
    name = PDF_CharNameFromPredefinedCharSet(iBaseEncoding, charcode);
  return name && name[0] ? name : nullptr;
}
