// 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/fpdfdoc/cpdf_bafontmap.h"

#include <memory>
#include <utility>

#include "constants/annotation_common.h"
#include "core/fpdfapi/font/cpdf_font.h"
#include "core/fpdfapi/font/cpdf_fontencoding.h"
#include "core/fpdfapi/page/cpdf_docpagedata.h"
#include "core/fpdfapi/page/cpdf_page.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fpdfapi/parser/cpdf_parser.h"
#include "core/fpdfapi/parser/cpdf_reference.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/fpdf_parser_utility.h"
#include "core/fpdfdoc/cpdf_defaultappearance.h"
#include "core/fpdfdoc/cpdf_formfield.h"
#include "core/fpdfdoc/ipvt_fontmap.h"
#include "core/fxcrt/fx_codepage.h"
#include "core/fxcrt/stl_util.h"
#include "core/fxge/cfx_fontmapper.h"
#include "core/fxge/cfx_fontmgr.h"
#include "core/fxge/cfx_gemodule.h"
#include "core/fxge/cfx_substfont.h"

namespace {

bool FindNativeTrueTypeFont(ByteStringView sFontFaceName) {
  CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr();
  CFX_FontMapper* pFontMapper = pFontMgr->GetBuiltinMapper();
  pFontMapper->LoadInstalledFonts();
  return pFontMapper->HasInstalledFont(sFontFaceName) ||
         pFontMapper->HasLocalizedFont(sFontFaceName);
}

RetainPtr<CPDF_Font> AddNativeTrueTypeFontToPDF(CPDF_Document* pDoc,
                                                ByteString sFontFaceName,
                                                FX_Charset nCharset) {
  if (!pDoc)
    return nullptr;

  auto pFXFont = std::make_unique<CFX_Font>();
  pFXFont->LoadSubst(sFontFaceName, true, 0, 0, 0,
                     FX_GetCodePageFromCharset(nCharset), false);

  auto* pDocPageData = CPDF_DocPageData::FromDocument(pDoc);
  return pDocPageData->AddFont(std::move(pFXFont), nCharset);
}

ByteString EncodeFontAlias(ByteString sFontName, FX_Charset nCharset) {
  sFontName.Remove(' ');
  sFontName += ByteString::Format("_%02X", nCharset);
  return sFontName;
}

}  // namespace

CPDF_BAFontMap::Data::Data() = default;

CPDF_BAFontMap::Data::~Data() = default;

CPDF_BAFontMap::CPDF_BAFontMap(CPDF_Document* pDocument,
                               CPDF_Dictionary* pAnnotDict,
                               const ByteString& sAPType)
    : m_pDocument(pDocument), m_pAnnotDict(pAnnotDict), m_sAPType(sAPType) {
  FX_Charset nCharset = FX_Charset::kDefault;
  m_pDefaultFont = GetAnnotDefaultFont(&m_sDefaultFontName);
  if (m_pDefaultFont) {
    const CFX_SubstFont* pSubstFont = m_pDefaultFont->GetSubstFont();
    if (pSubstFont) {
      nCharset = pSubstFont->m_Charset;
    } else if (m_sDefaultFontName == "Wingdings" ||
               m_sDefaultFontName == "Wingdings2" ||
               m_sDefaultFontName == "Wingdings3" ||
               m_sDefaultFontName == "Webdings") {
      nCharset = FX_Charset::kSymbol;
    } else {
      nCharset = FX_Charset::kANSI;
    }
    AddFontData(m_pDefaultFont, m_sDefaultFontName, nCharset);
    AddFontToAnnotDict(m_pDefaultFont, m_sDefaultFontName);
  }

  if (nCharset != FX_Charset::kANSI)
    GetFontIndex(CFX_Font::kDefaultAnsiFontName, FX_Charset::kANSI, false);
}

CPDF_BAFontMap::~CPDF_BAFontMap() = default;

RetainPtr<CPDF_Font> CPDF_BAFontMap::GetPDFFont(int32_t nFontIndex) {
  if (fxcrt::IndexInBounds(m_Data, nFontIndex))
    return m_Data[nFontIndex]->pFont;
  return nullptr;
}

ByteString CPDF_BAFontMap::GetPDFFontAlias(int32_t nFontIndex) {
  if (fxcrt::IndexInBounds(m_Data, nFontIndex))
    return m_Data[nFontIndex]->sFontName;
  return ByteString();
}

