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

#include "core/include/fpdfapi/fpdf_module.h"
#include "core/include/fpdfapi/fpdf_page.h"

CPDF_PageObject* CPDF_PageObject::Create(int type) {
  switch (type) {
    case PDFPAGE_TEXT:
      return new CPDF_TextObject;
    case PDFPAGE_IMAGE:
      return new CPDF_ImageObject;
    case PDFPAGE_PATH:
      return new CPDF_PathObject;
    case PDFPAGE_SHADING:
      return new CPDF_ShadingObject;
    case PDFPAGE_FORM:
      return new CPDF_FormObject;
  }
  return NULL;
}
CPDF_PageObject::~CPDF_PageObject() {}
CPDF_PageObject* CPDF_PageObject::Clone() const {
  CPDF_PageObject* pObj = Create(m_Type);
  pObj->Copy(this);
  return pObj;
}
void CPDF_PageObject::Copy(const CPDF_PageObject* pSrc) {
  if (m_Type != pSrc->m_Type) {
    return;
  }
  CopyData(pSrc);
  CopyStates(*pSrc);
  m_Left = pSrc->m_Left;
  m_Right = pSrc->m_Right;
  m_Top = pSrc->m_Top;
  m_Bottom = pSrc->m_Bottom;
}
void CPDF_PageObject::AppendClipPath(CPDF_Path path,
                                     int type,
                                     FX_BOOL bAutoMerge) {
  m_ClipPath.AppendPath(path, type, bAutoMerge);
}
void CPDF_PageObject::CopyClipPath(CPDF_PageObject* pObj) {
  m_ClipPath = pObj->m_ClipPath;
}
void CPDF_PageObject::RemoveClipPath() {
  m_ClipPath.SetNull();
}
void CPDF_PageObject::RecalcBBox() {
  switch (m_Type) {
    case PDFPAGE_TEXT:
      ((CPDF_TextObject*)this)->RecalcPositionData();
      break;
    case PDFPAGE_PATH:
      ((CPDF_PathObject*)this)->CalcBoundingBox();
      break;
    case PDFPAGE_SHADING:
      ((CPDF_ShadingObject*)this)->CalcBoundingBox();
      break;
  }
}
void CPDF_PageObject::TransformClipPath(CFX_Matrix& matrix) {
  if (m_ClipPath.IsNull()) {
    return;
  }
  m_ClipPath.GetModify();
  m_ClipPath.Transform(matrix);
}
void CPDF_PageObject::TransformGeneralState(CFX_Matrix& matrix) {
  if (m_GeneralState.IsNull()) {
    return;
  }
  CPDF_GeneralStateData* pGS = m_GeneralState.GetModify();
  pGS->m_Matrix.Concat(matrix);
}
FX_RECT CPDF_PageObject::GetBBox(const CFX_Matrix* pMatrix) const {
  CFX_FloatRect rect(m_Left, m_Bottom, m_Right, m_Top);
  if (pMatrix) {
    pMatrix->TransformRect(rect);
  }
  return rect.GetOutterRect();
}

CPDF_TextObject::CPDF_TextObject()
    : m_PosX(0),
      m_PosY(0),
      m_nChars(0),
      m_pCharCodes(nullptr),
      m_pCharPos(nullptr) {
  m_Type = PDFPAGE_TEXT;
}

CPDF_TextObject::~CPDF_TextObject() {
  if (m_nChars > 1) {
    FX_Free(m_pCharCodes);
  }
  FX_Free(m_pCharPos);
}

void CPDF_TextObject::GetItemInfo(int index, CPDF_TextObjectItem* pInfo) const {
  pInfo->m_CharCode =
      m_nChars == 1 ? (FX_DWORD)(uintptr_t)m_pCharCodes : m_pCharCodes[index];
  pInfo->m_OriginX = index ? m_pCharPos[index - 1] : 0;
  pInfo->m_OriginY = 0;
  if (pInfo->m_CharCode == -1) {
    return;
  }
  CPDF_Font* pFont = m_TextState.GetFont();
  if (pFont->GetFontType() != PDFFONT_CIDFONT) {
    return;
  }
  if (!((CPDF_CIDFont*)pFont)->IsVertWriting()) {
    return;
  }
  FX_WORD CID = ((CPDF_CIDFont*)pFont)->CIDFromCharCode(pInfo->m_CharCode);
  pInfo->m_OriginY = pInfo->m_OriginX;
  pInfo->m_OriginX = 0;
  short vx, vy;
  ((CPDF_CIDFont*)pFont)->GetVertOrigin(CID, vx, vy);
  FX_FLOAT fontsize = m_TextState.GetFontSize();
  pInfo->m_OriginX -= fontsize * vx / 1000;
  pInfo->m_OriginY -= fontsize * vy / 1000;
}

