// 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 --)
        if (m_pTextList[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_memcpy32(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_memcpy32(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_memmove32(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_memcpy32(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_memcpy32(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_memset32(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_memcpy32(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_memcpy32(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_memcpy32(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;
}