int32_t CPDF_BAFontMap::GetWordFontIndex(uint16_t word,
                                         FX_Charset nCharset,
                                         int32_t nFontIndex) {
  if (nFontIndex > 0) {
    if (KnowWord(nFontIndex, word))
      return nFontIndex;
  } else {
    if (!m_Data.empty()) {
      const Data* pData = m_Data.front().get();
      if (nCharset == FX_Charset::kDefault ||
          pData->nCharset == FX_Charset::kSymbol ||
          nCharset == pData->nCharset) {
        if (KnowWord(0, word))
          return 0;
      }
    }
  }

  int32_t nNewFontIndex =
      GetFontIndex(GetCachedNativeFontName(nCharset), nCharset, true);
  if (nNewFontIndex >= 0) {
    if (KnowWord(nNewFontIndex, word))
      return nNewFontIndex;
  }
  nNewFontIndex = GetFontIndex(CFX_Font::kUniversalDefaultFontName,
                               FX_Charset::kDefault, false);
  if (nNewFontIndex >= 0) {
    if (KnowWord(nNewFontIndex, word))
      return nNewFontIndex;
  }
  return -1;
}

int32_t CPDF_BAFontMap::CharCodeFromUnicode(int32_t nFontIndex, uint16_t word) {
  if (!fxcrt::IndexInBounds(m_Data, nFontIndex))
    return -1;

  Data* pData = m_Data[nFontIndex].get();
  if (!pData->pFont)
    return -1;

  if (pData->pFont->IsUnicodeCompatible())
    return pData->pFont->CharCodeFromUnicode(word);

  return word < 0xFF ? word : -1;
}

FX_Charset CPDF_BAFontMap::CharSetFromUnicode(uint16_t word,
                                              FX_Charset nOldCharset) {
  // to avoid CJK Font to show ASCII
  if (word < 0x7F)
    return FX_Charset::kANSI;

  // follow the old charset
  if (nOldCharset != FX_Charset::kDefault)
    return nOldCharset;

  return CFX_Font::GetCharSetFromUnicode(word);
}

FX_Charset CPDF_BAFontMap::GetNativeCharset() {
  return FX_GetCharsetFromCodePage(FX_GetACP());
}

RetainPtr<CPDF_Font> CPDF_BAFontMap::FindFontSameCharset(ByteString* sFontAlias,
                                                         FX_Charset nCharset) {
  if (m_pAnnotDict->GetNameFor(pdfium::annotation::kSubtype) != "Widget")
    return nullptr;

  const CPDF_Dictionary* pRootDict = m_pDocument->GetRoot();
  if (!pRootDict)
    return nullptr;

  const CPDF_Dictionary* pAcroFormDict = pRootDict->GetDictFor("AcroForm");
  if (!pAcroFormDict)
    return nullptr;

  const CPDF_Dictionary* pDRDict = pAcroFormDict->GetDictFor("DR");
  if (!pDRDict)
    return nullptr;

  return FindResFontSameCharset(pDRDict, sFontAlias, nCharset);
}

RetainPtr<CPDF_Font> CPDF_BAFontMap::FindResFontSameCharset(
    const CPDF_Dictionary* pResDict,
    ByteString* sFontAlias,
    FX_Charset nCharset) {
  if (!pResDict)
    return nullptr;

  const CPDF_Dictionary* pFonts = pResDict->GetDictFor("Font");
  if (!pFonts)
    return nullptr;

  RetainPtr<CPDF_Font> pFind;
  CPDF_DictionaryLocker locker(pFonts);
  for (const auto& it : locker) {
    const ByteString& csKey = it.first;
    CPDF_Dictionary* pElement = ToDictionary(it.second->GetDirect());
    if (!ValidateDictType(pElement, "Font"))
      continue;

    auto* pData = CPDF_DocPageData::FromDocument(m_pDocument.Get());
    RetainPtr<CPDF_Font> pFont = pData->GetFont(pElement);
    if (!pFont)
      continue;

    const CFX_SubstFont* pSubst = pFont->GetSubstFont();
    if (!pSubst)
      continue;

    if (pSubst->m_Charset == nCharset) {
      *sFontAlias = csKey;
      pFind = std::move(pFont);
    }
  }
  return pFind;
}

