// 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 "pageint.h"
#include "../fpdf_render/render_int.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->m_pObjectList->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->m_pCurStates->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;
}
