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

#include <algorithm>

#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
#include "core/fpdfapi/fpdf_render/render_int.h"
#include "core/include/fpdfapi/fpdf_pageobj.h"
#include "third_party/base/stl_util.h"

namespace {

FX_FLOAT ClipFloat(FX_FLOAT f) {
  return std::max(0.0f, std::min(1.0f, f));
}

}  // namespace

void CPDF_GraphicStates::DefaultStates() {
  m_ColorState.New()->Default();
}
void CPDF_GraphicStates::CopyStates(const CPDF_GraphicStates& src) {
  m_ClipPath = src.m_ClipPath;
  m_GraphState = src.m_GraphState;
  m_ColorState = src.m_ColorState;
  m_TextState = src.m_TextState;
  m_GeneralState = src.m_GeneralState;
}
CPDF_ClipPathData::CPDF_ClipPathData() {
  m_PathCount = 0;
  m_pPathList = NULL;
  m_pTypeList = NULL;
  m_TextCount = 0;
  m_pTextList = NULL;
}
CPDF_ClipPathData::~CPDF_ClipPathData() {
  int i;
  delete[] m_pPathList;
  FX_Free(m_pTypeList);
  for (i = m_TextCount - 1; i > -1; i--)
    delete m_pTextList[i];
  FX_Free(m_pTextList);
}
CPDF_ClipPathData::CPDF_ClipPathData(const CPDF_ClipPathData& src) {
  m_pPathList = NULL;
  m_pPathList = NULL;
  m_pTextList = NULL;
  m_PathCount = src.m_PathCount;
  if (m_PathCount) {
    int alloc_size = m_PathCount;
    if (alloc_size % 8) {
      alloc_size += 8 - (alloc_size % 8);
    }
    m_pPathList = new CPDF_Path[alloc_size];
    for (int i = 0; i < m_PathCount; i++) {
      m_pPathList[i] = src.m_pPathList[i];
    }
    m_pTypeList = FX_Alloc(uint8_t, alloc_size);
    FXSYS_memcpy(m_pTypeList, src.m_pTypeList, m_PathCount);
  } else {
    m_pPathList = NULL;
    m_pTypeList = NULL;
  }
  m_TextCount = src.m_TextCount;
  if (m_TextCount) {
    m_pTextList = FX_Alloc(CPDF_TextObject*, m_TextCount);
    for (int i = 0; i < m_TextCount; i++) {
      if (src.m_pTextList[i]) {
        m_pTextList[i] = src.m_pTextList[i]->Clone();
      } else {
        m_pTextList[i] = NULL;
      }
    }
  } else {
    m_pTextList = NULL;
  }
}
void CPDF_ClipPathData::SetCount(int path_count, int text_count) {
  ASSERT(m_TextCount == 0 && m_PathCount == 0);
  if (path_count) {
    m_PathCount = path_count;
    int alloc_size = (path_count + 7) / 8 * 8;
    m_pPathList = new CPDF_Path[alloc_size];
    m_pTypeList = FX_Alloc(uint8_t, alloc_size);
  }
  if (text_count) {
    m_TextCount = text_count;
    m_pTextList = FX_Alloc(CPDF_TextObject*, text_count);
  }
}
CFX_FloatRect CPDF_ClipPath::GetClipBox() const {
  CFX_FloatRect rect;
  FX_BOOL bStarted = FALSE;
  int count = GetPathCount();
  if (count) {
    rect = GetPath(0).GetBoundingBox();
    for (int i = 1; i < count; i++) {
      CFX_FloatRect path_rect = GetPath(i).GetBoundingBox();
      rect.Intersect(path_rect);
    }
    bStarted = TRUE;
  }
  count = GetTextCount();
  if (count) {
    CFX_FloatRect layer_rect;
    FX_BOOL bLayerStarted = FALSE;
    for (int i = 0; i < count; i++) {
      CPDF_TextObject* pTextObj = GetText(i);
      if (!pTextObj) {
        if (!bStarted) {
          rect = layer_rect;
          bStarted = TRUE;
        } else {
          rect.Intersect(layer_rect);
        }
        bLayerStarted = FALSE;
      } else {
        if (!bLayerStarted) {
          layer_rect = CFX_FloatRect(pTextObj->GetBBox(nullptr));
          bLayerStarted = TRUE;
        } else {
          layer_rect.Union(CFX_FloatRect(pTextObj->GetBBox(nullptr)));
        }
      }
    }
  }
  return rect;
}
void CPDF_ClipPath::AppendPath(CPDF_Path path, int type, FX_BOOL bAutoMerge) {
  CPDF_ClipPathData* pData = GetModify();
  if (pData->m_PathCount && bAutoMerge) {
    CPDF_Path old_path = pData->m_pPathList[pData->m_PathCount - 1];
    if (old_path.IsRect()) {
      CFX_FloatRect old_rect(old_path.GetPointX(0), old_path.GetPointY(0),
                             old_path.GetPointX(2), old_path.GetPointY(2));
      CFX_FloatRect new_rect = path.GetBoundingBox();
      if (old_rect.Contains(new_rect)) {
        pData->m_PathCount--;
        pData->m_pPathList[pData->m_PathCount].SetNull();
      }
    }
  }
  if (pData->m_PathCount % 8 == 0) {
    CPDF_Path* pNewPath = new CPDF_Path[pData->m_PathCount + 8];
    for (int i = 0; i < pData->m_PathCount; i++) {
      pNewPath[i] = pData->m_pPathList[i];
    }
    delete[] pData->m_pPathList;
    uint8_t* pNewType = FX_Alloc(uint8_t, pData->m_PathCount + 8);
    FXSYS_memcpy(pNewType, pData->m_pTypeList, pData->m_PathCount);
    FX_Free(pData->m_pTypeList);
    pData->m_pPathList = pNewPath;
    pData->m_pTypeList = pNewType;
  }
  pData->m_pPathList[pData->m_PathCount] = path;
  pData->m_pTypeList[pData->m_PathCount] = (uint8_t)type;
  pData->m_PathCount++;
}
void CPDF_ClipPath::DeletePath(int index) {
  CPDF_ClipPathData* pData = GetModify();
  if (index >= pData->m_PathCount) {
    return;
  }
  pData->m_pPathList[index].SetNull();
  for (int i = index; i < pData->m_PathCount - 1; i++) {
    pData->m_pPathList[i] = pData->m_pPathList[i + 1];
  }
  pData->m_pPathList[pData->m_PathCount - 1].SetNull();
  FXSYS_memmove(pData->m_pTypeList + index, pData->m_pTypeList + index + 1,
                pData->m_PathCount - index - 1);
  pData->m_PathCount--;
}
#define FPDF_CLIPPATH_MAX_TEXTS 1024
void CPDF_ClipPath::AppendTexts(CPDF_TextObject** pTexts, int count) {
  CPDF_ClipPathData* pData = GetModify();
  if (pData->m_TextCount + count > FPDF_CLIPPATH_MAX_TEXTS) {
    for (int i = 0; i < count; i++) {
      delete pTexts[i];
    }
    return;
  }
  CPDF_TextObject** pNewList =
      FX_Alloc(CPDF_TextObject*, pData->m_TextCount + count + 1);
  if (pData->m_pTextList) {
    FXSYS_memcpy(pNewList, pData->m_pTextList,
                 pData->m_TextCount * sizeof(CPDF_TextObject*));
    FX_Free(pData->m_pTextList);
  }
  pData->m_pTextList = pNewList;
  for (int i = 0; i < count; i++) {
    pData->m_pTextList[pData->m_TextCount + i] = pTexts[i];
  }
  pData->m_pTextList[pData->m_TextCount + count] = NULL;
  pData->m_TextCount += count + 1;
}
void CPDF_ClipPath::Transform(const CFX_Matrix& matrix) {
  CPDF_ClipPathData* pData = GetModify();
  int i;
  for (i = 0; i < pData->m_PathCount; i++) {
    pData->m_pPathList[i].Transform(&matrix);
  }
  for (i = 0; i < pData->m_TextCount; i++)
    if (pData->m_pTextList[i]) {
      pData->m_pTextList[i]->Transform(matrix);
    }
}
CPDF_ColorStateData::CPDF_ColorStateData(const CPDF_ColorStateData& src) {
  m_FillColor.Copy(&src.m_FillColor);
  m_FillRGB = src.m_FillRGB;
  m_StrokeColor.Copy(&src.m_StrokeColor);
  m_StrokeRGB = src.m_StrokeRGB;
}
void CPDF_ColorStateData::Default() {
  m_FillRGB = m_StrokeRGB = 0;
  m_FillColor.SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY));
  m_StrokeColor.SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY));
}
void CPDF_ColorState::SetFillColor(CPDF_ColorSpace* pCS,
                                   FX_FLOAT* pValue,
                                   int nValues) {
  CPDF_ColorStateData* pData = GetModify();
  SetColor(pData->m_FillColor, pData->m_FillRGB, pCS, pValue, nValues);
}
void CPDF_ColorState::SetStrokeColor(CPDF_ColorSpace* pCS,
                                     FX_FLOAT* pValue,
                                     int nValues) {
  CPDF_ColorStateData* pData = GetModify();
  SetColor(pData->m_StrokeColor, pData->m_StrokeRGB, pCS, pValue, nValues);
}
void CPDF_ColorState::SetColor(CPDF_Color& color,
                               FX_DWORD& rgb,
                               CPDF_ColorSpace* pCS,
                               FX_FLOAT* pValue,
                               int nValues) {
  if (pCS) {
    color.SetColorSpace(pCS);
  } else if (color.IsNull()) {
    color.SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY));
  }
  if (color.m_pCS->CountComponents() > nValues) {
    return;
  }
  color.SetValue(pValue);
  int R, G, B;
  rgb = color.GetRGB(R, G, B) ? FXSYS_RGB(R, G, B) : (FX_DWORD)-1;
}
void CPDF_ColorState::SetFillPattern(CPDF_Pattern* pPattern,
                                     FX_FLOAT* pValue,
                                     int nValues) {
  CPDF_ColorStateData* pData = GetModify();
  pData->m_FillColor.SetValue(pPattern, pValue, nValues);
  int R, G, B;
  FX_BOOL ret = pData->m_FillColor.GetRGB(R, G, B);
  if (pPattern->m_PatternType == 1 &&
      ((CPDF_TilingPattern*)pPattern)->m_bColored && !ret) {
    pData->m_FillRGB = 0x00BFBFBF;
    return;
  }
  pData->m_FillRGB = ret ? FXSYS_RGB(R, G, B) : (FX_DWORD)-1;
}
void CPDF_ColorState::SetStrokePattern(CPDF_Pattern* pPattern,
                                       FX_FLOAT* pValue,
                                       int nValues) {
  CPDF_ColorStateData* pData = GetModify();
  pData->m_StrokeColor.SetValue(pPattern, pValue, nValues);
  int R, G, B;
  FX_BOOL ret = pData->m_StrokeColor.GetRGB(R, G, B);
  if (pPattern->m_PatternType == 1 &&
      ((CPDF_TilingPattern*)pPattern)->m_bColored && !ret) {
    pData->m_StrokeRGB = 0x00BFBFBF;
    return;
  }
  pData->m_StrokeRGB =
      pData->m_StrokeColor.GetRGB(R, G, B) ? FXSYS_RGB(R, G, B) : (FX_DWORD)-1;
}
CPDF_TextStateData::CPDF_TextStateData() {
  m_pFont = NULL;
  m_pDocument = NULL;
  m_FontSize = 1.0f;
  m_WordSpace = 0;
  m_CharSpace = 0;
  m_TextMode = 0;
  m_Matrix[0] = m_Matrix[3] = 1.0f;
  m_Matrix[1] = m_Matrix[2] = 0;
  m_CTM[0] = m_CTM[3] = 1.0f;
  m_CTM[1] = m_CTM[2] = 0;
}
CPDF_TextStateData::CPDF_TextStateData(const CPDF_TextStateData& src) {
  if (this == &src) {
    return;
  }
  FXSYS_memcpy(this, &src, sizeof(CPDF_TextStateData));
  if (m_pDocument && m_pFont) {
    m_pFont =
        m_pDocument->GetPageData()->GetFont(m_pFont->GetFontDict(), FALSE);
  }
}
CPDF_TextStateData::~CPDF_TextStateData() {
  if (m_pDocument && m_pFont) {
    CPDF_DocPageData* pPageData = m_pDocument->GetPageData();
    if (pPageData && !pPageData->IsForceClear()) {
      pPageData->ReleaseFont(m_pFont->GetFontDict());
    }
  }
}
void CPDF_TextState::SetFont(CPDF_Font* pFont) {
  CPDF_TextStateData* pStateData = GetModify();
  if (pStateData) {
    CPDF_Document* pDoc = pStateData->m_pDocument;
    CPDF_DocPageData* pPageData = pDoc ? pDoc->GetPageData() : NULL;
    if (pPageData && pStateData->m_pFont && !pPageData->IsForceClear()) {
      pPageData->ReleaseFont(pStateData->m_pFont->GetFontDict());
    }
    pStateData->m_pDocument = pFont ? pFont->m_pDocument : NULL;
    pStateData->m_pFont = pFont;
  }
}
FX_FLOAT CPDF_TextState::GetFontSizeV() const {
  FX_FLOAT* pMatrix = GetMatrix();
  FX_FLOAT unit = FXSYS_sqrt2(pMatrix[1], pMatrix[3]);
  FX_FLOAT size = unit * GetFontSize();
  return (FX_FLOAT)FXSYS_fabs(size);
}
FX_FLOAT CPDF_TextState::GetFontSizeH() const {
  FX_FLOAT* pMatrix = GetMatrix();
  FX_FLOAT unit = FXSYS_sqrt2(pMatrix[0], pMatrix[2]);
  FX_FLOAT size = unit * GetFontSize();
  return (FX_FLOAT)FXSYS_fabs(size);
}
FX_FLOAT CPDF_TextState::GetBaselineAngle() const {
  FX_FLOAT* m_Matrix = GetMatrix();
  return FXSYS_atan2(m_Matrix[2], m_Matrix[0]);
}
FX_FLOAT CPDF_TextState::GetShearAngle() const {
  FX_FLOAT* m_Matrix = GetMatrix();
  FX_FLOAT shear_angle = FXSYS_atan2(m_Matrix[1], m_Matrix[3]);
  return GetBaselineAngle() + shear_angle;
}
CPDF_GeneralStateData::CPDF_GeneralStateData() {
  FXSYS_memset(this, 0, sizeof(CPDF_GeneralStateData));
  FXSYS_strcpy((FX_CHAR*)m_BlendMode, "Normal");
  m_StrokeAlpha = 1.0f;
  m_FillAlpha = 1.0f;
  m_Flatness = 1.0f;
  m_Matrix.SetIdentity();
}
CPDF_GeneralStateData::CPDF_GeneralStateData(const CPDF_GeneralStateData& src) {
  FXSYS_memcpy(this, &src, sizeof(CPDF_GeneralStateData));
  if (src.m_pTransferFunc && src.m_pTransferFunc->m_pPDFDoc) {
    CPDF_DocRenderData* pDocCache =
        src.m_pTransferFunc->m_pPDFDoc->GetRenderData();
    if (!pDocCache) {
      return;
    }
    m_pTransferFunc = pDocCache->GetTransferFunc(m_pTR);
  }
}
CPDF_GeneralStateData::~CPDF_GeneralStateData() {
  if (m_pTransferFunc && m_pTransferFunc->m_pPDFDoc) {
    CPDF_DocRenderData* pDocCache = m_pTransferFunc->m_pPDFDoc->GetRenderData();
    if (!pDocCache) {
      return;
    }
    pDocCache->ReleaseTransferFunc(m_pTR);
  }
}
static int GetBlendType(const CFX_ByteStringC& mode) {
  switch (mode.GetID()) {
    case FXBSTR_ID('N', 'o', 'r', 'm'):
    case FXBSTR_ID('C', 'o', 'm', 'p'):
      return FXDIB_BLEND_NORMAL;
    case FXBSTR_ID('M', 'u', 'l', 't'):
      return FXDIB_BLEND_MULTIPLY;
    case FXBSTR_ID('S', 'c', 'r', 'e'):
      return FXDIB_BLEND_SCREEN;
    case FXBSTR_ID('O', 'v', 'e', 'r'):
      return FXDIB_BLEND_OVERLAY;
    case FXBSTR_ID('D', 'a', 'r', 'k'):
      return FXDIB_BLEND_DARKEN;
    case FXBSTR_ID('L', 'i', 'g', 'h'):
      return FXDIB_BLEND_LIGHTEN;
    case FXBSTR_ID('C', 'o', 'l', 'o'):
      if (mode.GetLength() == 10) {
        return FXDIB_BLEND_COLORDODGE;
      }
      if (mode.GetLength() == 9) {
        return FXDIB_BLEND_COLORBURN;
      }
      return FXDIB_BLEND_COLOR;
    case FXBSTR_ID('H', 'a', 'r', 'd'):
      return FXDIB_BLEND_HARDLIGHT;
    case FXBSTR_ID('S', 'o', 'f', 't'):
      return FXDIB_BLEND_SOFTLIGHT;
    case FXBSTR_ID('D', 'i', 'f', 'f'):
      return FXDIB_BLEND_DIFFERENCE;
    case FXBSTR_ID('E', 'x', 'c', 'l'):
      return FXDIB_BLEND_EXCLUSION;
    case FXBSTR_ID('H', 'u', 'e', 0):
      return FXDIB_BLEND_HUE;
    case FXBSTR_ID('S', 'a', 't', 'u'):
      return FXDIB_BLEND_SATURATION;
    case FXBSTR_ID('L', 'u', 'm', 'i'):
      return FXDIB_BLEND_LUMINOSITY;
  }
  return FXDIB_BLEND_NORMAL;
}
void CPDF_GeneralStateData::SetBlendMode(const CFX_ByteStringC& blend_mode) {
  if (blend_mode.GetLength() > 15) {
    return;
  }
  FXSYS_memcpy(m_BlendMode, blend_mode.GetPtr(), blend_mode.GetLength());
  m_BlendMode[blend_mode.GetLength()] = 0;
  m_BlendType = ::GetBlendType(blend_mode);
}
int RI_StringToId(const CFX_ByteString& ri) {
  FX_DWORD id = ri.GetID();
  if (id == FXBSTR_ID('A', 'b', 's', 'o')) {
    return 1;
  }
  if (id == FXBSTR_ID('S', 'a', 't', 'u')) {
    return 2;
  }
  if (id == FXBSTR_ID('P', 'e', 'r', 'c')) {
    return 3;
  }
  return 0;
}
void CPDF_GeneralState::SetRenderIntent(const CFX_ByteString& ri) {
  GetModify()->m_RenderIntent = RI_StringToId(ri);
}
CPDF_AllStates::CPDF_AllStates() {
  m_TextX = m_TextY = m_TextLineX = m_TextLineY = 0;
  m_TextLeading = 0;
  m_TextRise = 0;
  m_TextHorzScale = 1.0f;
}
CPDF_AllStates::~CPDF_AllStates() {}
void CPDF_AllStates::Copy(const CPDF_AllStates& src) {
  CopyStates(src);
  m_TextMatrix.Copy(src.m_TextMatrix);
  m_ParentMatrix.Copy(src.m_ParentMatrix);
  m_CTM.Copy(src.m_CTM);
  m_TextX = src.m_TextX;
  m_TextY = src.m_TextY;
  m_TextLineX = src.m_TextLineX;
  m_TextLineY = src.m_TextLineY;
  m_TextLeading = src.m_TextLeading;
  m_TextRise = src.m_TextRise;
  m_TextHorzScale = src.m_TextHorzScale;
}
void CPDF_AllStates::SetLineDash(CPDF_Array* pArray,
                                 FX_FLOAT phase,
                                 FX_FLOAT scale) {
  CFX_GraphStateData* pData = m_GraphState.GetModify();
  pData->m_DashPhase = phase * scale;
  pData->SetDashCount(pArray->GetCount());
  for (FX_DWORD i = 0; i < pArray->GetCount(); i++) {
    pData->m_DashArray[i] = pArray->GetNumberAt(i) * scale;
  }
}
void CPDF_AllStates::ProcessExtGS(CPDF_Dictionary* pGS,
                                  CPDF_StreamContentParser* pParser) {
  CPDF_GeneralStateData* pGeneralState = m_GeneralState.GetModify();
  for (const auto& it : *pGS) {
    const CFX_ByteString& key_str = it.first;
    CPDF_Object* pElement = it.second;
    CPDF_Object* pObject = pElement ? pElement->GetDirect() : nullptr;
    if (!pObject)
      continue;

    FX_DWORD key = key_str.GetID();
    switch (key) {
      case FXBSTR_ID('L', 'W', 0, 0):
        m_GraphState.GetModify()->m_LineWidth = pObject->GetNumber();
        break;
      case FXBSTR_ID('L', 'C', 0, 0):
        m_GraphState.GetModify()->m_LineCap =
            (CFX_GraphStateData::LineCap)pObject->GetInteger();
        break;
      case FXBSTR_ID('L', 'J', 0, 0):
        m_GraphState.GetModify()->m_LineJoin =
            (CFX_GraphStateData::LineJoin)pObject->GetInteger();
        break;
      case FXBSTR_ID('M', 'L', 0, 0):
        m_GraphState.GetModify()->m_MiterLimit = pObject->GetNumber();
        break;
      case FXBSTR_ID('D', 0, 0, 0): {
        CPDF_Array* pDash = pObject->AsArray();
        if (!pDash)
          break;

        CPDF_Array* pArray = pDash->GetArrayAt(0);
        if (!pArray)
          break;

        SetLineDash(pArray, pDash->GetNumberAt(1), 1.0f);
        break;
      }
      case FXBSTR_ID('R', 'I', 0, 0):
        m_GeneralState.SetRenderIntent(pObject->GetString());
        break;
      case FXBSTR_ID('F', 'o', 'n', 't'): {
        CPDF_Array* pFont = pObject->AsArray();
        if (!pFont)
          break;

        m_TextState.GetModify()->m_FontSize = pFont->GetNumberAt(1);
        m_TextState.SetFont(pParser->FindFont(pFont->GetStringAt(0)));
        break;
      }
      case FXBSTR_ID('T', 'R', 0, 0):
        if (pGS->KeyExist("TR2")) {
          continue;
        }
      case FXBSTR_ID('T', 'R', '2', 0):
        pGeneralState->m_pTR =
            (pObject && !pObject->IsName()) ? pObject : nullptr;
        break;
      case FXBSTR_ID('B', 'M', 0, 0): {
        CPDF_Array* pArray = pObject->AsArray();
        CFX_ByteString mode =
            pArray ? pArray->GetStringAt(0) : pObject->GetString();

        pGeneralState->SetBlendMode(mode);
        if (pGeneralState->m_BlendType > FXDIB_BLEND_MULTIPLY) {
          pParser->GetPageObjectHolder()->SetBackgroundAlphaNeeded(TRUE);
        }
        break;
      }
      case FXBSTR_ID('S', 'M', 'a', 's'):
        if (ToDictionary(pObject)) {
          pGeneralState->m_pSoftMask = pObject;
          FXSYS_memcpy(pGeneralState->m_SMaskMatrix,
                       &pParser->GetCurStates()->m_CTM, sizeof(CFX_Matrix));
        } else {
          pGeneralState->m_pSoftMask = NULL;
        }
        break;
      case FXBSTR_ID('C', 'A', 0, 0):
        pGeneralState->m_StrokeAlpha = ClipFloat(pObject->GetNumber());
        break;
      case FXBSTR_ID('c', 'a', 0, 0):
        pGeneralState->m_FillAlpha = ClipFloat(pObject->GetNumber());
        break;
      case FXBSTR_ID('O', 'P', 0, 0):
        pGeneralState->m_StrokeOP = pObject->GetInteger();
        if (!pGS->KeyExist("op")) {
          pGeneralState->m_FillOP = pObject->GetInteger();
        }
        break;
      case FXBSTR_ID('o', 'p', 0, 0):
        pGeneralState->m_FillOP = pObject->GetInteger();
        break;
      case FXBSTR_ID('O', 'P', 'M', 0):
        pGeneralState->m_OPMode = pObject->GetInteger();
        break;
      case FXBSTR_ID('B', 'G', 0, 0):
        if (pGS->KeyExist("BG2")) {
          continue;
        }
      case FXBSTR_ID('B', 'G', '2', 0):
        pGeneralState->m_pBG = pObject;
        break;
      case FXBSTR_ID('U', 'C', 'R', 0):
        if (pGS->KeyExist("UCR2")) {
          continue;
        }
      case FXBSTR_ID('U', 'C', 'R', '2'):
        pGeneralState->m_pUCR = pObject;
        break;
      case FXBSTR_ID('H', 'T', 0, 0):
        pGeneralState->m_pHT = pObject;
        break;
      case FXBSTR_ID('F', 'L', 0, 0):
        pGeneralState->m_Flatness = pObject->GetNumber();
        break;
      case FXBSTR_ID('S', 'M', 0, 0):
        pGeneralState->m_Smoothness = pObject->GetNumber();
        break;
      case FXBSTR_ID('S', 'A', 0, 0):
        pGeneralState->m_StrokeAdjust = pObject->GetInteger();
        break;
      case FXBSTR_ID('A', 'I', 'S', 0):
        pGeneralState->m_AlphaSource = pObject->GetInteger();
        break;
      case FXBSTR_ID('T', 'K', 0, 0):
        pGeneralState->m_TextKnockout = pObject->GetInteger();
        break;
    }
  }
  pGeneralState->m_Matrix = m_CTM;
}
CPDF_ContentMarkItem::CPDF_ContentMarkItem() {
  m_ParamType = None;
}
CPDF_ContentMarkItem::CPDF_ContentMarkItem(const CPDF_ContentMarkItem& src) {
  m_MarkName = src.m_MarkName;
  m_ParamType = src.m_ParamType;
  if (m_ParamType == DirectDict) {
    m_pParam = ToDictionary(src.m_pParam->Clone());
  } else {
    m_pParam = src.m_pParam;
  }
}
CPDF_ContentMarkItem::~CPDF_ContentMarkItem() {
  if (m_ParamType == DirectDict && m_pParam)
    m_pParam->Release();
}
FX_BOOL CPDF_ContentMarkItem::HasMCID() const {
  if (m_pParam &&
      (m_ParamType == DirectDict || m_ParamType == PropertiesDict)) {
    return m_pParam->KeyExist("MCID");
  }
  return FALSE;
}

