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

#include "core/fpdfapi/fpdf_font/cpdf_type3char.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_form.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/fxcrt/include/fx_system.h"
#include "third_party/base/stl_util.h"

CPDF_Type3Font::CPDF_Type3Font()
    : m_pCharProcs(nullptr),
      m_pPageResources(nullptr),
      m_pFontResources(nullptr) {
  FXSYS_memset(m_CharWidthL, 0, sizeof(m_CharWidthL));
}

CPDF_Type3Font::~CPDF_Type3Font() {
  for (auto it : m_CacheMap)
    delete it.second;
}

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

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

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

FX_BOOL CPDF_Type3Font::Load() {
  m_pFontResources = m_pFontDict->GetDictBy("Resources");
  CPDF_Array* pMatrix = m_pFontDict->GetArrayBy("FontMatrix");
  FX_FLOAT xscale = 1.0f, yscale = 1.0f;
  if (pMatrix) {
    m_FontMatrix = pMatrix->GetMatrix();
    xscale = m_FontMatrix.a;
    yscale = m_FontMatrix.d;
  }
  CPDF_Array* pBBox = m_pFontDict->GetArrayBy("FontBBox");
  if (pBBox) {
    m_FontBBox.left = (int32_t)(pBBox->GetNumberAt(0) * xscale * 1000);
    m_FontBBox.bottom = (int32_t)(pBBox->GetNumberAt(1) * yscale * 1000);
    m_FontBBox.right = (int32_t)(pBBox->GetNumberAt(2) * xscale * 1000);
    m_FontBBox.top = (int32_t)(pBBox->GetNumberAt(3) * yscale * 1000);
  }
  int StartChar = m_pFontDict->GetIntegerBy("FirstChar");
  CPDF_Array* pWidthArray = m_pFontDict->GetArrayBy("Widths");
  if (pWidthArray && (StartChar >= 0 && StartChar < 256)) {
    uint32_t count = pWidthArray->GetCount();
    if (count > 256) {
      count = 256;
    }
    if (StartChar + count > 256) {
      count = 256 - StartChar;
    }
    for (uint32_t i = 0; i < count; i++) {
      m_CharWidthL[StartChar + i] =
          FXSYS_round(pWidthArray->GetNumberAt(i) * xscale * 1000);
    }
  }
  m_pCharProcs = m_pFontDict->GetDictBy("CharProcs");
  CPDF_Object* pEncoding = m_pFontDict->GetElementValue("Encoding");
  if (pEncoding) {
    LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, FALSE, FALSE);
    if (m_pCharNames) {
      for (int i = 0; i < 256; i++) {
        m_Encoding.m_Unicodes[i] = PDF_UnicodeFromAdobeName(m_pCharNames[i]);
        if (m_Encoding.m_Unicodes[i] == 0) {
          m_Encoding.m_Unicodes[i] = i;
        }
      }
    }
  }
  return TRUE;
}

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

CPDF_Type3Char* CPDF_Type3Font::LoadChar(uint32_t charcode, int level) {
  if (level >= _FPDF_MAX_TYPE3_FORM_LEVEL_)
    return nullptr;

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

  const FX_CHAR* name =
      GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
  if (!name)
    return nullptr;

  CPDF_Stream* pStream =
      ToStream(m_pCharProcs ? m_pCharProcs->GetElementValue(name) : nullptr);
  if (!pStream)
    return nullptr;

  std::unique_ptr<CPDF_Type3Char> pNewChar(new CPDF_Type3Char(new CPDF_Form(
      m_pDocument, m_pFontResources ? m_pFontResources : m_pPageResources,
      pStream, nullptr)));

  // 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.
  pNewChar->m_pForm->ParseContent(nullptr, nullptr, pNewChar.get(), nullptr,
                                  level + 1);
  it = m_CacheMap.find(charcode);
  if (it != m_CacheMap.end())
    return it->second;

  FX_FLOAT scale = m_FontMatrix.GetXUnit();
  pNewChar->m_Width = (int32_t)(pNewChar->m_Width * scale + 0.5f);
  FX_RECT& rcBBox = pNewChar->m_BBox;
  CFX_FloatRect char_rect(
      (FX_FLOAT)rcBBox.left / 1000.0f, (FX_FLOAT)rcBBox.bottom / 1000.0f,
      (FX_FLOAT)rcBBox.right / 1000.0f, (FX_FLOAT)rcBBox.top / 1000.0f);
  if (rcBBox.right <= rcBBox.left || rcBBox.bottom >= rcBBox.top)
    char_rect = pNewChar->m_pForm->CalcBoundingBox();

  char_rect.Transform(&m_FontMatrix);
  rcBBox.left = FXSYS_round(char_rect.left * 1000);
  rcBBox.right = FXSYS_round(char_rect.right * 1000);
  rcBBox.top = FXSYS_round(char_rect.top * 1000);
  rcBBox.bottom = FXSYS_round(char_rect.bottom * 1000);

  ASSERT(!pdfium::ContainsKey(m_CacheMap, charcode));
  CPDF_Type3Char* pCachedChar = pNewChar.release();
  m_CacheMap[charcode] = pCachedChar;
  if (pCachedChar->m_pForm->GetPageObjectList()->empty()) {
    delete pCachedChar->m_pForm;
    pCachedChar->m_pForm = nullptr;
  }
  return pCachedChar;
}

int CPDF_Type3Font::GetCharWidthF(uint32_t charcode, int level) {
  if (charcode >= FX_ArraySize(m_CharWidthL))
    charcode = 0;

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

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

FX_RECT CPDF_Type3Font::GetCharBBox(uint32_t charcode, int level) {
  const CPDF_Type3Char* pChar = LoadChar(charcode, level);
  return pChar ? pChar->m_BBox : FX_RECT();
}
