// 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->weight_ = FontStyleIsForceBold(dwFontStyle) ? 700 : 400;
  SubstFxFont->italic_angle_ = FontStyleIsItalic(dwFontStyle) ? -12 : 0;
  SubstFxFont->weight_cjk_ = SubstFxFont->weight_;
  SubstFxFont->italic_cjk_ = 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.font_style_ = false;
    if (pCurFont != pSTFont) {
      if (pCurFont) {
        pFxFont = pCurFont->GetDevFont();

        CFX_Font* font;
#if !BUILDFLAG(IS_WIN)
        FxFont.SetFace(pFxFont->GetFace());
        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.SetFace(pFxFont->GetFace());
    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(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(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(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(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
