// 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 "../../../include/fpdfapi/fpdf_page.h"
#include "../../../include/fpdfapi/fpdf_pageobj.h"
#include "../../../include/fpdfapi/fpdf_module.h"
#include "../../../include/fpdfapi/fpdf_render.h"
#include "../fpdf_render/render_int.h"
#include "pageint.h"

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] = new CPDF_TextObject;
        m_pTextList[i]->Copy(src.m_pTextList[i]);
      } 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);
  }
}
CPDF_Rect CPDF_ClipPath::GetClipBox() const {
  CPDF_Rect rect;
  FX_BOOL bStarted = FALSE;
  int count = GetPathCount();
  if (count) {
    rect = GetPath(0).GetBoundingBox();
    for (int i = 1; i < count; i++) {
      CPDF_Rect path_rect = GetPath(i).GetBoundingBox();
      rect.Intersect(path_rect);
    }
    bStarted = TRUE;
  }
  count = GetTextCount();
  if (count) {
    CPDF_Rect layer_rect;
    FX_BOOL bLayerStarted = FALSE;
    for (int i = 0; i < count; i++) {
      CPDF_TextObject* pTextObj = GetText(i);
      if (pTextObj == NULL) {
        if (!bStarted) {
          rect = layer_rect;
          bStarted = TRUE;
        } else {
          rect.Intersect(layer_rect);
        }
        bLayerStarted = FALSE;
      } else {
        if (!bLayerStarted) {
          layer_rect = pTextObj->GetBBox(NULL);
          bLayerStarted = TRUE;
        } else {
          layer_rect.Union(pTextObj->GetBBox(NULL));
        }
      }
    }
  }
  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()) {
      CPDF_Rect old_rect(old_path.GetPointX(0), old_path.GetPointY(0),
                         old_path.GetPointX(2), old_path.GetPointY(2));
      CPDF_Rect 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 CPDF_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 = FXSYS_Mul(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 = FXSYS_Mul(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 = FXSYS_Mul(phase, scale);
  pData->SetDashCount(pArray->GetCount());
  for (FX_DWORD i = 0; i < pArray->GetCount(); i++) {
    pData->m_DashArray[i] = FXSYS_Mul(pArray->GetNumber(i), scale);
  }
}
void CPDF_AllStates::ProcessExtGS(CPDF_Dictionary* pGS,
                                  CPDF_StreamContentParser* pParser) {
  CPDF_GeneralStateData* pGeneralState = m_GeneralState.GetModify();
  FX_POSITION pos = pGS->GetStartPos();
  while (pos) {
    CFX_ByteString key_str;
    CPDF_Object* pElement = pGS->GetNextElement(pos, key_str);
    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->GetArray(0);
        if (!pArray)
          break;

        SetLineDash(pArray, pDash->GetNumber(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->GetNumber(1);
        m_TextState.SetFont(pParser->FindFont(pFont->GetString(0)));
        break;
      }
      case FXBSTR_ID('T', 'R', 0, 0):
        if (pGS->KeyExist(FX_BSTRC("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->GetString(0) : pObject->GetString();

        pGeneralState->SetBlendMode(mode);
        if (pGeneralState->m_BlendType > FXDIB_BLEND_MULTIPLY) {
          pParser->GetObjectList()->m_bBackgroundAlphaNeeded = 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(CPDF_Matrix));
        } else {
          pGeneralState->m_pSoftMask = NULL;
        }
        break;
      case FXBSTR_ID('C', 'A', 0, 0):
        pGeneralState->m_StrokeAlpha = PDF_ClipFloat(pObject->GetNumber());
        break;
      case FXBSTR_ID('c', 'a', 0, 0):
        pGeneralState->m_FillAlpha = PDF_ClipFloat(pObject->GetNumber());
        break;
      case FXBSTR_ID('O', 'P', 0, 0):
        pGeneralState->m_StrokeOP = pObject->GetInteger();
        if (!pGS->KeyExist(FX_BSTRC("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(FX_BSTRC("BG2"))) {
          continue;
        }
      case FXBSTR_ID('B', 'G', '2', 0):
        pGeneralState->m_pBG = pObject;
        break;
      case FXBSTR_ID('U', 'C', 'R', 0):
        if (pGS->KeyExist(FX_BSTRC("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(static_cast<CPDF_Object*>(src.m_pParam))->Clone();
  } else {
    m_pParam = src.m_pParam;
  }
}
CPDF_ContentMarkItem::~CPDF_ContentMarkItem() {
  if (m_ParamType == DirectDict && m_pParam) {
    ToDictionary(static_cast<CPDF_Object*>(m_pParam))->Release();
  }
}
FX_BOOL CPDF_ContentMarkItem::HasMCID() const {
  if (m_pParam &&
      (m_ParamType == DirectDict || m_ParamType == PropertiesDict)) {
    return ToDictionary(static_cast<CPDF_Object*>(m_pParam))
        ->KeyExist(FX_BSTRC("MCID"));
  }
  return FALSE;
}
CPDF_ContentMarkData::CPDF_ContentMarkData(const CPDF_ContentMarkData& src) {
  for (int i = 0; i < src.m_Marks.GetSize(); i++) {
    m_Marks.Add(src.m_Marks[i]);
  }
}
int CPDF_ContentMarkData::GetMCID() const {
  CPDF_ContentMarkItem::ParamType type = CPDF_ContentMarkItem::None;
  for (int i = 0; i < m_Marks.GetSize(); i++) {
    type = m_Marks[i].GetParamType();
    if (type == CPDF_ContentMarkItem::PropertiesDict ||
        type == CPDF_ContentMarkItem::DirectDict) {
      CPDF_Dictionary* pDict =
          ToDictionary(static_cast<CPDF_Object*>(m_Marks[i].GetParam()));
      if (pDict->KeyExist(FX_BSTRC("MCID"))) {
        return pDict->GetInteger(FX_BSTRC("MCID"));
      }
    }
  }
  return -1;
}
void CPDF_ContentMarkData::AddMark(const CFX_ByteString& name,
                                   CPDF_Dictionary* pDict,
                                   FX_BOOL bDirect) {
  CPDF_ContentMarkItem& item = m_Marks.Add();
  item.SetName(name);
  if (pDict == NULL) {
    return;
  }
  item.SetParam(bDirect ? CPDF_ContentMarkItem::DirectDict
                        : CPDF_ContentMarkItem::PropertiesDict,
                bDirect ? pDict->Clone() : pDict);
}
void CPDF_ContentMarkData::DeleteLastMark() {
  int size = m_Marks.GetSize();
  if (size == 0) {
    return;
  }
  m_Marks.RemoveAt(size - 1);
}
FX_BOOL CPDF_ContentMark::HasMark(const CFX_ByteStringC& mark) const {
  if (m_pObject == NULL) {
    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 == NULL) {
    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 = ToDictionary(static_cast<CPDF_Object*>(item.GetParam()));
      }
      return TRUE;
    }
  }
  return FALSE;
}
