// 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 "xfa/fde/cfde_textout.h"

#include <algorithm>
#include <utility>

#include "core/fxcrt/fx_coordinates.h"
#include "core/fxcrt/fx_system.h"
#include "core/fxge/cfx_font.h"
#include "core/fxge/cfx_pathdata.h"
#include "third_party/base/ptr_util.h"
#include "third_party/base/stl_util.h"
#include "xfa/fgas/layout/cfx_txtbreak.h"

namespace {

bool TextAlignmentVerticallyCentered(const FDE_TextAlignment align) {
  return align == FDE_TextAlignment::kCenterLeft ||
         align == FDE_TextAlignment::kCenter ||
         align == FDE_TextAlignment::kCenterRight;
}

bool IsTextAlignmentTop(const FDE_TextAlignment align) {
  return align == FDE_TextAlignment::kTopLeft;
}

}  // namespace

// static
bool CFDE_TextOut::DrawString(CFX_RenderDevice* device,
                              FX_ARGB color,
                              const RetainPtr<CFGAS_GEFont>& pFont,
                              FXTEXT_CHARPOS* pCharPos,
                              int32_t iCount,
                              float fFontSize,
                              const CFX_Matrix* pMatrix) {
  ASSERT(pFont && pCharPos && iCount > 0);

  CFX_Font* pFxFont = pFont->GetDevFont();
  if (FontStyleIsItalic(pFont->GetFontStyles()) && !pFxFont->IsItalic()) {
    for (int32_t i = 0; i < iCount; ++i) {
      static const float mc = 0.267949f;
      float* pAM = pCharPos->m_AdjustMatrix;
      pAM[2] = mc * pAM[0] + pAM[2];
      pAM[3] = mc * pAM[1] + pAM[3];
      ++pCharPos;
    }
  }

#if _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_
  uint32_t dwFontStyle = pFont->GetFontStyles();
  CFX_Font FxFont;
  auto SubstFxFont = pdfium::MakeUnique<CFX_SubstFont>();
  SubstFxFont->m_Weight = FontStyleIsBold(dwFontStyle) ? 700 : 400;
  SubstFxFont->m_ItalicAngle = FontStyleIsItalic(dwFontStyle) ? -12 : 0;
  SubstFxFont->m_WeightCJK = SubstFxFont->m_Weight;
  SubstFxFont->m_bItalicCJK = FontStyleIsItalic(dwFontStyle);
  FxFont.SetSubstFont(std::move(SubstFxFont));
#endif  // _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_

  RetainPtr<CFGAS_GEFont> pCurFont;
  FXTEXT_CHARPOS* pCurCP = nullptr;
  int32_t iCurCount = 0;
  for (int32_t i = 0; i < iCount; ++i) {
    RetainPtr<CFGAS_GEFont> pSTFont =
        pFont->GetSubstFont(static_cast<int32_t>(pCharPos->m_GlyphIndex));
    pCharPos->m_GlyphIndex &= 0x00FFFFFF;
    pCharPos->m_bFontStyle = false;
    if (pCurFont != pSTFont) {
      if (pCurFont) {
        pFxFont = pCurFont->GetDevFont();

        CFX_Font* font;
#if _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_
        FxFont.SetFace(pFxFont->GetFace());
        font = &FxFont;
#else
        font = pFxFont;
#endif  // _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_

        device->DrawNormalText(iCurCount, pCurCP, font, -fFontSize, pMatrix,
                               color, FXTEXT_CLEARTYPE);
      }
      pCurFont = pSTFont;
      pCurCP = pCharPos;
      iCurCount = 1;
    } else {
      ++iCurCount;
    }
    ++pCharPos;
  }

  bool bRet = true;
  if (pCurFont && iCurCount) {
    pFxFont = pCurFont->GetDevFont();
    CFX_Font* font;
#if _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_
    FxFont.SetFace(pFxFont->GetFace());
    font = &FxFont;
#else
    font = pFxFont;
#endif  // _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_

    bRet = device->DrawNormalText(iCurCount, pCurCP, font, -fFontSize, pMatrix,
                                  color, FXTEXT_CLEARTYPE);
  }

#if _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_
  FxFont.SetFace(nullptr);
#endif  // _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_

  return bRet;
}

FDE_TTOPIECE::FDE_TTOPIECE() = default;

FDE_TTOPIECE::FDE_TTOPIECE(const FDE_TTOPIECE& that) = default;

FDE_TTOPIECE::~FDE_TTOPIECE() = default;

