// Copyright 2014 The PDFium Authors
// 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 "build/build_config.h"
#include "core/fxcrt/check.h"
#include "core/fxcrt/check_op.h"
#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/fx_coordinates.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_system.h"
#include "core/fxcrt/numerics/safe_conversions.h"
#include "core/fxcrt/stl_util.h"
#include "core/fxge/cfx_font.h"
#include "core/fxge/cfx_path.h"
#include "core/fxge/cfx_renderdevice.h"
#include "core/fxge/cfx_substfont.h"
#include "core/fxge/cfx_textrenderoptions.h"
#include "core/fxge/fx_font.h"
#include "core/fxge/text_char_pos.h"
#include "xfa/fgas/font/cfgas_gefont.h"
#include "xfa/fgas/layout/cfgas_txtbreak.h"

namespace pdfium {

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,
                              span<TextCharPos> pCharPos,
                              float fFontSize,
                              const CFX_Matrix& matrix) {
  DCHECK(pFont);
  DCHECK(!pCharPos.empty());

  CFX_Font* pFxFont = pFont->GetDevFont();
  if (FontStyleIsItalic(pFont->GetFontStyles()) && !pFxFont->IsItalic()) {
    for (auto& pos : pCharPos) {
      static constexpr float mc = 0.267949f;
      pos.adjust_matrix_[2] += mc * pos.adjust_matrix_[0];
      pos.adjust_matrix_[3] += mc * pos.adjust_matrix_[1];
    }
  }

#if !BUILDFLAG(IS_WIN)
  uint32_t dwFontStyle = pFont->GetFontStyles();
  CFX_Font FxFont;
  auto SubstFxFont = std::make_unique<CFX_SubstFont>();
  SubstFxFont->SetWeight(FontStyleIsForceBold(dwFontStyle) ? 700 : 400);
  SubstFxFont->SetItalicAngle(FontStyleIsItalic(dwFontStyle) ? -12 : 0);
  SubstFxFont->SetWeightCJK(SubstFxFont->GetWeight());
  SubstFxFont->SetItalicCJK(FontStyleIsItalic(dwFontStyle));
  FxFont.SetSubstFont(std::move(SubstFxFont));
#endif

  RetainPtr<CFGAS_GEFont> pCurFont;
  TextCharPos* pCurCP = nullptr;
  size_t count = 0;
  static constexpr CFX_TextRenderOptions kOptions(CFX_TextRenderOptions::kLcd);
  for (auto& pos : pCharPos) {
    RetainPtr<CFGAS_GEFont> pSTFont =
        pFont->GetSubstFont(static_cast<int32_t>(pos.glyph_index_));
    pos.glyph_index_ &= 0x00FFFFFF;
    pos.is_cid_font_ = false;
    if (pCurFont != pSTFont) {
      if (pCurFont) {
        pFxFont = pCurFont->GetDevFont();

        CFX_Font* font;
#if !BUILDFLAG(IS_WIN)
        FxFont.SetFaceFromFont(*pFxFont);
        FxFont.SetFontSpan(pFxFont->GetFontSpan());
        font = &FxFont;
#else
        font = pFxFont;
#endif
        device->DrawNormalText(UNSAFE_TODO(pdfium::span(pCurCP, count)), font,
                               -fFontSize, matrix, color, kOptions);
      }
      pCurFont = pSTFont;
      pCurCP = &pos;
      count = 1;
    } else {
      ++count;
    }
  }
  if (pCurFont && count) {
    pFxFont = pCurFont->GetDevFont();
    CFX_Font* font;
#if !BUILDFLAG(IS_WIN)
    FxFont.SetFaceFromFont(*pFxFont);
    FxFont.SetFontSpan(pFxFont->GetFontSpan());
    font = &FxFont;
#else
    font = pFxFont;
#endif
    return device->DrawNormalText(UNSAFE_TODO(pdfium::span(pCurCP, count)),
                                  font, -fFontSize, matrix, color, kOptions);
  }
  return true;
}