int CPDF_TextObject::CountChars() const {
  if (m_nChars == 1) {
    return 1;
  }
  int count = 0;
  for (int i = 0; i < m_nChars; ++i)
    if (m_pCharCodes[i] != (FX_DWORD)-1) {
      ++count;
    }
  return count;
}

void CPDF_TextObject::GetCharInfo(int index,
                                  FX_DWORD& charcode,
                                  FX_FLOAT& kerning) const {
  if (m_nChars == 1) {
    charcode = (FX_DWORD)(uintptr_t)m_pCharCodes;
    kerning = 0;
    return;
  }
  int count = 0;
  for (int i = 0; i < m_nChars; ++i) {
    if (m_pCharCodes[i] != (FX_DWORD)-1) {
      if (count == index) {
        charcode = m_pCharCodes[i];
        if (i == m_nChars - 1 || m_pCharCodes[i + 1] != (FX_DWORD)-1) {
          kerning = 0;
        } else {
          kerning = m_pCharPos[i];
        }
        return;
      }
      ++count;
    }
  }
}

void CPDF_TextObject::GetCharInfo(int index, CPDF_TextObjectItem* pInfo) const {
  if (m_nChars == 1) {
    GetItemInfo(0, pInfo);
    return;
  }
  int count = 0;
  for (int i = 0; i < m_nChars; ++i) {
    FX_DWORD charcode = m_pCharCodes[i];
    if (charcode == (FX_DWORD)-1) {
      continue;
    }
    if (count == index) {
      GetItemInfo(i, pInfo);
      break;
    }
    ++count;
  }
}

void CPDF_TextObject::CopyData(const CPDF_PageObject* pSrc) {
  const CPDF_TextObject* pSrcObj = (const CPDF_TextObject*)pSrc;
  if (m_nChars > 1) {
    FX_Free(m_pCharCodes);
    m_pCharCodes = nullptr;
  }
  FX_Free(m_pCharPos);
  m_pCharPos = nullptr;
  m_nChars = pSrcObj->m_nChars;
  if (m_nChars > 1) {
    m_pCharCodes = FX_Alloc(FX_DWORD, m_nChars);
    m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1);
    for (int i = 0; i < m_nChars; ++i) {
      m_pCharCodes[i] = pSrcObj->m_pCharCodes[i];
    }
    for (int i = 0; i < m_nChars - 1; ++i) {
      m_pCharPos[i] = pSrcObj->m_pCharPos[i];
    }
  } else {
    m_pCharCodes = pSrcObj->m_pCharCodes;
  }
  m_PosX = pSrcObj->m_PosX;
  m_PosY = pSrcObj->m_PosY;
}

void CPDF_TextObject::GetTextMatrix(CFX_Matrix* pMatrix) const {
  FX_FLOAT* pTextMatrix = m_TextState.GetMatrix();
  pMatrix->Set(pTextMatrix[0], pTextMatrix[2], pTextMatrix[1], pTextMatrix[3],
               m_PosX, m_PosY);
}

void CPDF_TextObject::SetSegments(const CFX_ByteString* pStrs,
                                  FX_FLOAT* pKerning,
                                  int nsegs) {
  if (m_nChars > 1) {
    FX_Free(m_pCharCodes);
    m_pCharCodes = nullptr;
  }
  FX_Free(m_pCharPos);
  m_pCharPos = nullptr;
  CPDF_Font* pFont = m_TextState.GetFont();
  m_nChars = 0;
  for (int i = 0; i < nsegs; ++i) {
    m_nChars += pFont->CountChar(pStrs[i], pStrs[i].GetLength());
  }
  m_nChars += nsegs - 1;
  if (m_nChars > 1) {
    m_pCharCodes = FX_Alloc(FX_DWORD, m_nChars);
    m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1);
    int index = 0;
    for (int i = 0; i < nsegs; ++i) {
      const FX_CHAR* segment = pStrs[i];
      int offset = 0, len = pStrs[i].GetLength();
      while (offset < len) {
        m_pCharCodes[index++] = pFont->GetNextChar(segment, len, offset);
      }
      if (i != nsegs - 1) {
        m_pCharPos[index - 1] = pKerning[i];
        m_pCharCodes[index++] = (FX_DWORD)-1;
      }
    }
  } else {
    int offset = 0;
    m_pCharCodes = (FX_DWORD*)(uintptr_t)pFont->GetNextChar(
        pStrs[0], pStrs[0].GetLength(), offset);
  }
}

void CPDF_TextObject::SetText(const CFX_ByteString& str) {
  SetSegments(&str, nullptr, 1);
  RecalcPositionData();
}

void CPDF_TextObject::SetEmpty() {
  if (m_nChars > 1) {
    FX_Free(m_pCharCodes);
  }
  if (m_nChars > 1) {
    FX_Free(m_pCharPos);
  }
  m_nChars = 0;
  m_pCharCodes = nullptr;
  m_pCharPos = nullptr;
  m_Left = m_Right = m_PosX;
  m_Top = m_Bottom = m_PosY;
}

