// 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;
  if (m_pTypeList) {
    FX_Free(m_pTypeList);
  }
  for (i = m_TextCount - 1; i > -1; i--)
    delete m_pTextList[i];
  if (m_pTextList) {
    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);
    if (pData->m_pTypeList) {
      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() : NULL;
    if (pObject == NULL) {
      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): {
        if (pObject->GetType() != PDFOBJ_ARRAY) {
          break;
        }
        CPDF_Array* pDash = (CPDF_Array*)pObject;
        CPDF_Array* pArray = pDash->GetArray(0);
        if (pArray == NULL) {
          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'): {
        if (pObject->GetType() != PDFOBJ_ARRAY) {
          break;
        }
        CPDF_Array* pFont = (CPDF_Array*)pObject;
        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):
        if (pObject && pObject->GetType() != PDFOBJ_NAME) {
          pGeneralState->m_pTR = pObject;
        } else {
          pGeneralState->m_pTR = NULL;
        }
        break;
      case FXBSTR_ID('B', 'M', 0, 0): {
        CFX_ByteString mode;
        if (pObject->GetType() == PDFOBJ_ARRAY) {
          mode = ((CPDF_Array*)pObject)->GetString(0);
        } else {
          mode = 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 (pObject && pObject->GetType() == PDFOBJ_DICTIONARY) {
          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 = ((CPDF_Dictionary*)src.m_pParam)->Clone();
  } else {
    m_pParam = src.m_pParam;
  }
}
CPDF_ContentMarkItem::~CPDF_ContentMarkItem() {
  if (m_ParamType == DirectDict && m_pParam) {
    ((CPDF_Dictionary*)m_pParam)->Release();
  }
}
FX_BOOL CPDF_ContentMarkItem::HasMCID() const {
  if (m_pParam &&
      (m_ParamType == DirectDict || m_ParamType == PropertiesDict)) {
    return ((CPDF_Dictionary*)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 = (CPDF_Dictionary*)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 = (CPDF_Dictionary*)item.GetParam();
      }
      return TRUE;
    }
  }
  return FALSE;
}
