// 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 <cctype>
#include <cwctype>
#include <memory>
#include <vector>

#include "core/include/fpdfapi/fpdf_page.h"
#include "core/include/fpdfapi/fpdf_pageobj.h"
#include "core/include/fpdfapi/fpdf_resource.h"
#include "core/include/fpdftext/fpdf_text.h"
#include "core/include/fxcrt/fx_bidi.h"
#include "core/include/fxcrt/fx_ucd.h"
#include "core/src/fpdftext/text_int.h"
#include "core/src/fpdftext/txtproc.h"
#include "third_party/base/stl_util.h"

CFX_ByteString CharFromUnicodeAlt(FX_WCHAR unicode,
                                  int destcp,
                                  const FX_CHAR* defchar) {
  if (destcp == 0) {
    if (unicode < 0x80) {
      return CFX_ByteString((char)unicode);
    }
    const FX_CHAR* altstr = FCS_GetAltStr(unicode);
    return CFX_ByteString(altstr ? altstr : defchar);
  }
  char buf[10];
  int iDef = 0;
  int ret = FXSYS_WideCharToMultiByte(destcp, 0, (wchar_t*)&unicode, 1, buf, 10,
                                      NULL, &iDef);
  if (ret && !iDef) {
    return CFX_ByteString(buf, ret);
  }
  const FX_CHAR* altstr = FCS_GetAltStr(unicode);
  return CFX_ByteString(altstr ? altstr : defchar);
}
CTextPage::CTextPage() {}
CTextPage::~CTextPage() {
  int i;
  for (i = 0; i < m_BaseLines.GetSize(); i++) {
    delete m_BaseLines.GetAt(i);
  }
  for (i = 0; i < m_TextColumns.GetSize(); i++) {
    delete m_TextColumns.GetAt(i);
  }
}
void CTextPage::ProcessObject(CPDF_PageObject* pObject) {
  if (pObject->m_Type != CPDF_PageObject::TEXT) {
    return;
  }
  CPDF_TextObject* pText = (CPDF_TextObject*)pObject;
  CPDF_Font* pFont = pText->m_TextState.GetFont();
  int count = pText->CountItems();
  FX_FLOAT* pPosArray = FX_Alloc2D(FX_FLOAT, count, 2);
  pText->CalcCharPos(pPosArray);

  FX_FLOAT fontsize_h = pText->m_TextState.GetFontSizeH();
  FX_FLOAT fontsize_v = pText->m_TextState.GetFontSizeV();
  FX_DWORD space_charcode = pFont->CharCodeFromUnicode(' ');
  FX_FLOAT spacew = 0;
  if (space_charcode != -1) {
    spacew = fontsize_h * pFont->GetCharWidthF(space_charcode) / 1000;
  }
  if (spacew == 0) {
    spacew = fontsize_h / 4;
  }
  if (pText->m_TextState.GetBaselineAngle() != 0) {
    int cc = 0;
    CFX_Matrix matrix;
    pText->GetTextMatrix(&matrix);
    for (int i = 0; i < pText->m_nChars; i++) {
      FX_DWORD charcode = pText->m_nChars == 1
                              ? (FX_DWORD)(uintptr_t)pText->m_pCharCodes
                              : pText->m_pCharCodes[i];
      if (charcode == (FX_DWORD)-1) {
        continue;
      }
      FX_RECT char_box;
      pFont->GetCharBBox(charcode, char_box);
      FX_FLOAT char_left =
          pPosArray ? pPosArray[cc * 2]
                    : char_box.left * pText->m_TextState.GetFontSize() / 1000;
      FX_FLOAT char_right =
          pPosArray ? pPosArray[cc * 2 + 1]
                    : char_box.right * pText->m_TextState.GetFontSize() / 1000;
      FX_FLOAT char_top =
          char_box.top * pText->m_TextState.GetFontSize() / 1000;
      FX_FLOAT char_bottom =
          char_box.bottom * pText->m_TextState.GetFontSize() / 1000;
      cc++;
      FX_FLOAT char_origx, char_origy;
      matrix.Transform(char_left, 0, char_origx, char_origy);
      matrix.TransformRect(char_left, char_right, char_top, char_bottom);
      CFX_ByteString str;
      pFont->AppendChar(str, charcode);
      InsertTextBox(NULL, char_origy, char_left, char_right, char_top,
                    char_bottom, spacew, fontsize_v, str, pFont);
    }
    FX_Free(pPosArray);
    return;
  }
  FX_FLOAT ratio_h = fontsize_h / pText->m_TextState.GetFontSize();
  for (int ii = 0; ii < count * 2; ii++) {
    pPosArray[ii] *= ratio_h;
  }
  FX_FLOAT baseline = pText->m_PosY;
  CTextBaseLine* pBaseLine = NULL;
  FX_FLOAT topy = pText->m_Top;
  FX_FLOAT bottomy = pText->m_Bottom;
  FX_FLOAT leftx = pText->m_Left;
  int cc = 0;
  CFX_ByteString segment;
  int space_count = 0;
  FX_FLOAT last_left = 0, last_right = 0, segment_left = 0, segment_right = 0;
  for (int i = 0; i < pText->m_nChars; i++) {
    FX_DWORD charcode = pText->m_nChars == 1
                            ? (FX_DWORD)(uintptr_t)pText->m_pCharCodes
                            : pText->m_pCharCodes[i];
    if (charcode == (FX_DWORD)-1) {
      continue;
    }
    FX_FLOAT char_left = pPosArray[cc * 2];
    FX_FLOAT char_right = pPosArray[cc * 2 + 1];
    cc++;
    if (char_left < last_left || (char_left - last_right) > spacew / 2) {
      pBaseLine = InsertTextBox(pBaseLine, baseline, leftx + segment_left,
                                leftx + segment_right, topy, bottomy, spacew,
                                fontsize_v, segment, pFont);
      segment_left = char_left;
      segment = "";
    }
    if (space_count > 1) {
      pBaseLine = InsertTextBox(pBaseLine, baseline, leftx + segment_left,
                                leftx + segment_right, topy, bottomy, spacew,
                                fontsize_v, segment, pFont);
      segment = "";
    } else if (space_count == 1) {
      pFont->AppendChar(segment, ' ');
    }
    if (segment.GetLength() == 0) {
      segment_left = char_left;
    }
    segment_right = char_right;
    pFont->AppendChar(segment, charcode);
    space_count = 0;
    last_left = char_left;
    last_right = char_right;
  }
  if (segment.GetLength())
    pBaseLine = InsertTextBox(pBaseLine, baseline, leftx + segment_left,
                              leftx + segment_right, topy, bottomy, spacew,
                              fontsize_v, segment, pFont);
  FX_Free(pPosArray);
}
CTextBaseLine* CTextPage::InsertTextBox(CTextBaseLine* pBaseLine,
                                        FX_FLOAT basey,
                                        FX_FLOAT leftx,
                                        FX_FLOAT rightx,
                                        FX_FLOAT topy,
                                        FX_FLOAT bottomy,
                                        FX_FLOAT spacew,
                                        FX_FLOAT fontsize_v,
                                        CFX_ByteString& str,
                                        CPDF_Font* pFont) {
  if (str.GetLength() == 0) {
    return NULL;
  }
  if (!pBaseLine) {
    int i;
    for (i = 0; i < m_BaseLines.GetSize(); i++) {
      CTextBaseLine* pExistLine = m_BaseLines.GetAt(i);
      if (pExistLine->m_BaseLine == basey) {
        pBaseLine = pExistLine;
        break;
      }
      if (pExistLine->m_BaseLine < basey) {
        break;
      }
    }
    if (!pBaseLine) {
      pBaseLine = new CTextBaseLine;
      pBaseLine->m_BaseLine = basey;
      m_BaseLines.InsertAt(i, pBaseLine);
    }
  }
  CFX_WideString text;
  const FX_CHAR* pStr = str;
  int len = str.GetLength(), offset = 0;
  while (offset < len) {
    FX_DWORD ch = pFont->GetNextChar(pStr, len, offset);
    CFX_WideString unicode_str = pFont->UnicodeFromCharCode(ch);
    if (unicode_str.IsEmpty()) {
      text += (FX_WCHAR)ch;
    } else {
      text += unicode_str;
    }
  }
  pBaseLine->InsertTextBox(leftx, rightx, topy, bottomy, spacew, fontsize_v,
                           text);
  return pBaseLine;
}
void CTextPage::WriteOutput(CFX_WideStringArray& lines, int iMinWidth) {
  FX_FLOAT lastheight = -1;
  FX_FLOAT lastbaseline = -1;
  FX_FLOAT MinLeftX = 1000000;
  FX_FLOAT MaxRightX = 0;
  int i;
  for (i = 0; i < m_BaseLines.GetSize(); i++) {
    CTextBaseLine* pBaseLine = m_BaseLines.GetAt(i);
    FX_FLOAT leftx, rightx;
    if (pBaseLine->GetWidth(leftx, rightx)) {
      if (leftx < MinLeftX) {
        MinLeftX = leftx;
      }
      if (rightx > MaxRightX) {
        MaxRightX = rightx;
      }
    }
  }
  for (i = 0; i < m_BaseLines.GetSize(); i++) {
    m_BaseLines.GetAt(i)->MergeBoxes();
  }
  for (i = 1; i < m_BaseLines.GetSize(); i++) {
    CTextBaseLine* pBaseLine = m_BaseLines.GetAt(i);
    CTextBaseLine* pPrevLine = m_BaseLines.GetAt(i - 1);
    if (pBaseLine->CanMerge(pPrevLine)) {
      pPrevLine->Merge(pBaseLine);
      delete pBaseLine;
      m_BaseLines.RemoveAt(i);
      i--;
    }
  }
  if (m_bAutoWidth) {
    int* widths = FX_Alloc(int, m_BaseLines.GetSize());
    for (i = 0; i < m_BaseLines.GetSize(); i++) {
      widths[i] = 0;
      CTextBaseLine* pBaseLine = m_BaseLines.GetAt(i);
      int TotalChars = 0;
      FX_FLOAT TotalWidth = 0;
      int minchars;
      pBaseLine->CountChars(TotalChars, TotalWidth, minchars);
      if (TotalChars) {
        FX_FLOAT charwidth = TotalWidth / TotalChars;
        widths[i] = (int)((MaxRightX - MinLeftX) / charwidth);
      }
      if (widths[i] > 1000) {
        widths[i] = 1000;
      }
      if (widths[i] < minchars) {
        widths[i] = minchars;
      }
    }
    int AvgWidth = 0, widthcount = 0;
    for (i = 0; i < m_BaseLines.GetSize(); i++)
      if (widths[i]) {
        AvgWidth += widths[i];
        widthcount++;
      }
    AvgWidth = int((FX_FLOAT)AvgWidth / widthcount + 0.5);
    int MaxWidth = 0;
    for (i = 0; i < m_BaseLines.GetSize(); i++)
      if (MaxWidth < widths[i]) {
        MaxWidth = widths[i];
      }
    if (MaxWidth > AvgWidth * 6 / 5) {
      MaxWidth = AvgWidth * 6 / 5;
    }
    FX_Free(widths);
    if (iMinWidth < MaxWidth) {
      iMinWidth = MaxWidth;
    }
  }
  for (i = 0; i < m_BaseLines.GetSize(); i++) {
    m_BaseLines.GetAt(i)->MergeBoxes();
  }
  if (m_bKeepColumn) {
    FindColumns();
  }
  for (i = 0; i < m_BaseLines.GetSize(); i++) {
    CTextBaseLine* pBaseLine = m_BaseLines.GetAt(i);
    if (lastheight >= 0) {
      FX_FLOAT dy = lastbaseline - pBaseLine->m_BaseLine;
      if (dy >= (pBaseLine->m_MaxFontSizeV) * 1.5 || dy >= lastheight * 1.5) {
        lines.Add(L"");
      }
    }
    lastheight = pBaseLine->m_MaxFontSizeV;
    lastbaseline = pBaseLine->m_BaseLine;
    CFX_WideString str;
    pBaseLine->WriteOutput(str, MinLeftX, MaxRightX - MinLeftX, iMinWidth);
    lines.Add(str);
  }
}
void NormalizeCompositeChar(FX_WCHAR wChar, CFX_WideString& sDest) {
  wChar = FX_GetMirrorChar(wChar, TRUE, FALSE);
  FX_WCHAR* pDst = NULL;
  FX_STRSIZE nCount = FX_Unicode_GetNormalization(wChar, pDst);
  if (nCount < 1) {
    sDest += wChar;
    return;
  }
  pDst = new FX_WCHAR[nCount];
  FX_Unicode_GetNormalization(wChar, pDst);
  for (int nIndex = 0; nIndex < nCount; nIndex++) {
    sDest += pDst[nIndex];
  }
  delete[] pDst;
}