CFDE_TextOut::Piece::Piece() = default;

CFDE_TextOut::Piece::Piece(const Piece& that) = default;

CFDE_TextOut::Piece::~Piece() = default;

CFDE_TextOut::CFDE_TextOut() : txt_break_(std::make_unique<CFGAS_TxtBreak>()) {}

CFDE_TextOut::~CFDE_TextOut() = default;

void CFDE_TextOut::SetFont(RetainPtr<CFGAS_GEFont> pFont) {
  DCHECK(pFont);
  font_ = std::move(pFont);
  txt_break_->SetFont(font_);
}

void CFDE_TextOut::SetFontSize(float fFontSize) {
  DCHECK_GT(fFontSize, 0);
  font_size_ = fFontSize;
  txt_break_->SetFontSize(fFontSize);
}

void CFDE_TextOut::SetStyles(const FDE_TextStyle& dwStyles) {
  styles_ = dwStyles;
  txt_bk_styles_ = styles_.single_line_ ? CFGAS_Break::LayoutStyle::kSingleLine
                                        : CFGAS_Break::LayoutStyle::kNone;

  txt_break_->SetLayoutStyles(txt_bk_styles_);
}

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

  int32_t txtBreakAlignment = 0;
  switch (alignment_) {
    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;
  }
  txt_break_->SetAlignment(txtBreakAlignment);
}

void CFDE_TextOut::SetLineSpace(float fLineSpace) {
  DCHECK_GT(fLineSpace, 1.0f);
  line_space_ = fLineSpace;
}

void CFDE_TextOut::SetLineBreakTolerance(float fTolerance) {
  tolerance_ = fTolerance;
  txt_break_->SetLineBreakTolerance(tolerance_);
}

void CFDE_TextOut::CalcLogicSize(WideStringView str, CFX_SizeF* pSize) {
  CFX_RectF rtText(0.0f, 0.0f, pSize->width, pSize->height);
  CalcLogicSize(str, &rtText);
  *pSize = rtText.Size();
}

void CFDE_TextOut::CalcLogicSize(WideStringView str, CFX_RectF* pRect) {
  if (str.IsEmpty()) {
    pRect->width = 0.0f;
    pRect->height = 0.0f;
    return;
  }

  DCHECK(font_);
  DCHECK_GE(font_size_, 1.0f);

  if (!styles_.single_line_) {
    if (pRect->Width() < 1.0f) {
      pRect->width = font_size_ * 1000.0f;
    }

    txt_break_->SetLineWidth(pRect->Width());
  }

  total_lines_ = 0;
  float fWidth = 0.0f;
  float fHeight = 0.0f;
  float fStartPos = pRect->right();
  CFGAS_Char::BreakType dwBreakStatus = CFGAS_Char::BreakType::kNone;
  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;
      txt_break_->SetParagraphBreakChar(wch);
    }
    dwBreakStatus = txt_break_->AppendChar(wch);
    if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus)) {
      RetrieveLineWidth(dwBreakStatus, &fStartPos, &fWidth, &fHeight);
    }
  }

  dwBreakStatus = txt_break_->EndBreak(CFGAS_Char::BreakType::kParagraph);
  if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus)) {
    RetrieveLineWidth(dwBreakStatus, &fStartPos, &fWidth, &fHeight);
  }

  txt_break_->Reset();
  float fInc = pRect->Height() - fHeight;
  if (TextAlignmentVerticallyCentered(alignment_)) {
    fInc /= 2.0f;
  } else if (IsTextAlignmentTop(alignment_)) {
    fInc = 0.0f;
  }

  pRect->left += fStartPos;
  pRect->top += fInc;
  pRect->width = std::min(fWidth, pRect->Width());
  pRect->height = fHeight;
  if (styles_.last_line_height_) {
    pRect->height -= line_space_ - font_size_;
  }
}