CFDE_TextOut::CFDE_TextOut()
    : m_pTxtBreak(pdfium::MakeUnique<CFX_TxtBreak>()),
      m_pFont(nullptr),
      m_fFontSize(12.0f),
      m_fLineSpace(m_fFontSize),
      m_fLinePos(0.0f),
      m_fTolerance(0.0f),
      m_iAlignment(FDE_TextAlignment::kTopLeft),
      m_TxtColor(0xFF000000),
      m_dwTxtBkStyles(0),
      m_ttoLines(5),
      m_iCurLine(0),
      m_iCurPiece(0),
      m_iTotalLines(0) {}

CFDE_TextOut::~CFDE_TextOut() {}

void CFDE_TextOut::SetFont(const RetainPtr<CFGAS_GEFont>& pFont) {
  ASSERT(pFont);
  m_pFont = pFont;
  m_pTxtBreak->SetFont(pFont);
}

void CFDE_TextOut::SetFontSize(float fFontSize) {
  ASSERT(fFontSize > 0);
  m_fFontSize = fFontSize;
  m_pTxtBreak->SetFontSize(fFontSize);
}

void CFDE_TextOut::SetStyles(const FDE_TextStyle& dwStyles) {
  m_Styles = dwStyles;

  m_dwTxtBkStyles = 0;
  if (m_Styles.single_line_)
    m_dwTxtBkStyles |= FX_LAYOUTSTYLE_SingleLine;

  m_pTxtBreak->SetLayoutStyles(m_dwTxtBkStyles);
}

void CFDE_TextOut::SetAlignment(FDE_TextAlignment iAlignment) {
  m_iAlignment = iAlignment;

  int32_t txtBreakAlignment = 0;
  switch (m_iAlignment) {
    case FDE_TextAlignment::kCenter:
      txtBreakAlignment = CFX_TxtLineAlignment_Center;
      break;
    case FDE_TextAlignment::kCenterRight:
      txtBreakAlignment = CFX_TxtLineAlignment_Right;
      break;
    case FDE_TextAlignment::kCenterLeft:
    case FDE_TextAlignment::kTopLeft:
      txtBreakAlignment = CFX_TxtLineAlignment_Left;
      break;
  }
  m_pTxtBreak->SetAlignment(txtBreakAlignment);
}

void CFDE_TextOut::SetLineSpace(float fLineSpace) {
  ASSERT(fLineSpace > 1.0f);
  m_fLineSpace = fLineSpace;
}

void CFDE_TextOut::SetLineBreakTolerance(float fTolerance) {
  m_fTolerance = fTolerance;
  m_pTxtBreak->SetLineBreakTolerance(m_fTolerance);
}

void CFDE_TextOut::CalcLogicSize(const WideString& str, CFX_SizeF& size) {
  CFX_RectF rtText(0.0f, 0.0f, size.width, size.height);
  CalcLogicSize(str, rtText);
  size = rtText.Size();
}

void CFDE_TextOut::CalcLogicSize(const WideString& str, CFX_RectF& rect) {
  if (str.IsEmpty()) {
    rect.width = 0.0f;
    rect.height = 0.0f;
    return;
  }

  ASSERT(m_pFont && m_fFontSize >= 1.0f);

  if (!m_Styles.single_line_) {
    if (rect.Width() < 1.0f)
      rect.width = m_fFontSize * 1000.0f;

    m_pTxtBreak->SetLineWidth(rect.Width());
  }

  m_iTotalLines = 0;
  float fWidth = 0.0f;
  float fHeight = 0.0f;
  float fStartPos = rect.right();
  CFX_BreakType dwBreakStatus = CFX_BreakType::None;
  bool break_char_is_set = false;
  for (const wchar_t& wch : str) {
    if (!break_char_is_set && (wch == L'\n' || wch == L'\r')) {
      break_char_is_set = true;
      m_pTxtBreak->SetParagraphBreakChar(wch);
    }
    dwBreakStatus = m_pTxtBreak->AppendChar(wch);
    if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus))
      RetrieveLineWidth(dwBreakStatus, fStartPos, fWidth, fHeight);
  }

  dwBreakStatus = m_pTxtBreak->EndBreak(CFX_BreakType::Paragraph);
  if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus))
    RetrieveLineWidth(dwBreakStatus, fStartPos, fWidth, fHeight);

  m_pTxtBreak->Reset();
  float fInc = rect.Height() - fHeight;
  if (TextAlignmentVerticallyCentered(m_iAlignment))
    fInc /= 2.0f;
  else if (IsTextAlignmentTop(m_iAlignment))
    fInc = 0.0f;

  rect.left += fStartPos;
  rect.top += fInc;
  rect.width = std::min(fWidth, rect.Width());
  rect.height = fHeight;
  if (m_Styles.last_line_height_)
    rect.height -= m_fLineSpace - m_fFontSize;
}