RetainPtr<CPDF_Font> CPDF_BAFontMap::GetAnnotDefaultFont(ByteString* sAlias) {
  CPDF_Dictionary* pAcroFormDict = nullptr;
  const bool bWidget =
      (m_pAnnotDict->GetNameFor(pdfium::annotation::kSubtype) == "Widget");
  if (bWidget) {
    CPDF_Dictionary* pRootDict = m_pDocument->GetRoot();
    if (pRootDict)
      pAcroFormDict = pRootDict->GetDictFor("AcroForm");
  }

  ByteString sDA;
  const CPDF_Object* pObj =
      CPDF_FormField::GetFieldAttr(m_pAnnotDict.Get(), "DA");
  if (pObj)
    sDA = pObj->GetString();

  if (bWidget) {
    if (sDA.IsEmpty()) {
      pObj = CPDF_FormField::GetFieldAttr(pAcroFormDict, "DA");
      sDA = pObj ? pObj->GetString() : ByteString();
    }
  }
  if (sDA.IsEmpty())
    return nullptr;

  CPDF_DefaultAppearance appearance(sDA);
  float font_size;
  absl::optional<ByteString> font = appearance.GetFont(&font_size);
  *sAlias = font.value_or(ByteString());

  CPDF_Dictionary* pFontDict = nullptr;
  if (CPDF_Dictionary* pAPDict =
          m_pAnnotDict->GetDictFor(pdfium::annotation::kAP)) {
    if (CPDF_Dictionary* pNormalDict = pAPDict->GetDictFor("N")) {
      if (CPDF_Dictionary* pNormalResDict =
              pNormalDict->GetDictFor("Resources")) {
        if (CPDF_Dictionary* pResFontDict = pNormalResDict->GetDictFor("Font"))
          pFontDict = pResFontDict->GetDictFor(*sAlias);
      }
    }
  }
  if (bWidget && !pFontDict && pAcroFormDict) {
    if (CPDF_Dictionary* pDRDict = pAcroFormDict->GetDictFor("DR")) {
      if (CPDF_Dictionary* pDRFontDict = pDRDict->GetDictFor("Font"))
        pFontDict = pDRFontDict->GetDictFor(*sAlias);
    }
  }
  if (!pFontDict)
    return nullptr;

  return CPDF_DocPageData::FromDocument(m_pDocument.Get())->GetFont(pFontDict);
}

void CPDF_BAFontMap::AddFontToAnnotDict(const RetainPtr<CPDF_Font>& pFont,
                                        const ByteString& sAlias) {
  if (!pFont)
    return;

  CPDF_Dictionary* pAPDict =
      GetOrCreateDict(m_pAnnotDict.Get(), pdfium::annotation::kAP);

  // to avoid checkbox and radiobutton
  if (ToDictionary(pAPDict->GetObjectFor(m_sAPType)))
    return;

  CPDF_Stream* pStream = pAPDict->GetStreamFor(m_sAPType);
  if (!pStream) {
    pStream = m_pDocument->NewIndirect<CPDF_Stream>();
    pAPDict->SetNewFor<CPDF_Reference>(m_sAPType, m_pDocument.Get(),
                                       pStream->GetObjNum());
  }

  CPDF_Dictionary* pStreamDict = pStream->GetDict();
  if (!pStreamDict) {
    auto pOwnedDict = m_pDocument->New<CPDF_Dictionary>();
    pStreamDict = pOwnedDict.Get();
    pStream->InitStream({}, std::move(pOwnedDict));
  }

  CPDF_Dictionary* pStreamResList = GetOrCreateDict(pStreamDict, "Resources");
  CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDictFor("Font");
  if (!pStreamResFontList) {
    pStreamResFontList = m_pDocument->NewIndirect<CPDF_Dictionary>();
    pStreamResList->SetNewFor<CPDF_Reference>("Font", m_pDocument.Get(),
                                              pStreamResFontList->GetObjNum());
  }
  if (!pStreamResFontList->KeyExist(sAlias)) {
    CPDF_Dictionary* pFontDict = pFont->GetFontDict();
    RetainPtr<CPDF_Object> pObject =
        pFontDict->IsInline() ? pFontDict->Clone()
                              : pFontDict->MakeReference(m_pDocument.Get());
    pStreamResFontList->SetFor(sAlias, std::move(pObject));
  }
}