bool CFDE_TextOut::RetrieveLineWidth(CFGAS_Char::BreakType dwBreakStatus,
                                     float* pStartPos,
                                     float* pWidth,
                                     float* pHeight) {
  if (CFX_BreakTypeNoneOrPiece(dwBreakStatus)) {
    return false;
  }

  float fLineStep = std::max(line_space_, font_size_);
  float fLineWidth = 0.0f;
  for (int32_t i = 0; i < txt_break_->CountBreakPieces(); i++) {
    const CFGAS_BreakPiece* pPiece = txt_break_->GetBreakPieceUnstable(i);
    fLineWidth += static_cast<float>(pPiece->GetWidth()) / 20000.0f;
    *pStartPos = std::min(*pStartPos,
                          static_cast<float>(pPiece->GetStartPos()) / 20000.0f);
  }
  txt_break_->ClearBreakPieces();

  if (dwBreakStatus == CFGAS_Char::BreakType::kParagraph) {
    txt_break_->Reset();
  }
  if (!styles_.line_wrap_ && dwBreakStatus == CFGAS_Char::BreakType::kLine) {
    *pWidth += fLineWidth;
  } else {
    *pWidth = std::max(*pWidth, fLineWidth);
    *pHeight += fLineStep;
  }
  ++total_lines_;
  return true;
}

void CFDE_TextOut::DrawLogicText(CFX_RenderDevice* device,
                                 const WideString& str,
                                 const CFX_RectF& rect) {
  DCHECK(font_);
  DCHECK_GE(font_size_, 1.0f);

  if (str.IsEmpty()) {
    return;
  }
  if (rect.width < font_size_ || rect.height < font_size_) {
    return;
  }

  float fLineWidth = rect.width;
  txt_break_->SetLineWidth(fLineWidth);
  tto_lines_.clear();
  text_.clear();

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

  if (!device || tto_lines_.empty()) {
    return;
  }

  CFX_RectF rtClip = matrix_.TransformRect(CFX_RectF());
  device->SaveState();
  if (rtClip.Width() > 0.0f && rtClip.Height() > 0.0f) {
    device->SetClip_Rect(rtClip.GetOuterRect());
  }

  for (auto& line : tto_lines_) {
    for (size_t i = 0; i < line.GetSize(); ++i) {
      const Piece* pPiece = line.GetPieceAtIndex(i);
      size_t szCount = GetDisplayPos(pPiece);
      if (szCount == 0) {
        continue;
      }
      CFDE_TextOut::DrawString(device, txt_color_, font_,
                               pdfium::span(char_pos_).first(szCount),
                               font_size_, matrix_);
    }
  }
  device->RestoreState(false);
}

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

  text_ = str;

  if (char_widths_.size() < str.GetLength()) {
    char_widths_.resize(str.GetLength(), 0);
  }

  float fLineStep = std::max(line_space_, font_size_);
  float fLineStop = rect.bottom();
  line_pos_ = rect.top;
  size_t start_char = 0;
  int32_t iPieceWidths = 0;
  CFGAS_Char::BreakType dwBreakStatus;
  bool bRet = false;
  for (const auto& wch : str) {
    dwBreakStatus = txt_break_->AppendChar(wch);
    if (CFX_BreakTypeNoneOrPiece(dwBreakStatus)) {
      continue;
    }

    bool bEndofLine =
        RetrievePieces(dwBreakStatus, false, rect, &start_char, &iPieceWidths);
    if (bEndofLine && (styles_.line_wrap_ ||
                       dwBreakStatus == CFGAS_Char::BreakType::kParagraph ||
                       dwBreakStatus == CFGAS_Char::BreakType::kPage)) {
      iPieceWidths = 0;
      ++cur_line_;
      line_pos_ += fLineStep;
    }
    if (line_pos_ + fLineStep > fLineStop) {
      size_t iCurLine = bEndofLine ? cur_line_ - 1 : cur_line_;
      CHECK_LT(cur_line_, tto_lines_.size());
      tto_lines_[iCurLine].set_new_reload(true);
      bRet = true;
      break;
    }
  }

  dwBreakStatus = txt_break_->EndBreak(CFGAS_Char::BreakType::kParagraph);
  if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus) && !bRet) {
    RetrievePieces(dwBreakStatus, false, rect, &start_char, &iPieceWidths);
  }

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