bool CFDE_TextOut::RetrieveLineWidth(CFX_BreakType dwBreakStatus,
                                     float& fStartPos,
                                     float& fWidth,
                                     float& fHeight) {
  if (CFX_BreakTypeNoneOrPiece(dwBreakStatus))
    return false;

  float fLineStep = (m_fLineSpace > m_fFontSize) ? m_fLineSpace : m_fFontSize;
  float fLineWidth = 0.0f;
  for (int32_t i = 0; i < m_pTxtBreak->CountBreakPieces(); i++) {
    const CFX_BreakPiece* pPiece = m_pTxtBreak->GetBreakPieceUnstable(i);
    fLineWidth += static_cast<float>(pPiece->m_iWidth) / 20000.0f;
    fStartPos =
        std::min(fStartPos, static_cast<float>(pPiece->m_iStartPos) / 20000.0f);
  }
  m_pTxtBreak->ClearBreakPieces();

  if (dwBreakStatus == CFX_BreakType::Paragraph)
    m_pTxtBreak->Reset();
  if (!m_Styles.line_wrap_ && dwBreakStatus == CFX_BreakType::Line) {
    fWidth += fLineWidth;
  } else {
    fWidth = std::max(fWidth, fLineWidth);
    fHeight += fLineStep;
  }
  ++m_iTotalLines;
  return true;
}

void CFDE_TextOut::DrawLogicText(CFX_RenderDevice* device,
                                 const WideStringView& str,
                                 const CFX_RectF& rect) {
  ASSERT(m_pFont && m_fFontSize >= 1.0f);

  if (str.IsEmpty())
    return;
  if (rect.width < m_fFontSize || rect.height < m_fFontSize)
    return;

  float fLineWidth = rect.width;
  m_pTxtBreak->SetLineWidth(fLineWidth);
  m_ttoLines.clear();
  m_wsText.clear();

  LoadText(WideString(str), rect);
  Reload(rect);
  DoAlignment(rect);

  if (!device || m_ttoLines.empty())
    return;

  CFX_RectF rtClip = m_Matrix.TransformRect(CFX_RectF());
  device->SaveState();
  if (rtClip.Width() > 0.0f && rtClip.Height() > 0.0f)
    device->SetClip_Rect(rtClip);

  for (auto& line : m_ttoLines) {
    int32_t iPieces = line.GetSize();
    for (int32_t j = 0; j < iPieces; j++) {
      FDE_TTOPIECE* pPiece = line.GetPtrAt(j);
      if (!pPiece)
        continue;

      int32_t iCount = GetDisplayPos(pPiece);
      if (iCount > 0) {
        CFDE_TextOut::DrawString(device, m_TxtColor, m_pFont, m_CharPos.data(),
                                 iCount, m_fFontSize, &m_Matrix);
      }
    }
  }
  device->RestoreState(false);
}

void CFDE_TextOut::LoadText(const WideString& str, const CFX_RectF& rect) {
  ASSERT(!str.IsEmpty());

  m_wsText = str;

  if (pdfium::CollectionSize<size_t>(m_CharWidths) < str.GetLength())
    m_CharWidths.resize(str.GetLength(), 0);

  float fLineStep = (m_fLineSpace > m_fFontSize) ? m_fLineSpace : m_fFontSize;
  float fLineStop = rect.bottom();
  m_fLinePos = rect.top;
  int32_t iStartChar = 0;
  int32_t iPieceWidths = 0;
  CFX_BreakType dwBreakStatus;
  bool bRet = false;
  for (const auto& wch : str) {
    dwBreakStatus = m_pTxtBreak->AppendChar(wch);
    if (CFX_BreakTypeNoneOrPiece(dwBreakStatus))
      continue;

    bool bEndofLine =
        RetrievePieces(dwBreakStatus, iStartChar, iPieceWidths, false, rect);
    if (bEndofLine &&
        (m_Styles.line_wrap_ || dwBreakStatus == CFX_BreakType::Paragraph ||
         dwBreakStatus == CFX_BreakType::Page)) {
      iPieceWidths = 0;
      ++m_iCurLine;
      m_fLinePos += fLineStep;
    }
    if (m_fLinePos + fLineStep > fLineStop) {
      int32_t iCurLine = bEndofLine ? m_iCurLine - 1 : m_iCurLine;
      m_ttoLines[iCurLine].SetNewReload(true);
      bRet = true;
      break;
    }
  }

  dwBreakStatus = m_pTxtBreak->EndBreak(CFX_BreakType::Paragraph);
  if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus) && !bRet)
    RetrievePieces(dwBreakStatus, iStartChar, iPieceWidths, false, rect);

  m_pTxtBreak->ClearBreakPieces();
  m_pTxtBreak->Reset();
}