bool CPDF_BAFontMap::KnowWord(int32_t nFontIndex, uint16_t word) {
  return fxcrt::IndexInBounds(m_Data, nFontIndex) &&
         CharCodeFromUnicode(nFontIndex, word) >= 0;
}

int32_t CPDF_BAFontMap::GetFontIndex(const ByteString& sFontName,
                                     FX_Charset nCharset,
                                     bool bFind) {
  int32_t nFontIndex = FindFont(EncodeFontAlias(sFontName, nCharset), nCharset);
  if (nFontIndex >= 0)
    return nFontIndex;

  ByteString sAlias;
  RetainPtr<CPDF_Font> pFont =
      bFind ? FindFontSameCharset(&sAlias, nCharset) : nullptr;
  if (!pFont) {
    pFont = AddFontToDocument(sFontName, nCharset);
    sAlias = EncodeFontAlias(sFontName, nCharset);
  }
  AddFontToAnnotDict(pFont, sAlias);
  return AddFontData(pFont, sAlias, nCharset);
}

int32_t CPDF_BAFontMap::AddFontData(const RetainPtr<CPDF_Font>& pFont,
                                    const ByteString& sFontAlias,
                                    FX_Charset nCharset) {
  auto pNewData = std::make_unique<Data>();
  pNewData->pFont = pFont;
  pNewData->sFontName = sFontAlias;
  pNewData->nCharset = nCharset;
  m_Data.push_back(std::move(pNewData));
  return fxcrt::CollectionSize<int32_t>(m_Data) - 1;
}

int32_t CPDF_BAFontMap::FindFont(const ByteString& sFontName,
                                 FX_Charset nCharset) {
  int32_t i = 0;
  for (const auto& pData : m_Data) {
    if ((nCharset == FX_Charset::kDefault || nCharset == pData->nCharset) &&
        (sFontName.IsEmpty() || pData->sFontName == sFontName)) {
      return i;
    }
    ++i;
  }
  return -1;
}

ByteString CPDF_BAFontMap::GetNativeFontName(FX_Charset nCharset) {
  if (nCharset == FX_Charset::kDefault)
    nCharset = GetNativeCharset();

  ByteString sFontName = CFX_Font::GetDefaultFontNameByCharset(nCharset);
  if (!FindNativeTrueTypeFont(sFontName.AsStringView()))
    return ByteString();

  return sFontName;
}

ByteString CPDF_BAFontMap::GetCachedNativeFontName(FX_Charset nCharset) {
  for (const auto& pData : m_NativeFont) {
    if (pData && pData->nCharset == nCharset)
      return pData->sFontName;
  }

  ByteString sNew = GetNativeFontName(nCharset);
  if (sNew.IsEmpty())
    return ByteString();

  auto pNewData = std::make_unique<Native>();
  pNewData->nCharset = nCharset;
  pNewData->sFontName = sNew;
  m_NativeFont.push_back(std::move(pNewData));
  return sNew;
}

RetainPtr<CPDF_Font> CPDF_BAFontMap::AddFontToDocument(ByteString sFontName,
                                                       FX_Charset nCharset) {
  if (CFX_FontMapper::IsStandardFontName(sFontName))
    return AddStandardFont(sFontName);

  return AddSystemFont(sFontName, nCharset);
}

RetainPtr<CPDF_Font> CPDF_BAFontMap::AddStandardFont(ByteString sFontName) {
  auto* pPageData = CPDF_DocPageData::FromDocument(m_pDocument.Get());
  if (sFontName == "ZapfDingbats")
    return pPageData->AddStandardFont(sFontName, nullptr);

  static const CPDF_FontEncoding fe(FontEncoding::kWinAnsi);
  return pPageData->AddStandardFont(sFontName, &fe);
}

RetainPtr<CPDF_Font> CPDF_BAFontMap::AddSystemFont(ByteString sFontName,
                                                   FX_Charset nCharset) {
  if (sFontName.IsEmpty())
    sFontName = GetNativeFontName(nCharset);

  if (nCharset == FX_Charset::kDefault)
    nCharset = GetNativeCharset();

  return AddNativeTrueTypeFontToPDF(m_pDocument.Get(), sFontName, nCharset);
}