void NormalizeString(CFX_WideString& str) {
  if (str.GetLength() <= 0) {
    return;
  }
  CFX_WideString sBuffer;
  std::unique_ptr<CFX_BidiChar> pBidiChar(new CFX_BidiChar);
  std::vector<FX_WORD> order;
  FX_BOOL bR2L = FALSE;
  int32_t start = 0, count = 0, i = 0;
  int nR2L = 0, nL2R = 0;
  for (i = 0; i < str.GetLength(); i++) {
    if (pBidiChar->AppendChar(str.GetAt(i))) {
      CFX_BidiChar::Direction ret = pBidiChar->GetBidiInfo(&start, &count);
      order.push_back(start);
      order.push_back(count);
      order.push_back(ret);
      if (!bR2L) {
        if (ret == CFX_BidiChar::RIGHT) {
          nR2L++;
        } else if (ret == CFX_BidiChar::LEFT) {
          nL2R++;
        }
      }
    }
  }
  if (pBidiChar->EndChar()) {
    CFX_BidiChar::Direction ret = pBidiChar->GetBidiInfo(&start, &count);
    order.push_back(start);
    order.push_back(count);
    order.push_back(ret);
    if (!bR2L) {
      if (ret == CFX_BidiChar::RIGHT) {
        nR2L++;
      } else if (ret == CFX_BidiChar::LEFT) {
        nL2R++;
      }
    }
  }
  if (nR2L > 0 && nR2L >= nL2R) {
    bR2L = TRUE;
  }
  if (bR2L) {
    int count = pdfium::CollectionSize<int>(order);
    for (int j = count - 1; j > 0; j -= 3) {
      int ret = order[j];
      int count1 = order[j - 1];
      int start = order[j - 2];
      if (ret == 2 || ret == 0) {
        for (int i = start + count1 - 1; i >= start; i--) {
          NormalizeCompositeChar(str[i], sBuffer);
        }
      } else {
        i = j;
        FX_BOOL bSymbol = FALSE;
        while (i > 0 && order[i] != 2) {
          bSymbol = !order[i];
          i -= 3;
        }
        int end = start + count1;
        int n = 0;
        if (bSymbol) {
          n = i + 6;
        } else {
          n = i + 3;
        }
        if (n >= j) {
          for (int m = start; m < end; m++) {
            sBuffer += str[m];
          }
        } else {
          i = j;
          j = n;
          for (; n <= i; n += 3) {
            int start = order[n - 2];
            int count1 = order[n - 1];
            int end = start + count1;
            for (int m = start; m < end; m++) {
              sBuffer += str[m];
            }
          }
        }
      }
    }
  } else {
    int count = pdfium::CollectionSize<int>(order);
    FX_BOOL bL2R = FALSE;
    for (int j = 0; j < count; j += 3) {
      int start = order[j];
      int count1 = order[j + 1];
      int ret = order[j + 2];
      if (ret == 2 || (j == 0 && ret == 0 && !bL2R)) {
        int i = j + 3;
        while (bR2L && i < count) {
          if (order[i + 2] == 1) {
            break;
          } else {
            i += 3;
          }
        }
        if (i == 3) {
          j = -3;
          bL2R = TRUE;
          continue;
        }
        int end = str.GetLength() - 1;
        if (i < count) {
          end = order[i] - 1;
        }
        j = i - 3;
        for (int n = end; n >= start; n--) {
          NormalizeCompositeChar(str[i], sBuffer);
        }
      } else {
        int end = start + count1;
        for (int i = start; i < end; i++) {
          sBuffer += str[i];
        }
      }
    }
  }
  str.Empty();
  str += sBuffer;
}
static FX_BOOL IsNumber(CFX_WideString& str) {
  for (int i = 0; i < str.GetLength(); i++) {
    FX_WCHAR ch = str[i];
    // TODO(dsinclair): --.+ +.-- should probably not be a number.
    if (!std::iswdigit(ch) && ch != '-' && ch != '+' && ch != '.' && ch != ' ')
      return FALSE;
  }
  return TRUE;
}
void CTextPage::FindColumns() {
  int i;
  for (i = 0; i < m_BaseLines.GetSize(); i++) {
    CTextBaseLine* pBaseLine = m_BaseLines.GetAt(i);
    for (int j = 0; j < pBaseLine->m_TextList.GetSize(); j++) {
      CTextBox* pTextBox = pBaseLine->m_TextList.GetAt(j);
      CTextColumn* pColumn = FindColumn(pTextBox->m_Right);
      if (pColumn) {
        pColumn->m_AvgPos =
            (pColumn->m_Count * pColumn->m_AvgPos + pTextBox->m_Right) /
            (pColumn->m_Count + 1);
        pColumn->m_Count++;
      } else {
        pColumn = new CTextColumn;
        pColumn->m_Count = 1;
        pColumn->m_AvgPos = pTextBox->m_Right;
        pColumn->m_TextPos = -1;
        m_TextColumns.Add(pColumn);
      }
    }
  }
  int mincount = m_BaseLines.GetSize() / 4;
  for (i = 0; i < m_TextColumns.GetSize(); i++) {
    CTextColumn* pTextColumn = m_TextColumns.GetAt(i);
    if (pTextColumn->m_Count >= mincount) {
      continue;
    }
    delete pTextColumn;
    m_TextColumns.RemoveAt(i);
    i--;
  }
  for (i = 0; i < m_BaseLines.GetSize(); i++) {
    CTextBaseLine* pBaseLine = m_BaseLines.GetAt(i);
    for (int j = 0; j < pBaseLine->m_TextList.GetSize(); j++) {
      CTextBox* pTextBox = pBaseLine->m_TextList.GetAt(j);
      if (IsNumber(pTextBox->m_Text)) {
        pTextBox->m_pColumn = FindColumn(pTextBox->m_Right);
      }
    }
  }
}
CTextColumn* CTextPage::FindColumn(FX_FLOAT xpos) {
  for (int i = 0; i < m_TextColumns.GetSize(); i++) {
    CTextColumn* pColumn = m_TextColumns.GetAt(i);
    if (pColumn->m_AvgPos < xpos + 1 && pColumn->m_AvgPos > xpos - 1) {
      return pColumn;
    }
  }
  return NULL;
}
void CTextPage::BreakSpace(CPDF_TextObject* pTextObj) {}
CTextBaseLine::CTextBaseLine() {
  m_Top = -100000;
  m_Bottom = 100000;
  m_MaxFontSizeV = 0;
}
CTextBaseLine::~CTextBaseLine() {
  for (int i = 0; i < m_TextList.GetSize(); i++) {
    delete m_TextList.GetAt(i);
  }
}
void CTextBaseLine::InsertTextBox(FX_FLOAT leftx,
                                  FX_FLOAT rightx,
                                  FX_FLOAT topy,
                                  FX_FLOAT bottomy,
                                  FX_FLOAT spacew,
                                  FX_FLOAT fontsize_v,
                                  const CFX_WideString& text) {
  if (m_Top < topy) {
    m_Top = topy;
  }
  if (m_Bottom > bottomy) {
    m_Bottom = bottomy;
  }
  if (m_MaxFontSizeV < fontsize_v) {
    m_MaxFontSizeV = fontsize_v;
  }
  int i;
  for (i = 0; i < m_TextList.GetSize(); i++) {
    CTextBox* pText = m_TextList.GetAt(i);
    if (pText->m_Left > leftx) {
      break;
    }
  }
  CTextBox* pText = new CTextBox;
  pText->m_Text = text;
  pText->m_Left = leftx;
  pText->m_Right = rightx;
  pText->m_Top = topy;
  pText->m_Bottom = bottomy;
  pText->m_SpaceWidth = spacew;
  pText->m_FontSizeV = fontsize_v;
  pText->m_pColumn = NULL;
  m_TextList.InsertAt(i, pText);
}
FX_BOOL GetIntersection(FX_FLOAT low1,
                        FX_FLOAT high1,
                        FX_FLOAT low2,
                        FX_FLOAT high2,
                        FX_FLOAT& interlow,
                        FX_FLOAT& interhigh);