void CPDF_TextObject::SetText(CFX_ByteString* pStrs,
                              FX_FLOAT* pKerning,
                              int nSegs) {
  SetSegments(pStrs, pKerning, nSegs);
  RecalcPositionData();
}

void CPDF_TextObject::SetText(int nChars,
                              FX_DWORD* pCharCodes,
                              FX_FLOAT* pKernings) {
  if (m_nChars > 1) {
    FX_Free(m_pCharCodes);
    m_pCharCodes = nullptr;
  }
  FX_Free(m_pCharPos);
  m_pCharPos = nullptr;
  int nKernings = 0;
  int i;
  for (i = 0; i < nChars - 1; ++i) {
    if (pKernings[i] != 0) {
      ++nKernings;
    }
  }
  m_nChars = nChars + nKernings;
  if (m_nChars > 1) {
    m_pCharCodes = FX_Alloc(FX_DWORD, m_nChars);
    m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1);
    for (int i = 0, index = 0; i < nChars; ++i) {
      m_pCharCodes[index++] = pCharCodes[i];
      if (pKernings[i] != 0 && i != nChars - 1) {
        m_pCharCodes[index] = (FX_DWORD)-1;
        m_pCharPos[index - 1] = pKernings[i];
        ++index;
      }
    }
  } else {
    m_pCharCodes = (FX_DWORD*)(uintptr_t)pCharCodes[0];
  }
  RecalcPositionData();
}

FX_FLOAT CPDF_TextObject::GetCharWidth(FX_DWORD charcode) const {
  FX_FLOAT fontsize = m_TextState.GetFontSize() / 1000;
  CPDF_Font* pFont = m_TextState.GetFont();
  FX_BOOL bVertWriting = FALSE;
  CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
  if (pCIDFont) {
    bVertWriting = pCIDFont->IsVertWriting();
  }
  if (!bVertWriting)
    return pFont->GetCharWidthF(charcode, 0) * fontsize;

  FX_WORD CID = pCIDFont->CIDFromCharCode(charcode);
  return pCIDFont->GetVertWidth(CID) * fontsize;
}

FX_FLOAT CPDF_TextObject::GetSpaceCharWidth() const {
  CPDF_Font* pFont = m_TextState.GetFont();
  FX_DWORD charCode = m_TextState.GetFont()->CharCodeFromUnicode(32);
  if (charCode != (FX_DWORD)-1) {
    return GetCharWidth(charCode);
  }
  FX_FLOAT fontSize = m_TextState.GetFontSize() / 4000.0f;
  FX_BOOL bVertWriting = FALSE;
  CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
  if (pCIDFont) {
    bVertWriting = pCIDFont->IsVertWriting();
  }
  FX_RECT fontRect;
  pFont->GetFontBBox(fontRect);
  fontSize *=
      bVertWriting ? (FX_FLOAT)fontRect.Height() : (FX_FLOAT)fontRect.Width();
  return fontSize;
}

void CPDF_TextObject::GetCharRect(int index, CFX_FloatRect& rect) const {
  CPDF_Font* pFont = m_TextState.GetFont();
  FX_BOOL bVertWriting = FALSE;
  CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
  if (pCIDFont) {
    bVertWriting = pCIDFont->IsVertWriting();
  }
  FX_FLOAT fontsize = m_TextState.GetFontSize() / 1000;
  int count = 0;
  for (int i = 0; i < m_nChars; ++i) {
    FX_DWORD charcode =
        m_nChars == 1 ? (FX_DWORD)(uintptr_t)m_pCharCodes : m_pCharCodes[i];
    if (charcode == (FX_DWORD)-1) {
      continue;
    }
    if (count != index) {
      ++count;
      continue;
    }
    FX_FLOAT curpos = i > 0 ? m_pCharPos[i - 1] : 0;
    FX_RECT char_rect;
    pFont->GetCharBBox(charcode, char_rect, 0);
    if (!bVertWriting) {
      rect.left = curpos + char_rect.left * fontsize;
      rect.right = curpos + char_rect.right * fontsize;
      rect.top = char_rect.top * fontsize;
      rect.bottom = char_rect.bottom * fontsize;
    } else {
      FX_WORD CID = pCIDFont->CIDFromCharCode(charcode);
      short vx, vy;
      pCIDFont->GetVertOrigin(CID, vx, vy);
      char_rect.left -= vx;
      char_rect.right -= vx;
      char_rect.top -= vy;
      char_rect.bottom -= vy;
      rect.left = char_rect.left * fontsize;
      rect.right = char_rect.right * fontsize;
      rect.top = curpos + char_rect.top * fontsize;
      rect.bottom = curpos + char_rect.bottom * fontsize;
    }
    return;
  }
}

