// 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/font/cpdf_type3font.h"

#include <algorithm>
#include <iterator>
#include <type_traits>
#include <utility>

#include "core/fpdfapi/font/cpdf_type3char.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fxcrt/autorestorer.h"
#include "core/fxcrt/fx_system.h"
#include "third_party/base/check.h"

namespace {

constexpr int kMaxType3FormLevel = 4;

}  // namespace

CPDF_Type3Font::CPDF_Type3Font(CPDF_Document* pDocument,
                               RetainPtr<CPDF_Dictionary> pFontDict,
                               FormFactoryIface* pFormFactory)
    : CPDF_SimpleFont(pDocument, std::move(pFontDict)),
      m_pFormFactory(pFormFactory) {
  DCHECK(GetDocument());
}

CPDF_Type3Font::~CPDF_Type3Font() = default;

bool CPDF_Type3Font::IsType3Font() const {
  return true;
}

const CPDF_Type3Font* CPDF_Type3Font::AsType3Font() const {
  return this;
}

CPDF_Type3Font* CPDF_Type3Font::AsType3Font() {
  return this;
}

void CPDF_Type3Font::WillBeDestroyed() {
  // Last reference to |this| may be through one of its CPDF_Type3Chars.
  RetainPtr<CPDF_Font> protector(this);
  for (const auto& item : m_CacheMap) {
    if (item.second)
      item.second->WillBeDestroyed();
  }
}

bool CPDF_Type3Font::Load() {
  m_pFontResources = m_pFontDict->GetMutableDictFor("Resources");
  const CPDF_Array* pMatrix = m_pFontDict->GetArrayFor("FontMatrix");
  float xscale = 1.0f;
  float yscale = 1.0f;
  if (pMatrix) {
    m_FontMatrix = pMatrix->GetMatrix();
    xscale = m_FontMatrix.a;
    yscale = m_FontMatrix.d;
  }

  const CPDF_Array* pBBox = m_pFontDict->GetArrayFor("FontBBox");
  if (pBBox) {
    CFX_FloatRect box(
        pBBox->GetNumberAt(0) * xscale, pBBox->GetNumberAt(1) * yscale,
        pBBox->GetNumberAt(2) * xscale, pBBox->GetNumberAt(3) * yscale);
    CPDF_Type3Char::TextUnitRectToGlyphUnitRect(&box);
    m_FontBBox = box.ToFxRect();
  }

  static constexpr size_t kCharLimit = std::extent<decltype(m_CharWidthL)>();
  int StartChar = m_pFontDict->GetIntegerFor("FirstChar");
  if (StartChar >= 0 && static_cast<size_t>(StartChar) < kCharLimit) {
    const CPDF_Array* pWidthArray = m_pFontDict->GetArrayFor("Widths");
    if (pWidthArray) {
      size_t count = std::min(pWidthArray->size(), kCharLimit);
      count = std::min(count, kCharLimit - StartChar);
      for (size_t i = 0; i < count; i++) {
        m_CharWidthL[StartChar + i] =
            FXSYS_roundf(CPDF_Type3Char::TextUnitToGlyphUnit(
                pWidthArray->GetNumberAt(i) * xscale));
      }
    }
  }
  m_pCharProcs = m_pFontDict->GetMutableDictFor("CharProcs");
  if (m_pFontDict->GetDirectObjectFor("Encoding"))
    LoadPDFEncoding(false, false);
  return true;
}

void CPDF_Type3Font::LoadGlyphMap() {}

void CPDF_Type3Font::CheckType3FontMetrics() {
  CheckFontMetrics();
}

CPDF_Type3Char* CPDF_Type3Font::LoadChar(uint32_t charcode) {
  if (m_CharLoadingDepth >= kMaxType3FormLevel)
    return nullptr;

  auto it = m_CacheMap.find(charcode);
  if (it != m_CacheMap.end())
    return it->second.get();

  const char* name = GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode);
  if (!name)
    return nullptr;

  if (!m_pCharProcs)
    return nullptr;

  RetainPtr<CPDF_Stream> pStream =
      ToStream(m_pCharProcs->GetMutableDirectObjectFor(name));
  if (!pStream)
    return nullptr;

  std::unique_ptr<CPDF_Font::FormIface> pForm = m_pFormFactory->CreateForm(
      m_pDocument.Get(), m_pFontResources ? m_pFontResources : m_pPageResources,
      pStream);

  auto pNewChar = std::make_unique<CPDF_Type3Char>();

  // This can trigger recursion into this method. The content of |m_CacheMap|
  // can change as a result. Thus after it returns, check the cache again for
  // a cache hit.
  {
    AutoRestorer<int> restorer(&m_CharLoadingDepth);
    m_CharLoadingDepth++;
    pForm->ParseContentForType3Char(pNewChar.get());
  }
  it = m_CacheMap.find(charcode);
  if (it != m_CacheMap.end())
    return it->second.get();

  pNewChar->Transform(pForm.get(), m_FontMatrix);
  if (pForm->HasPageObjects())
    pNewChar->SetForm(std::move(pForm));

  CPDF_Type3Char* pCachedChar = pNewChar.get();
  m_CacheMap[charcode] = std::move(pNewChar);
  return pCachedChar;
}

int CPDF_Type3Font::GetCharWidthF(uint32_t charcode) {
  if (charcode >= std::size(m_CharWidthL))
    charcode = 0;

  if (m_CharWidthL[charcode])
    return m_CharWidthL[charcode];

  const CPDF_Type3Char* pChar = LoadChar(charcode);
  return pChar ? pChar->width() : 0;
}

FX_RECT CPDF_Type3Font::GetCharBBox(uint32_t charcode) {
  FX_RECT ret;
  const CPDF_Type3Char* pChar = LoadChar(charcode);
  if (pChar)
    ret = pChar->bbox();
  return ret;
}