bool CFDE_TextOut::RetrievePieces(CFGAS_Char::BreakType dwBreakStatus,
                                  bool bReload,
                                  const CFX_RectF& rect,
                                  size_t* pStartChar,
                                  int32_t* pPieceWidths) {
  float fLineStep = std::max(line_space_, font_size_);
  bool bNeedReload = false;
  int32_t iLineWidth = FXSYS_roundf(rect.Width() * 20000.0f);
  int32_t iCount = txt_break_->CountBreakPieces();

  size_t chars_to_skip = *pStartChar;
  for (int32_t i = 0; i < iCount; i++) {
    const CFGAS_BreakPiece* pPiece = txt_break_->GetBreakPieceUnstable(i);
    size_t iPieceChars = pPiece->GetLength();
    if (chars_to_skip > iPieceChars) {
      chars_to_skip -= iPieceChars;
      continue;
    }

    size_t iChar = *pStartChar;
    int32_t iWidth = 0;
    size_t j = chars_to_skip;
    for (; j < iPieceChars; j++) {
      const CFGAS_Char* pTC = pPiece->GetChar(j);
      int32_t iCurCharWidth = std::max(pTC->char_width_, 0);
      if (styles_.single_line_ || !styles_.line_wrap_) {
        if (iLineWidth - *pPieceWidths - iWidth < iCurCharWidth) {
          bNeedReload = true;
          break;
        }
      }
      iWidth += iCurCharWidth;
      char_widths_[iChar++] = iCurCharWidth;
    }

    if (j == chars_to_skip && !bReload) {
      CHECK_LT(cur_line_, tto_lines_.size());
      tto_lines_[cur_line_].set_new_reload(true);
    } else if (j > chars_to_skip) {
      Piece piece;
      piece.start_char = *pStartChar;
      piece.char_count = j - chars_to_skip;
      piece.char_styles = pPiece->GetCharStyles();
      piece.bounds = CFX_RectF(
          rect.left + static_cast<float>(pPiece->GetStartPos()) / 20000.0f,
          line_pos_, iWidth / 20000.0f, fLineStep);

      if (FX_IsOdd(pPiece->GetBidiLevel())) {
        piece.char_styles |= FX_TXTCHARSTYLE_OddBidiLevel;
      }

      AppendPiece(piece, bNeedReload, (bReload && i == iCount - 1));
    }
    *pStartChar += iPieceChars;
    *pPieceWidths += iWidth;
  }
  txt_break_->ClearBreakPieces();

  return styles_.single_line_ || styles_.line_wrap_ || bNeedReload ||
         dwBreakStatus == CFGAS_Char::BreakType::kParagraph;
}

void CFDE_TextOut::AppendPiece(const Piece& piece,
                               bool bNeedReload,
                               bool bEnd) {
  if (cur_line_ >= tto_lines_.size()) {
    Line ttoLine;
    ttoLine.set_new_reload(bNeedReload);

    cur_piece_ = ttoLine.AddPiece(cur_piece_, piece);
    tto_lines_.push_back(ttoLine);
    cur_line_ = tto_lines_.size() - 1;
  } else {
    Line* pLine = &tto_lines_[cur_line_];
    pLine->set_new_reload(bNeedReload);

    cur_piece_ = pLine->AddPiece(cur_piece_, piece);
    if (bEnd) {
      size_t iPieces = pLine->GetSize();
      if (cur_piece_ < iPieces) {
        pLine->RemoveLast(iPieces - cur_piece_ - 1);
      }
    }
  }
  if (!bEnd && bNeedReload) {
    cur_piece_ = 0;
  }
}

void CFDE_TextOut::Reload(const CFX_RectF& rect) {
  size_t i = 0;
  for (auto& line : tto_lines_) {
    if (line.new_reload()) {
      cur_line_ = i;
      cur_piece_ = 0;
      ReloadLinePiece(&line, rect);
    }
    ++i;
  }
}

