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

#include "build/build_config.h"
#include "core/fpdfapi/font/cpdf_cidfont.h"
#include "core/fpdfapi/font/cpdf_font.h"
#include "core/fxge/cfx_substfont.h"
#include "core/fxge/text_char_pos.h"

CPDF_CharPosList::CPDF_CharPosList(const std::vector<uint32_t>& charCodes,
                                   const std::vector<float>& charPos,
                                   CPDF_Font* pFont,
                                   float font_size) {
  m_CharPos.reserve(charCodes.size());
  CPDF_CIDFont* pCIDFont = pFont->AsCIDFont();
  bool bVertWriting = pCIDFont && pCIDFont->IsVertWriting();
  for (size_t i = 0; i < charCodes.size(); ++i) {
    uint32_t CharCode = charCodes[i];
    if (CharCode == static_cast<uint32_t>(-1))
      continue;

    bool bVert = false;
    m_CharPos.emplace_back();
    TextCharPos& charpos = m_CharPos.back();
    if (pCIDFont)
      charpos.m_bFontStyle = true;
    WideString unicode = pFont->UnicodeFromCharCode(CharCode);
    charpos.m_Unicode = !unicode.IsEmpty() ? unicode[0] : CharCode;
    charpos.m_GlyphIndex = pFont->GlyphFromCharCode(CharCode, &bVert);
    uint32_t GlyphID = charpos.m_GlyphIndex;
#if defined(OS_MACOSX)
    charpos.m_ExtGID = pFont->GlyphFromCharCodeExt(CharCode);
    GlyphID = charpos.m_ExtGID != static_cast<uint32_t>(-1)
                  ? charpos.m_ExtGID
                  : charpos.m_GlyphIndex;
#endif
    CFX_Font* pCurrentFont;
    if (GlyphID != static_cast<uint32_t>(-1)) {
      charpos.m_FallbackFontPosition = -1;
      pCurrentFont = pFont->GetFont();
    } else {
      charpos.m_FallbackFontPosition =
          pFont->FallbackFontFromCharcode(CharCode);
      charpos.m_GlyphIndex = pFont->FallbackGlyphFromCharcode(
          charpos.m_FallbackFontPosition, CharCode);
      pCurrentFont = pFont->GetFontFallback(charpos.m_FallbackFontPosition);
#if defined(OS_MACOSX)
      charpos.m_ExtGID = charpos.m_GlyphIndex;
#endif
    }

    if (!pFont->IsEmbedded() && !pFont->IsCIDFont())
      charpos.m_FontCharWidth = pFont->GetCharWidthF(CharCode);
    else
      charpos.m_FontCharWidth = 0;

    charpos.m_Origin = CFX_PointF(i > 0 ? charPos[i - 1] : 0, 0);
    charpos.m_bGlyphAdjust = false;

    float scalingFactor = 1.0f;
    if (!pFont->IsEmbedded() && pFont->HasFontWidths() && !bVertWriting &&
        !pCurrentFont->GetSubstFont()->m_bFlagMM) {
      uint32_t pdfGlyphWidth = pFont->GetCharWidthF(CharCode);
      uint32_t ftGlyphWidth =
          pCurrentFont ? pCurrentFont->GetGlyphWidth(charpos.m_GlyphIndex) : 0;
      if (ftGlyphWidth && pdfGlyphWidth > ftGlyphWidth + 1) {
        // Move the initial x position by half of the excess (transformed to
        // text space coordinates).
        charpos.m_Origin.x +=
            (pdfGlyphWidth - ftGlyphWidth) * font_size / 2000.0f;
      } else if (pdfGlyphWidth && ftGlyphWidth &&
                 pdfGlyphWidth < ftGlyphWidth) {
        scalingFactor = static_cast<float>(pdfGlyphWidth) / ftGlyphWidth;
        charpos.m_AdjustMatrix[0] = scalingFactor;
        charpos.m_AdjustMatrix[1] = 0.0f;
        charpos.m_AdjustMatrix[2] = 0.0f;
        charpos.m_AdjustMatrix[3] = 1.0f;
        charpos.m_bGlyphAdjust = true;
      }
    }
    if (!pCIDFont)
      continue;

    uint16_t CID = pCIDFont->CIDFromCharCode(CharCode);
    if (bVertWriting) {
      charpos.m_Origin = CFX_PointF(0, charpos.m_Origin.x);

      short vx;
      short vy;
      pCIDFont->GetVertOrigin(CID, vx, vy);
      charpos.m_Origin.x -= font_size * vx / 1000;
      charpos.m_Origin.y -= font_size * vy / 1000;
    }

    const uint8_t* pTransform = pCIDFont->GetCIDTransform(CID);
    if (pTransform && !bVert) {
      charpos.m_AdjustMatrix[0] =
          pCIDFont->CIDTransformToFloat(pTransform[0]) * scalingFactor;
      charpos.m_AdjustMatrix[1] =
          pCIDFont->CIDTransformToFloat(pTransform[1]) * scalingFactor;
      charpos.m_AdjustMatrix[2] = pCIDFont->CIDTransformToFloat(pTransform[2]);
      charpos.m_AdjustMatrix[3] = pCIDFont->CIDTransformToFloat(pTransform[3]);
      charpos.m_Origin.x +=
          pCIDFont->CIDTransformToFloat(pTransform[4]) * font_size;
      charpos.m_Origin.y +=
          pCIDFont->CIDTransformToFloat(pTransform[5]) * font_size;
      charpos.m_bGlyphAdjust = true;
    }
  }
}

CPDF_CharPosList::~CPDF_CharPosList() = default;

uint32_t CPDF_CharPosList::GetCount() const {
  return pdfium::CollectionSize<uint32_t>(m_CharPos);
}

const TextCharPos& CPDF_CharPosList::GetAt(size_t index) const {
  return m_CharPos[index];
}