void CPDF_TextObject::CalcPositionData(FX_FLOAT* pTextAdvanceX,
                                       FX_FLOAT* pTextAdvanceY,
                                       FX_FLOAT horz_scale,
                                       int level) {
  FX_FLOAT curpos = 0;
  FX_FLOAT min_x = 10000 * 1.0f;
  FX_FLOAT max_x = -10000 * 1.0f;
  FX_FLOAT min_y = 10000 * 1.0f;
  FX_FLOAT max_y = -10000 * 1.0f;
  CPDF_Font* pFont = m_TextState.GetFont();
  FX_BOOL bVertWriting = FALSE;
  CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
  if (pCIDFont) {
    bVertWriting = pCIDFont->IsVertWriting();
  }
  FX_FLOAT fontsize = m_TextState.GetFontSize();
  for (int i = 0; i < m_nChars; ++i) {
    FX_DWORD charcode =
        m_nChars == 1 ? (FX_DWORD)(uintptr_t)m_pCharCodes : m_pCharCodes[i];
    if (i > 0) {
      if (charcode == (FX_DWORD)-1) {
        curpos -= FXSYS_Mul(m_pCharPos[i - 1], fontsize) / 1000;
        continue;
      }
      m_pCharPos[i - 1] = curpos;
    }
    FX_RECT char_rect;
    pFont->GetCharBBox(charcode, char_rect, level);
    FX_FLOAT charwidth;
    if (!bVertWriting) {
      if (min_y > char_rect.top) {
        min_y = (FX_FLOAT)char_rect.top;
      }
      if (max_y < char_rect.top) {
        max_y = (FX_FLOAT)char_rect.top;
      }
      if (min_y > char_rect.bottom) {
        min_y = (FX_FLOAT)char_rect.bottom;
      }
      if (max_y < char_rect.bottom) {
        max_y = (FX_FLOAT)char_rect.bottom;
      }
      FX_FLOAT char_left = curpos + char_rect.left * fontsize / 1000;
      FX_FLOAT char_right = curpos + char_rect.right * fontsize / 1000;
      if (min_x > char_left) {
        min_x = char_left;
      }
      if (max_x < char_left) {
        max_x = char_left;
      }
      if (min_x > char_right) {
        min_x = char_right;
      }
      if (max_x < char_right) {
        max_x = char_right;
      }
      charwidth = pFont->GetCharWidthF(charcode, level) * fontsize / 1000;
    } else {
      FX_WORD CID = pCIDFont->CIDFromCharCode(charcode);
      short vx;
      short vy;
      pCIDFont->GetVertOrigin(CID, vx, vy);
      char_rect.left -= vx;
      char_rect.right -= vx;
      char_rect.top -= vy;
      char_rect.bottom -= vy;
      if (min_x > char_rect.left) {
        min_x = (FX_FLOAT)char_rect.left;
      }
      if (max_x < char_rect.left) {
        max_x = (FX_FLOAT)char_rect.left;
      }
      if (min_x > char_rect.right) {
        min_x = (FX_FLOAT)char_rect.right;
      }
      if (max_x < char_rect.right) {
        max_x = (FX_FLOAT)char_rect.right;
      }
      FX_FLOAT char_top = curpos + char_rect.top * fontsize / 1000;
      FX_FLOAT char_bottom = curpos + char_rect.bottom * fontsize / 1000;
      if (min_y > char_top) {
        min_y = char_top;
      }
      if (max_y < char_top) {
        max_y = char_top;
      }
      if (min_y > char_bottom) {
        min_y = char_bottom;
      }
      if (max_y < char_bottom) {
        max_y = char_bottom;
      }
      charwidth = pCIDFont->GetVertWidth(CID) * fontsize / 1000;
    }
    curpos += charwidth;
    if (charcode == ' ' && (!pCIDFont || pCIDFont->GetCharSize(32) == 1)) {
      curpos += m_TextState.GetObject()->m_WordSpace;
    }
    curpos += m_TextState.GetObject()->m_CharSpace;
  }
  if (bVertWriting) {
    if (pTextAdvanceX) {
      *pTextAdvanceX = 0;
    }
    if (pTextAdvanceY) {
      *pTextAdvanceY = curpos;
    }
    min_x = min_x * fontsize / 1000;
    max_x = max_x * fontsize / 1000;
  } else {
    if (pTextAdvanceX) {
      *pTextAdvanceX = FXSYS_Mul(curpos, horz_scale);
    }
    if (pTextAdvanceY) {
      *pTextAdvanceY = 0;
    }
    min_y = min_y * fontsize / 1000;
    max_y = max_y * fontsize / 1000;
  }
  CFX_Matrix matrix;
  GetTextMatrix(&matrix);
  m_Left = min_x;
  m_Right = max_x;
  m_Bottom = min_y;
  m_Top = max_y;
  matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom);
  int textmode = m_TextState.GetObject()->m_TextMode;
  if (textmode == 1 || textmode == 2 || textmode == 5 || textmode == 6) {
    FX_FLOAT half_width = m_GraphState.GetObject()->m_LineWidth / 2;
    m_Left -= half_width;
    m_Right += half_width;
    m_Top += half_width;
    m_Bottom -= half_width;
  }
}

