// Copyright 2017 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 "xfa/fxfa/cxfa_pdffontmgr.h"

#include <algorithm>

#include "core/fpdfapi/font/cpdf_font.h"
#include "xfa/fxfa/cxfa_ffapp.h"

namespace {

// The 5 names per entry are: PsName, Normal, Bold, Italic, BoldItalic.
const char* const g_XFAPDFFontName[][5] = {
    {"Adobe PI Std", "AdobePIStd", "AdobePIStd", "AdobePIStd", "AdobePIStd"},
    {"Myriad Pro Light", "MyriadPro-Light", "MyriadPro-Semibold",
     "MyriadPro-LightIt", "MyriadPro-SemiboldIt"},
};

}  // namespace

CXFA_PDFFontMgr::CXFA_PDFFontMgr(CXFA_FFDoc* pDoc) : m_pDoc(pDoc) {}

CXFA_PDFFontMgr::~CXFA_PDFFontMgr() {}

CFX_RetainPtr<CFGAS_GEFont> CXFA_PDFFontMgr::FindFont(
    const CFX_ByteString& strPsName,
    bool bBold,
    bool bItalic,
    CPDF_Font** pDstPDFFont,
    bool bStrictMatch) {
  CPDF_Document* pDoc = m_pDoc->GetPDFDoc();
  if (!pDoc)
    return nullptr;

  CPDF_Dictionary* pFontSetDict =
      pDoc->GetRoot()->GetDictFor("AcroForm")->GetDictFor("DR");
  if (!pFontSetDict)
    return nullptr;

  pFontSetDict = pFontSetDict->GetDictFor("Font");
  if (!pFontSetDict)
    return nullptr;

  CFX_ByteString name = strPsName;
  name.Remove(' ');
  CFGAS_FontMgr* pFDEFontMgr = m_pDoc->GetApp()->GetFDEFontMgr();
  for (const auto& it : *pFontSetDict) {
    const CFX_ByteString& key = it.first;
    CPDF_Object* pObj = it.second.get();
    if (!PsNameMatchDRFontName(name.AsStringC(), bBold, bItalic, key,
                               bStrictMatch)) {
      continue;
    }
    CPDF_Dictionary* pFontDict = ToDictionary(pObj->GetDirect());
    if (!pFontDict || pFontDict->GetStringFor("Type") != "Font") {
      return nullptr;
    }
    CPDF_Font* pPDFFont = pDoc->LoadFont(pFontDict);
    if (!pPDFFont) {
      return nullptr;
    }
    if (!pPDFFont->IsEmbedded()) {
      *pDstPDFFont = pPDFFont;
      return nullptr;
    }
    return CFGAS_GEFont::LoadFont(pPDFFont->GetFont(), pFDEFontMgr);
  }
  return nullptr;
}

CFX_RetainPtr<CFGAS_GEFont> CXFA_PDFFontMgr::GetFont(
    const CFX_WideStringC& wsFontFamily,
    uint32_t dwFontStyles,
    CPDF_Font** pPDFFont,
    bool bStrictMatch) {
  uint32_t dwHashCode = FX_HashCode_GetW(wsFontFamily, false);
  CFX_ByteString strKey;
  strKey.Format("%u%u", dwHashCode, dwFontStyles);
  auto it = m_FontMap.find(strKey);
  if (it != m_FontMap.end())
    return it->second;
  CFX_ByteString bsPsName =
      CFX_ByteString::FromUnicode(CFX_WideString(wsFontFamily));
  bool bBold = (dwFontStyles & FX_FONTSTYLE_Bold) == FX_FONTSTYLE_Bold;
  bool bItalic = (dwFontStyles & FX_FONTSTYLE_Italic) == FX_FONTSTYLE_Italic;
  CFX_ByteString strFontName = PsNameToFontName(bsPsName, bBold, bItalic);
  CFX_RetainPtr<CFGAS_GEFont> pFont =
      FindFont(strFontName, bBold, bItalic, pPDFFont, bStrictMatch);
  if (pFont)
    m_FontMap[strKey] = pFont;
  return pFont;
}