CPDF_ContentMarkData::CPDF_ContentMarkData(const CPDF_ContentMarkData& src)
    : m_Marks(src.m_Marks) {}

int CPDF_ContentMarkData::CountItems() const {
  return pdfium::CollectionSize<int>(m_Marks);
}

int CPDF_ContentMarkData::GetMCID() const {
  for (const auto& mark : m_Marks) {
    CPDF_ContentMarkItem::ParamType type = mark.GetParamType();
    if (type == CPDF_ContentMarkItem::PropertiesDict ||
        type == CPDF_ContentMarkItem::DirectDict) {
      CPDF_Dictionary* pDict = mark.GetParam();
      if (pDict->KeyExist("MCID"))
        return pDict->GetIntegerBy("MCID");
    }
  }
  return -1;
}

void CPDF_ContentMarkData::AddMark(const CFX_ByteString& name,
                                   CPDF_Dictionary* pDict,
                                   FX_BOOL bDirect) {
  CPDF_ContentMarkItem item;
  item.SetName(name);
  if (pDict) {
    if (bDirect) {
      item.SetParam(CPDF_ContentMarkItem::DirectDict,
                    ToDictionary(pDict->Clone()));
    } else {
      item.SetParam(CPDF_ContentMarkItem::PropertiesDict, pDict);
    }
  }
  m_Marks.push_back(item);
}

void CPDF_ContentMarkData::DeleteLastMark() {
  if (!m_Marks.empty())
    m_Marks.pop_back();
}

FX_BOOL CPDF_ContentMark::HasMark(const CFX_ByteStringC& mark) const {
  if (!m_pObject) {
    return FALSE;
  }
  for (int i = 0; i < m_pObject->CountItems(); i++) {
    CPDF_ContentMarkItem& item = m_pObject->GetItem(i);
    if (item.GetName() == mark) {
      return TRUE;
    }
  }
  return FALSE;
}
FX_BOOL CPDF_ContentMark::LookupMark(const CFX_ByteStringC& mark,
                                     CPDF_Dictionary*& pDict) const {
  if (!m_pObject) {
    return FALSE;
  }
  for (int i = 0; i < m_pObject->CountItems(); i++) {
    CPDF_ContentMarkItem& item = m_pObject->GetItem(i);
    if (item.GetName() == mark) {
      pDict = NULL;
      if (item.GetParamType() == CPDF_ContentMarkItem::PropertiesDict ||
          item.GetParamType() == CPDF_ContentMarkItem::DirectDict) {
        pDict = item.GetParam();
      }
      return TRUE;
    }
  }
  return FALSE;
}