bool CFDE_TextOut::RetrievePieces(CFX_BreakType dwBreakStatus,
                                  int32_t& iStartChar,
                                  int32_t& iPieceWidths,
                                  bool bReload,
                                  const CFX_RectF& rect) {
  float fLineStep = (m_fLineSpace > m_fFontSize) ? m_fLineSpace : m_fFontSize;
  bool bNeedReload = false;
  int32_t iLineWidth = FXSYS_round(rect.Width() * 20000.0f);
  int32_t iCount = m_pTxtBreak->CountBreakPieces();
  for (int32_t i = 0; i < iCount; i++) {
    const CFX_BreakPiece* pPiece = m_pTxtBreak->GetBreakPieceUnstable(i);
    int32_t iPieceChars = pPiece->GetLength();
    int32_t iChar = iStartChar;
    int32_t iWidth = 0;
    int32_t j = 0;
    for (; j < iPieceChars; j++) {
      const CFX_Char* pTC = pPiece->GetChar(j);
      int32_t iCurCharWidth = pTC->m_iCharWidth > 0 ? pTC->m_iCharWidth : 0;
      if (m_Styles.single_line_ || !m_Styles.line_wrap_) {
        if (iLineWidth - iPieceWidths - iWidth < iCurCharWidth) {
          bNeedReload = true;
          break;
        }
      }
      iWidth += iCurCharWidth;
      m_CharWidths[iChar++] = iCurCharWidth;
    }

    if (j == 0 && !bReload) {
      m_ttoLines[m_iCurLine].SetNewReload(true);
    } else if (j > 0) {
      FDE_TTOPIECE ttoPiece;
      ttoPiece.iStartChar = iStartChar;
      ttoPiece.iChars = j;
      ttoPiece.dwCharStyles = pPiece->m_dwCharStyles;
      ttoPiece.rtPiece = CFX_RectF(
          rect.left + static_cast<float>(pPiece->m_iStartPos) / 20000.0f,
          m_fLinePos, iWidth / 20000.0f, fLineStep);

      if (FX_IsOdd(pPiece->m_iBidiLevel))
        ttoPiece.dwCharStyles |= FX_TXTCHARSTYLE_OddBidiLevel;

      AppendPiece(ttoPiece, bNeedReload, (bReload && i == iCount - 1));
    }
    iStartChar += iPieceChars;
    iPieceWidths += iWidth;
  }
  m_pTxtBreak->ClearBreakPieces();

  return m_Styles.single_line_ || m_Styles.line_wrap_ || bNeedReload ||
         dwBreakStatus == CFX_BreakType::Paragraph;
}

void CFDE_TextOut::AppendPiece(const FDE_TTOPIECE& ttoPiece,
                               bool bNeedReload,
                               bool bEnd) {
  if (m_iCurLine >= pdfium::CollectionSize<int32_t>(m_ttoLines)) {
    CFDE_TTOLine ttoLine;
    ttoLine.SetNewReload(bNeedReload);

    m_iCurPiece = ttoLine.AddPiece(m_iCurPiece, ttoPiece);
    m_ttoLines.push_back(ttoLine);
    m_iCurLine = pdfium::CollectionSize<int32_t>(m_ttoLines) - 1;
  } else {
    CFDE_TTOLine* pLine = &m_ttoLines[m_iCurLine];
    pLine->SetNewReload(bNeedReload);

    m_iCurPiece = pLine->AddPiece(m_iCurPiece, ttoPiece);
    if (bEnd) {
      int32_t iPieces = pLine->GetSize();
      if (m_iCurPiece < iPieces)
        pLine->RemoveLast(iPieces - m_iCurPiece - 1);
    }
  }
  if (!bEnd && bNeedReload)
    m_iCurPiece = 0;
}

void CFDE_TextOut::Reload(const CFX_RectF& rect) {
  int i = 0;
  for (auto& line : m_ttoLines) {
    if (line.GetNewReload()) {
      m_iCurLine = i;
      m_iCurPiece = 0;
      ReloadLinePiece(&line, rect);
    }
    ++i;
  }
}