void CFDE_TextOut::ReloadLinePiece(Line* line, const CFX_RectF& rect) {
  span<const wchar_t> text_span = text_.span();
  size_t start_char = 0;
  size_t piece_count = line->GetSize();
  int32_t piece_widths = 0;
  CFGAS_Char::BreakType break_status = CFGAS_Char::BreakType::kNone;
  for (size_t piece_index = 0; piece_index < piece_count; ++piece_index) {
    const Piece* piece = line->GetPieceAtIndex(piece_index);
    if (piece_index == 0) {
      line_pos_ = piece->bounds.top;
    }

    start_char = piece->start_char;
    const size_t end = piece->start_char + piece->char_count;
    for (size_t char_index = start_char; char_index < end; ++char_index) {
      break_status = txt_break_->AppendChar(text_span[char_index]);
      if (!CFX_BreakTypeNoneOrPiece(break_status)) {
        RetrievePieces(break_status, true, rect, &start_char, &piece_widths);
      }
    }
  }

  break_status = txt_break_->EndBreak(CFGAS_Char::BreakType::kParagraph);
  if (!CFX_BreakTypeNoneOrPiece(break_status)) {
    RetrievePieces(break_status, true, rect, &start_char, &piece_widths);
  }

  txt_break_->Reset();
}

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

  const Piece* pFirstPiece = tto_lines_.back().GetPieceAtIndex(0);
  if (!pFirstPiece) {
    return;
  }

  float fInc = rect.bottom() - pFirstPiece->bounds.bottom();
  if (TextAlignmentVerticallyCentered(alignment_)) {
    fInc /= 2.0f;
  } else if (IsTextAlignmentTop(alignment_)) {
    fInc = 0.0f;
  }

  if (fInc < 1.0f) {
    return;
  }

  for (auto& line : tto_lines_) {
    for (size_t i = 0; i < line.GetSize(); ++i) {
      line.GetPieceAtIndex(i)->bounds.top += fInc;
    }
  }
}

size_t CFDE_TextOut::GetDisplayPos(const Piece* pPiece) {
  if (char_pos_.size() < pPiece->char_count) {
    char_pos_.resize(pPiece->char_count, TextCharPos());
  }

  CFGAS_TxtBreak::Run tr;
  tr.wsStr = text_.Substr(pPiece->start_char);
  tr.pWidths = pdfium::span(char_widths_).subspan(pPiece->start_char);
  tr.iLength = checked_cast<int32_t>(pPiece->char_count);
  tr.font = font_;
  tr.fFontSize = font_size_;
  tr.dwStyles = txt_bk_styles_;
  tr.dwCharStyles = pPiece->char_styles;
  tr.pRect = &pPiece->bounds;

  return txt_break_->GetDisplayPos(tr, char_pos_);
}

CFDE_TextOut::Line::Line() = default;

CFDE_TextOut::Line::Line(const Line& that) = default;

CFDE_TextOut::Line::~Line() = default;

size_t CFDE_TextOut::Line::AddPiece(size_t index, const Piece& piece) {
  if (index >= pieces_.size()) {
    pieces_.push_back(piece);
    return pieces_.size();
  }
  pieces_[index] = piece;
  return index;
}

size_t CFDE_TextOut::Line::GetSize() const {
  return pieces_.size();
}

const CFDE_TextOut::Piece* CFDE_TextOut::Line::GetPieceAtIndex(
    size_t index) const {
  CHECK(fxcrt::IndexInBounds(pieces_, index));
  return &pieces_[index];
}

CFDE_TextOut::Piece* CFDE_TextOut::Line::GetPieceAtIndex(size_t index) {
  CHECK(fxcrt::IndexInBounds(pieces_, index));
  return &pieces_[index];
}

void CFDE_TextOut::Line::RemoveLast(size_t count) {
  pieces_.erase(pieces_.end() - std::min(count, pieces_.size()), pieces_.end());
}

}  // namespace pdfium