void CPDF_TextObject::CalcCharPos(FX_FLOAT* pPosArray) const {
  CPDF_Font* pFont = m_TextState.GetFont();
  FX_BOOL bVertWriting = FALSE;
  CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
  if (pCIDFont) {
    bVertWriting = pCIDFont->IsVertWriting();
  }
  FX_FLOAT fontsize = m_TextState.GetFontSize();
  for (int i = 0, index = 0; i < m_nChars; ++i) {
    FX_DWORD charcode =
        m_nChars == 1 ? (FX_DWORD)(uintptr_t)m_pCharCodes : m_pCharCodes[i];
    if (charcode == (FX_DWORD)-1) {
      continue;
    }
    pPosArray[index++] = i ? m_pCharPos[i - 1] : 0;
    FX_FLOAT charwidth;
    if (bVertWriting) {
      FX_WORD CID = pCIDFont->CIDFromCharCode(charcode);
      charwidth = pCIDFont->GetVertWidth(CID) * fontsize / 1000;
    } else {
      charwidth = pFont->GetCharWidthF(charcode) * fontsize / 1000;
    }
    pPosArray[index] = pPosArray[index - 1] + charwidth;
    index++;
  }
}

void CPDF_TextObject::Transform(const CFX_Matrix& matrix) {
  m_TextState.GetModify();
  CFX_Matrix text_matrix;
  GetTextMatrix(&text_matrix);
  text_matrix.Concat(matrix);
  FX_FLOAT* pTextMatrix = m_TextState.GetMatrix();
  pTextMatrix[0] = text_matrix.GetA();
  pTextMatrix[1] = text_matrix.GetC();
  pTextMatrix[2] = text_matrix.GetB();
  pTextMatrix[3] = text_matrix.GetD();
  m_PosX = text_matrix.GetE();
  m_PosY = text_matrix.GetF();
  CalcPositionData(nullptr, nullptr, 0);
}

void CPDF_TextObject::SetPosition(FX_FLOAT x, FX_FLOAT y) {
  FX_FLOAT dx = x - m_PosX;
  FX_FLOAT dy = y - m_PosY;
  m_PosX = x;
  m_PosY = y;
  m_Left += dx;
  m_Right += dx;
  m_Top += dy;
  m_Bottom += dy;
}

void CPDF_TextObject::SetData(int nChars,
                              FX_DWORD* pCharCodes,
                              FX_FLOAT* pCharPos,
                              FX_FLOAT x,
                              FX_FLOAT y) {
  ASSERT(m_nChars == 0);
  m_nChars = nChars;
  m_PosX = x;
  m_PosY = y;
  if (nChars == 0) {
    return;
  }
  if (nChars == 1) {
    m_pCharCodes = (FX_DWORD*)(uintptr_t)*pCharCodes;
  } else {
    m_pCharCodes = FX_Alloc(FX_DWORD, nChars);
    FXSYS_memcpy(m_pCharCodes, pCharCodes, sizeof(FX_DWORD) * nChars);
    m_pCharPos = FX_Alloc(FX_FLOAT, nChars - 1);
    FXSYS_memcpy(m_pCharPos, pCharPos, sizeof(FX_FLOAT) * (nChars - 1));
  }
  RecalcPositionData();
}

void CPDF_TextObject::SetTextState(CPDF_TextState TextState) {
  m_TextState = TextState;
  CalcPositionData(nullptr, nullptr, 0);
}