CFX_ByteString CXFA_PDFFontMgr::PsNameToFontName(
    const CFX_ByteString& strPsName,
    bool bBold,
    bool bItalic) {
  for (size_t i = 0; i < FX_ArraySize(g_XFAPDFFontName); ++i) {
    if (strPsName == g_XFAPDFFontName[i][0]) {
      size_t index = 1;
      if (bBold)
        ++index;
      if (bItalic)
        index += 2;
      return g_XFAPDFFontName[i][index];
    }
  }
  return strPsName;
}

bool CXFA_PDFFontMgr::PsNameMatchDRFontName(const CFX_ByteStringC& bsPsName,
                                            bool bBold,
                                            bool bItalic,
                                            const CFX_ByteString& bsDRFontName,
                                            bool bStrictMatch) {
  CFX_ByteString bsDRName = bsDRFontName;
  bsDRName.Remove('-');
  int32_t iPsLen = bsPsName.GetLength();
  int32_t nIndex = bsDRName.Find(bsPsName);
  if (nIndex != -1 && !bStrictMatch)
    return true;

  if (nIndex != 0)
    return false;

  int32_t iDifferLength = bsDRName.GetLength() - iPsLen;
  if (iDifferLength > 1 || (bBold || bItalic)) {
    int32_t iBoldIndex = bsDRName.Find("Bold");
    bool bBoldFont = iBoldIndex > 0;
    if (bBold != bBoldFont)
      return false;

    if (bBoldFont) {
      iDifferLength =
          std::min(iDifferLength - 4, bsDRName.GetLength() - iBoldIndex - 4);
    }
    bool bItalicFont = true;
    if (bsDRName.Find("Italic") > 0) {
      iDifferLength -= 6;
    } else if (bsDRName.Find("It") > 0) {
      iDifferLength -= 2;
    } else if (bsDRName.Find("Oblique") > 0) {
      iDifferLength -= 7;
    } else {
      bItalicFont = false;
    }
    if (bItalic != bItalicFont)
      return false;

    if (iDifferLength > 1) {
      CFX_ByteString bsDRTailer = bsDRName.Right(iDifferLength);
      if (bsDRTailer == "MT" || bsDRTailer == "PSMT" ||
          bsDRTailer == "Regular" || bsDRTailer == "Reg") {
        return true;
      }
      if (bBoldFont || bItalicFont)
        return false;

      bool bMatch = false;
      switch (bsPsName.GetAt(iPsLen - 1)) {
        case 'L': {
          if (bsDRName.Right(5) == "Light") {
            bMatch = true;
          }
        } break;
        case 'R': {
          if (bsDRName.Right(7) == "Regular" || bsDRName.Right(3) == "Reg") {
            bMatch = true;
          }
        } break;
        case 'M': {
          if (bsDRName.Right(5) == "Medium") {
            bMatch = true;
          }
        } break;
        default:
          break;
      }
      return bMatch;
    }
  }
  return true;
}

bool CXFA_PDFFontMgr::GetCharWidth(const CFX_RetainPtr<CFGAS_GEFont>& pFont,
                                   wchar_t wUnicode,
                                   bool bCharCode,
                                   int32_t* pWidth) {
  if (wUnicode != 0x20 || bCharCode)
    return false;

  auto it = m_FDE2PDFFont.find(pFont);
  if (it == m_FDE2PDFFont.end())
    return false;

  CPDF_Font* pPDFFont = it->second;
  *pWidth = pPDFFont->GetCharWidthF(pPDFFont->CharCodeFromUnicode(wUnicode));
  return true;
}

void CXFA_PDFFontMgr::SetFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont,
                              CPDF_Font* pPDFFont) {
  m_FDE2PDFFont[pFont] = pPDFFont;
}