FX_BOOL CTextBaseLine::CanMerge(CTextBaseLine* pOther) {
  FX_FLOAT inter_top, inter_bottom;
  if (!GetIntersection(m_Bottom, m_Top, pOther->m_Bottom, pOther->m_Top,
                       inter_bottom, inter_top)) {
    return FALSE;
  }
  FX_FLOAT inter_h = inter_top - inter_bottom;
  if (inter_h < (m_Top - m_Bottom) / 2 &&
      inter_h < (pOther->m_Top - pOther->m_Bottom) / 2) {
    return FALSE;
  }
  FX_FLOAT dy = (FX_FLOAT)FXSYS_fabs(m_BaseLine - pOther->m_BaseLine);
  for (int i = 0; i < m_TextList.GetSize(); i++) {
    CTextBox* pText = m_TextList.GetAt(i);
    for (int j = 0; j < pOther->m_TextList.GetSize(); j++) {
      CTextBox* pOtherText = pOther->m_TextList.GetAt(j);
      FX_FLOAT inter_left, inter_right;
      if (!GetIntersection(pText->m_Left, pText->m_Right, pOtherText->m_Left,
                           pOtherText->m_Right, inter_left, inter_right)) {
        continue;
      }
      FX_FLOAT inter_w = inter_right - inter_left;
      if (inter_w < pText->m_SpaceWidth / 2 &&
          inter_w < pOtherText->m_SpaceWidth / 2) {
        continue;
      }
      if (dy >= (pText->m_Bottom - pText->m_Top) / 2 ||
          dy >= (pOtherText->m_Bottom - pOtherText->m_Top) / 2) {
        return FALSE;
      }
    }
  }
  return TRUE;
}
void CTextBaseLine::Merge(CTextBaseLine* pOther) {
  for (int i = 0; i < pOther->m_TextList.GetSize(); i++) {
    CTextBox* pText = pOther->m_TextList.GetAt(i);
    InsertTextBox(pText->m_Left, pText->m_Right, pText->m_Top, pText->m_Bottom,
                  pText->m_SpaceWidth, pText->m_FontSizeV, pText->m_Text);
  }
}
FX_BOOL CTextBaseLine::GetWidth(FX_FLOAT& leftx, FX_FLOAT& rightx) {
  int i;
  for (i = 0; i < m_TextList.GetSize(); i++) {
    CTextBox* pText = m_TextList.GetAt(i);
    if (pText->m_Text != L" ") {
      break;
    }
  }
  if (i == m_TextList.GetSize()) {
    return FALSE;
  }
  CTextBox* pText = m_TextList.GetAt(i);
  leftx = pText->m_Left;
  for (i = m_TextList.GetSize() - 1; i >= 0; i--) {
    CTextBox* pText = m_TextList.GetAt(i);
    if (pText->m_Text != L" ") {
      break;
    }
  }
  pText = m_TextList.GetAt(i);
  rightx = pText->m_Right;
  return TRUE;
}
void CTextBaseLine::MergeBoxes() {
  int i = 0;
  while (1) {
    if (i >= m_TextList.GetSize() - 1) {
      break;
    }
    CTextBox* pThisText = m_TextList.GetAt(i);
    CTextBox* pNextText = m_TextList.GetAt(i + 1);
    FX_FLOAT dx = pNextText->m_Left - pThisText->m_Right;
    FX_FLOAT spacew = (pThisText->m_SpaceWidth == 0.0)
                          ? pNextText->m_SpaceWidth
                          : pThisText->m_SpaceWidth;
    if (spacew > 0.0 && dx < spacew * 2) {
      pThisText->m_Right = pNextText->m_Right;
      if (dx > spacew * 1.5) {
        pThisText->m_Text += L"  ";
      } else if (dx > spacew / 3) {
        pThisText->m_Text += L' ';
      }
      pThisText->m_Text += pNextText->m_Text;
      pThisText->m_SpaceWidth =
          pNextText->m_SpaceWidth == 0.0 ? spacew : pNextText->m_SpaceWidth;
      m_TextList.RemoveAt(i + 1);
      delete pNextText;
    } else {
      i++;
    }
  }
}
void CTextBaseLine::WriteOutput(CFX_WideString& str,
                                FX_FLOAT leftx,
                                FX_FLOAT pagewidth,
                                int iTextWidth) {
  int lastpos = -1;
  for (int i = 0; i < m_TextList.GetSize(); i++) {
    CTextBox* pText = m_TextList.GetAt(i);
    int xpos;
    if (pText->m_pColumn) {
      xpos =
          (int)((pText->m_pColumn->m_AvgPos - leftx) * iTextWidth / pagewidth +
                0.5);
      xpos -= pText->m_Text.GetLength();
    } else {
      xpos = (int)((pText->m_Left - leftx) * iTextWidth / pagewidth + 0.5);
    }
    if (xpos <= lastpos) {
      xpos = lastpos + 1;
    }
    for (int j = lastpos + 1; j < xpos; j++) {
      str += ' ';
    }
    CFX_WideString sSrc(pText->m_Text);
    NormalizeString(sSrc);
    str += sSrc;
    str += ' ';
    lastpos = xpos + pText->m_Text.GetLength();
  }
}
void CTextBaseLine::CountChars(int& count, FX_FLOAT& width, int& minchars) {
  minchars = 0;
  for (int i = 0; i < m_TextList.GetSize(); i++) {
    CTextBox* pText = m_TextList.GetAt(i);
    if (pText->m_Right - pText->m_Left < 0.002) {
      continue;
    }
    count += pText->m_Text.GetLength();
    width += pText->m_Right - pText->m_Left;
    minchars += pText->m_Text.GetLength() + 1;
  }
}
#define PI 3.1415926535897932384626433832795
static void CheckRotate(CPDF_Page& page, CFX_FloatRect& page_bbox) {
  int total_count = 0, rotated_count[3] = {0, 0, 0};
  FX_POSITION pos = page.GetFirstObjectPosition();
  while (pos) {
    CPDF_PageObject* pObj = page.GetNextObject(pos);
    if (pObj->m_Type != CPDF_PageObject::TEXT) {
      continue;
    }
    total_count++;
    CPDF_TextObject* pText = (CPDF_TextObject*)pObj;
    FX_FLOAT angle = pText->m_TextState.GetBaselineAngle();
    if (angle == 0.0) {
      continue;
    }
    int degree = (int)(angle * 180 / PI + 0.5);
    if (degree % 90) {
      continue;
    }
    if (degree < 0) {
      degree += 360;
    }
    int index = degree / 90 % 3 - 1;
    if (index < 0) {
      continue;
    }
    rotated_count[index]++;
  }
  if (total_count == 0) {
    return;
  }
  CFX_Matrix matrix;
  if (rotated_count[0] > total_count * 2 / 3) {
    matrix.Set(0, -1, 1, 0, 0, page.GetPageHeight());
  } else if (rotated_count[1] > total_count * 2 / 3) {
    matrix.Set(-1, 0, 0, -1, page.GetPageWidth(), page.GetPageHeight());
  } else if (rotated_count[2] > total_count * 2 / 3) {
    matrix.Set(0, 1, -1, 0, page.GetPageWidth(), 0);
  } else {
    return;
  }
  page.Transform(matrix);
  page_bbox.Transform(&matrix);
}
void PDF_GetPageText_Unicode(CFX_WideStringArray& lines,
                             CPDF_Document* pDoc,
                             CPDF_Dictionary* pPage,
                             int iMinWidth,
                             FX_DWORD flags) {
  lines.RemoveAll();
  if (!pPage) {
    return;
  }
  CPDF_Page page;
  page.Load(pDoc, pPage);
  CPDF_ParseOptions options;
  options.m_bTextOnly = TRUE;
  options.m_bSeparateForm = FALSE;
  page.ParseContent(&options);
  CFX_FloatRect page_bbox = page.GetPageBBox();
  if (flags & PDF2TXT_AUTO_ROTATE) {
    CheckRotate(page, page_bbox);
  }
  CTextPage texts;
  texts.m_bAutoWidth = flags & PDF2TXT_AUTO_WIDTH;
  texts.m_bKeepColumn = flags & PDF2TXT_KEEP_COLUMN;
  texts.m_bBreakSpace = TRUE;
  FX_POSITION pos = page.GetFirstObjectPosition();
  while (pos) {
    CPDF_PageObject* pObject = page.GetNextObject(pos);
    if (!(flags & PDF2TXT_INCLUDE_INVISIBLE)) {
      CFX_FloatRect rect(pObject->m_Left, pObject->m_Bottom, pObject->m_Right,
                         pObject->m_Top);
      if (!page_bbox.Contains(rect)) {
        continue;
      }
    }
    texts.ProcessObject(pObject);
  }
  texts.WriteOutput(lines, iMinWidth);
}
void PDF_GetPageText(CFX_ByteStringArray& lines,
                     CPDF_Document* pDoc,
                     CPDF_Dictionary* pPage,
                     int iMinWidth,
                     FX_DWORD flags) {
  lines.RemoveAll();
  CFX_WideStringArray wlines;
  PDF_GetPageText_Unicode(wlines, pDoc, pPage, iMinWidth, flags);
  for (int i = 0; i < wlines.GetSize(); i++) {
    CFX_WideString wstr = wlines[i];
    CFX_ByteString str;
    for (int c = 0; c < wstr.GetLength(); c++) {
      str += CharFromUnicodeAlt(wstr[c], FXSYS_GetACP(), "?");
    }
    lines.Add(str);
  }
}
void PDF_GetTextStream_Unicode(CFX_WideTextBuf& buffer,
                               CPDF_Document* pDoc,
                               CPDF_Dictionary* pPage,
                               FX_DWORD flags) {
  buffer.EstimateSize(0, 10240);
  CPDF_Page page;
  page.Load(pDoc, pPage);
  CPDF_ParseOptions options;
  options.m_bTextOnly = TRUE;
  options.m_bSeparateForm = FALSE;
  page.ParseContent(&options);
  GetTextStream_Unicode(buffer, &page, TRUE);
}