CPDF_ShadingObject::CPDF_ShadingObject() {
  m_pShading = NULL;
  m_Type = PDFPAGE_SHADING;
}
CPDF_ShadingObject::~CPDF_ShadingObject() {}
void CPDF_ShadingObject::CopyData(const CPDF_PageObject* pSrc) {
  CPDF_ShadingObject* pSrcObj = (CPDF_ShadingObject*)pSrc;
  m_pShading = pSrcObj->m_pShading;
  if (m_pShading && m_pShading->m_pDocument) {
    CPDF_DocPageData* pDocPageData = m_pShading->m_pDocument->GetPageData();
    m_pShading = (CPDF_ShadingPattern*)pDocPageData->GetPattern(
        m_pShading->m_pShadingObj, m_pShading->m_bShadingObj,
        &m_pShading->m_ParentMatrix);
  }
  m_Matrix = pSrcObj->m_Matrix;
}
void CPDF_ShadingObject::Transform(const CFX_Matrix& matrix) {
  if (!m_ClipPath.IsNull()) {
    m_ClipPath.GetModify();
    m_ClipPath.Transform(matrix);
  }
  m_Matrix.Concat(matrix);
  if (!m_ClipPath.IsNull()) {
    CalcBoundingBox();
  } else {
    matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom);
  }
}
void CPDF_ShadingObject::CalcBoundingBox() {
  if (m_ClipPath.IsNull()) {
    return;
  }
  CFX_FloatRect rect = m_ClipPath.GetClipBox();
  m_Left = rect.left;
  m_Bottom = rect.bottom;
  m_Right = rect.right;
  m_Top = rect.top;
}
CPDF_FormObject::~CPDF_FormObject() {
  delete m_pForm;
}
void CPDF_FormObject::Transform(const CFX_Matrix& matrix) {
  m_FormMatrix.Concat(matrix);
  CalcBoundingBox();
}
void CPDF_FormObject::CopyData(const CPDF_PageObject* pSrc) {
  const CPDF_FormObject* pSrcObj = (const CPDF_FormObject*)pSrc;
  delete m_pForm;
  m_pForm = pSrcObj->m_pForm->Clone();
  m_FormMatrix = pSrcObj->m_FormMatrix;
}
void CPDF_FormObject::CalcBoundingBox() {
  CFX_FloatRect form_rect = m_pForm->CalcBoundingBox();
  form_rect.Transform(&m_FormMatrix);
  m_Left = form_rect.left;
  m_Bottom = form_rect.bottom;
  m_Right = form_rect.right;
  m_Top = form_rect.top;
}
CPDF_PageObjects::CPDF_PageObjects(FX_BOOL bReleaseMembers)
    : m_pFormDict(nullptr),
      m_pFormStream(nullptr),
      m_pDocument(nullptr),
      m_pPageResources(nullptr),
      m_pResources(nullptr),
      m_Transparency(0),
      m_ObjectList(128),
      m_bBackgroundAlphaNeeded(FALSE),
      m_bHasImageMask(FALSE),
      m_bReleaseMembers(bReleaseMembers),
      m_pParser(nullptr),
      m_ParseState(CONTENT_NOT_PARSED) {}