void CFDE_TextOut::ReloadLinePiece(CFDE_TTOLine* pLine, const CFX_RectF& rect) {
  const wchar_t* pwsStr = m_wsText.c_str();
  int32_t iPieceWidths = 0;

  FDE_TTOPIECE* pPiece = pLine->GetPtrAt(0);
  int32_t iStartChar = pPiece->iStartChar;
  int32_t iPieceCount = pLine->GetSize();
  int32_t iPieceIndex = 0;
  CFX_BreakType dwBreakStatus = CFX_BreakType::None;
  m_fLinePos = pPiece->rtPiece.top;
  while (iPieceIndex < iPieceCount) {
    int32_t iStar = iStartChar;
    int32_t iEnd = pPiece->iChars + iStar;
    while (iStar < iEnd) {
      dwBreakStatus = m_pTxtBreak->AppendChar(*(pwsStr + iStar));
      if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus))
        RetrievePieces(dwBreakStatus, iStartChar, iPieceWidths, true, rect);

      ++iStar;
    }
    ++iPieceIndex;
    pPiece = pLine->GetPtrAt(iPieceIndex);
  }

  dwBreakStatus = m_pTxtBreak->EndBreak(CFX_BreakType::Paragraph);
  if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus))
    RetrievePieces(dwBreakStatus, iStartChar, iPieceWidths, true, rect);

  m_pTxtBreak->Reset();
}

void CFDE_TextOut::DoAlignment(const CFX_RectF& rect) {
  if (m_ttoLines.empty())
    return;

  FDE_TTOPIECE* pFirstPiece = m_ttoLines.back().GetPtrAt(0);
  if (!pFirstPiece)
    return;

  float fInc = rect.bottom() - pFirstPiece->rtPiece.bottom();
  if (TextAlignmentVerticallyCentered(m_iAlignment))
    fInc /= 2.0f;
  else if (IsTextAlignmentTop(m_iAlignment))
    fInc = 0.0f;

  if (fInc < 1.0f)
    return;

  for (auto& line : m_ttoLines) {
    int32_t iPieces = line.GetSize();
    for (int32_t j = 0; j < iPieces; j++)
      line.GetPtrAt(j)->rtPiece.top += fInc;
  }
}

int32_t CFDE_TextOut::GetDisplayPos(FDE_TTOPIECE* pPiece) {
  ASSERT(pPiece->iChars >= 0);

  if (pdfium::CollectionSize<int32_t>(m_CharPos) < pPiece->iChars)
    m_CharPos.resize(pPiece->iChars, FXTEXT_CHARPOS());

  FX_TXTRUN tr;
  tr.wsStr = m_wsText + pPiece->iStartChar;
  tr.pWidths = &m_CharWidths[pPiece->iStartChar];
  tr.iLength = pPiece->iChars;
  tr.pFont = m_pFont;
  tr.fFontSize = m_fFontSize;
  tr.dwStyles = m_dwTxtBkStyles;
  tr.dwCharStyles = pPiece->dwCharStyles;
  tr.pRect = &pPiece->rtPiece;

  return m_pTxtBreak->GetDisplayPos(&tr, m_CharPos.data());
}

CFDE_TTOLine::CFDE_TTOLine() : m_bNewReload(false) {}

CFDE_TTOLine::CFDE_TTOLine(const CFDE_TTOLine& ttoLine) : m_pieces(5) {
  m_bNewReload = ttoLine.m_bNewReload;
  m_pieces = ttoLine.m_pieces;
}

CFDE_TTOLine::~CFDE_TTOLine() {}

int32_t CFDE_TTOLine::AddPiece(int32_t index, const FDE_TTOPIECE& ttoPiece) {
  if (index >= pdfium::CollectionSize<int32_t>(m_pieces)) {
    m_pieces.push_back(ttoPiece);
    return pdfium::CollectionSize<int32_t>(m_pieces);
  }
  m_pieces[index] = ttoPiece;
  return index;
}

int32_t CFDE_TTOLine::GetSize() const {
  return pdfium::CollectionSize<int32_t>(m_pieces);
}

FDE_TTOPIECE* CFDE_TTOLine::GetPtrAt(int32_t index) {
  return pdfium::IndexInBounds(m_pieces, index) ? &m_pieces[index] : nullptr;
}

void CFDE_TTOLine::RemoveLast(int32_t icount) {
  if (icount < 0)
    return;
  m_pieces.erase(
      m_pieces.end() -
          std::min(icount, pdfium::CollectionSize<int32_t>(m_pieces)),
      m_pieces.end());
}