CPDF_PageObjects::~CPDF_PageObjects() {
  delete m_pParser;
  if (!m_bReleaseMembers) {
    return;
  }
  FX_POSITION pos = m_ObjectList.GetHeadPosition();
  while (pos) {
    delete (CPDF_PageObject*)m_ObjectList.GetNext(pos);
  }
}
void CPDF_PageObjects::ContinueParse(IFX_Pause* pPause) {
  if (!m_pParser) {
    return;
  }
  m_pParser->Continue(pPause);
  if (m_pParser->GetStatus() == CPDF_ContentParser::Done) {
    m_ParseState = CONTENT_PARSED;
    delete m_pParser;
    m_pParser = NULL;
  }
}
FX_POSITION CPDF_PageObjects::InsertObject(FX_POSITION posInsertAfter,
                                           CPDF_PageObject* pNewObject) {
  if (!posInsertAfter) {
    return m_ObjectList.AddHead(pNewObject);
  }
  return m_ObjectList.InsertAfter(posInsertAfter, pNewObject);
}
int CPDF_PageObjects::GetObjectIndex(CPDF_PageObject* pObj) const {
  int index = 0;
  FX_POSITION pos = m_ObjectList.GetHeadPosition();
  while (pos) {
    CPDF_PageObject* pThisObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos);
    if (pThisObj == pObj) {
      return index;
    }
    index++;
  }
  return -1;
}
CPDF_PageObject* CPDF_PageObjects::GetObjectByIndex(int index) const {
  FX_POSITION pos = m_ObjectList.FindIndex(index);
  return pos ? static_cast<CPDF_PageObject*>(m_ObjectList.GetAt(pos)) : nullptr;
}
void CPDF_PageObjects::Transform(const CFX_Matrix& matrix) {
  FX_POSITION pos = m_ObjectList.GetHeadPosition();
  while (pos) {
    CPDF_PageObject* pObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos);
    pObj->Transform(matrix);
  }
}
CFX_FloatRect CPDF_PageObjects::CalcBoundingBox() const {
  if (m_ObjectList.GetCount() == 0) {
    return CFX_FloatRect(0, 0, 0, 0);
  }
  FX_FLOAT left, right, top, bottom;
  left = bottom = 1000000 * 1.0f;
  right = top = -1000000 * 1.0f;
  FX_POSITION pos = m_ObjectList.GetHeadPosition();
  while (pos) {
    CPDF_PageObject* pObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos);
    if (left > pObj->m_Left) {
      left = pObj->m_Left;
    }
    if (right < pObj->m_Right) {
      right = pObj->m_Right;
    }
    if (top < pObj->m_Top) {
      top = pObj->m_Top;
    }
    if (bottom > pObj->m_Bottom) {
      bottom = pObj->m_Bottom;
    }
  }
  return CFX_FloatRect(left, bottom, right, top);
}
void CPDF_PageObjects::LoadTransInfo() {
  if (!m_pFormDict) {
    return;
  }
  CPDF_Dictionary* pGroup = m_pFormDict->GetDict("Group");
  if (!pGroup) {
    return;
  }
  if (pGroup->GetString("S") != "Transparency") {
    return;
  }
  m_Transparency |= PDFTRANS_GROUP;
  if (pGroup->GetInteger("I")) {
    m_Transparency |= PDFTRANS_ISOLATED;
  }
  if (pGroup->GetInteger("K")) {
    m_Transparency |= PDFTRANS_KNOCKOUT;
  }
}
void CPDF_PageObjects::ClearCacheObjects() {
  m_ParseState = CONTENT_NOT_PARSED;
  delete m_pParser;
  m_pParser = NULL;
  if (m_bReleaseMembers) {
    FX_POSITION pos = m_ObjectList.GetHeadPosition();
    while (pos) {
      delete (CPDF_PageObject*)m_ObjectList.GetNext(pos);
    }
  }
  m_ObjectList.RemoveAll();
}
CPDF_Page::CPDF_Page() {
  m_pPageRender = NULL;
}
void CPDF_Page::Load(CPDF_Document* pDocument,
                     CPDF_Dictionary* pPageDict,
                     FX_BOOL bPageCache) {
  m_pDocument = (CPDF_Document*)pDocument;
  m_pFormDict = pPageDict;
  if (bPageCache) {
    m_pPageRender =
        CPDF_ModuleMgr::Get()->GetRenderModule()->CreatePageCache(this);
  }
  if (!pPageDict) {
    m_PageWidth = m_PageHeight = 100 * 1.0f;
    m_pPageResources = m_pResources = NULL;
    return;
  }
  CPDF_Object* pageAttr = GetPageAttr("Resources");
  m_pResources = pageAttr ? pageAttr->GetDict() : NULL;
  m_pPageResources = m_pResources;
  CPDF_Object* pRotate = GetPageAttr("Rotate");
  int rotate = 0;
  if (pRotate) {
    rotate = pRotate->GetInteger() / 90 % 4;
  }
  if (rotate < 0) {
    rotate += 4;
  }
  CPDF_Array* pMediaBox = ToArray(GetPageAttr("MediaBox"));
  CFX_FloatRect mediabox;
  if (pMediaBox) {
    mediabox = pMediaBox->GetRect();
    mediabox.Normalize();
  }
  if (mediabox.IsEmpty()) {
    mediabox = CFX_FloatRect(0, 0, 612, 792);
  }

  CPDF_Array* pCropBox = ToArray(GetPageAttr("CropBox"));
  if (pCropBox) {
    m_BBox = pCropBox->GetRect();
    m_BBox.Normalize();
  }
  if (m_BBox.IsEmpty()) {
    m_BBox = mediabox;
  } else {
    m_BBox.Intersect(mediabox);
  }
  if (rotate % 2) {
    m_PageHeight = m_BBox.right - m_BBox.left;
    m_PageWidth = m_BBox.top - m_BBox.bottom;
  } else {
    m_PageWidth = m_BBox.right - m_BBox.left;
    m_PageHeight = m_BBox.top - m_BBox.bottom;
  }
  switch (rotate) {
    case 0:
      m_PageMatrix.Set(1.0f, 0, 0, 1.0f, -m_BBox.left, -m_BBox.bottom);
      break;
    case 1:
      m_PageMatrix.Set(0, -1.0f, 1.0f, 0, -m_BBox.bottom, m_BBox.right);
      break;
    case 2:
      m_PageMatrix.Set(-1.0f, 0, 0, -1.0f, m_BBox.right, m_BBox.top);
      break;
    case 3:
      m_PageMatrix.Set(0, 1.0f, -1.0f, 0, m_BBox.top, -m_BBox.left);
      break;
  }
  m_Transparency = PDFTRANS_ISOLATED;
  LoadTransInfo();
}
void CPDF_Page::StartParse(CPDF_ParseOptions* pOptions, FX_BOOL bReParse) {
  if (bReParse) {
    ClearCacheObjects();
  }
  if (m_ParseState == CONTENT_PARSED || m_ParseState == CONTENT_PARSING) {
    return;
  }
  m_pParser = new CPDF_ContentParser;
  m_pParser->Start(this, pOptions);
  m_ParseState = CONTENT_PARSING;
}
void CPDF_Page::ParseContent(CPDF_ParseOptions* pOptions, FX_BOOL bReParse) {
  StartParse(pOptions, bReParse);
  ContinueParse(NULL);
}
CPDF_Page::~CPDF_Page() {
  if (m_pPageRender) {
    IPDF_RenderModule* pModule = CPDF_ModuleMgr::Get()->GetRenderModule();
    pModule->DestroyPageCache(m_pPageRender);
  }
}
CPDF_Object* FPDFAPI_GetPageAttr(CPDF_Dictionary* pPageDict,
                                 const CFX_ByteStringC& name) {
  int level = 0;
  while (1) {
    CPDF_Object* pObj = pPageDict->GetElementValue(name);
    if (pObj) {
      return pObj;
    }
    CPDF_Dictionary* pParent = pPageDict->GetDict("Parent");
    if (!pParent || pParent == pPageDict) {
      return NULL;
    }
    pPageDict = pParent;
    level++;
    if (level == 1000) {
      return NULL;
    }
  }
}
CPDF_Object* CPDF_Page::GetPageAttr(const CFX_ByteStringC& name) const {
  return FPDFAPI_GetPageAttr(m_pFormDict, name);
}
CPDF_Form::CPDF_Form(CPDF_Document* pDoc,
                     CPDF_Dictionary* pPageResources,
                     CPDF_Stream* pFormStream,
                     CPDF_Dictionary* pParentResources) {
  m_pDocument = pDoc;
  m_pFormStream = pFormStream;
  m_pFormDict = pFormStream ? pFormStream->GetDict() : NULL;
  m_pResources = m_pFormDict->GetDict("Resources");
  m_pPageResources = pPageResources;
  if (!m_pResources) {
    m_pResources = pParentResources;
  }
  if (!m_pResources) {
    m_pResources = pPageResources;
  }
  m_Transparency = 0;
  LoadTransInfo();
}
CPDF_Form::~CPDF_Form() {}
void CPDF_Form::StartParse(CPDF_AllStates* pGraphicStates,
                           CFX_Matrix* pParentMatrix,
                           CPDF_Type3Char* pType3Char,
                           CPDF_ParseOptions* pOptions,
                           int level) {
  if (m_ParseState == CONTENT_PARSED || m_ParseState == CONTENT_PARSING) {
    return;
  }
  m_pParser = new CPDF_ContentParser;
  m_pParser->Start(this, pGraphicStates, pParentMatrix, pType3Char, pOptions,
                   level);
  m_ParseState = CONTENT_PARSING;
}
void CPDF_Form::ParseContent(CPDF_AllStates* pGraphicStates,
                             CFX_Matrix* pParentMatrix,
                             CPDF_Type3Char* pType3Char,
                             CPDF_ParseOptions* pOptions,
                             int level) {
  StartParse(pGraphicStates, pParentMatrix, pType3Char, pOptions, level);
  ContinueParse(NULL);
}
CPDF_Form* CPDF_Form::Clone() const {
  CPDF_Form* pClone =
      new CPDF_Form(m_pDocument, m_pPageResources, m_pFormStream, m_pResources);
  FX_POSITION pos = m_ObjectList.GetHeadPosition();
  while (pos) {
    CPDF_PageObject* pObj = (CPDF_PageObject*)m_ObjectList.GetNext(pos);
    pClone->m_ObjectList.AddTail(pObj->Clone());
  }
  return pClone;
}
void CPDF_Page::GetDisplayMatrix(CFX_Matrix& matrix,
                                 int xPos,
                                 int yPos,
                                 int xSize,
                                 int ySize,
                                 int iRotate) const {
  if (m_PageWidth == 0 || m_PageHeight == 0) {
    return;
  }
  CFX_Matrix display_matrix;
  int x0, y0, x1, y1, x2, y2;
  iRotate %= 4;
  switch (iRotate) {
    case 0:
      x0 = xPos;
      y0 = yPos + ySize;
      x1 = xPos;
      y1 = yPos;
      x2 = xPos + xSize;
      y2 = yPos + ySize;
      break;
    case 1:
      x0 = xPos;
      y0 = yPos;
      x1 = xPos + xSize;
      y1 = yPos;
      x2 = xPos;
      y2 = yPos + ySize;
      break;
    case 2:
      x0 = xPos + xSize;
      y0 = yPos;
      x1 = xPos + xSize;
      y1 = yPos + ySize;
      x2 = xPos;
      y2 = yPos;
      break;
    case 3:
      x0 = xPos + xSize;
      y0 = yPos + ySize;
      x1 = xPos;
      y1 = yPos + ySize;
      x2 = xPos + xSize;
      y2 = yPos;
      break;
  }
  display_matrix.Set(FXSYS_Div((FX_FLOAT)(x2 - x0), m_PageWidth),
                     FXSYS_Div((FX_FLOAT)(y2 - y0), m_PageWidth),
                     FXSYS_Div((FX_FLOAT)(x1 - x0), m_PageHeight),
                     FXSYS_Div((FX_FLOAT)(y1 - y0), m_PageHeight), (FX_FLOAT)x0,
                     (FX_FLOAT)y0);
  matrix = m_PageMatrix;
  matrix.Concat(display_matrix);
}
CPDF_ParseOptions::CPDF_ParseOptions() {
  m_bTextOnly = FALSE;
  m_bMarkedContent = TRUE;
  m_bSeparateForm = TRUE;
  m_bDecodeInlineImage = FALSE;
}
