// 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_module.h"
#include "../../../include/fpdfapi/fpdf_serial.h"
#include "pageint.h"
#define REQUIRE_PARAMS(count) if (m_ParamCount != count) { m_bAbort = TRUE; return; }
CPDF_StreamContentParser::CPDF_StreamContentParser()
{
    m_DefFontSize = 0;
    m_pCurStates = NULL;
    m_pLastTextObject = NULL;
    m_pPathPoints = NULL;
    m_PathClipType = 0;
    m_PathPointCount = m_PathAllocSize = 0;
    m_PathCurrentX = m_PathCurrentY = 0.0f;
    m_bResourceMissing = FALSE;
    m_bColored = FALSE;
    FXSYS_memset(m_Type3Data, 0, sizeof(FX_FLOAT) * 6);
    m_ParamCount = 0;
    m_ParamStartPos = 0;
    m_bAbort = FALSE;
    m_pLastImageDict = NULL;
    m_pLastCloneImageDict = NULL;
    m_pLastImage = NULL;
    m_bReleaseLastDict = TRUE;
    m_pParentResources = NULL;
}
FX_BOOL CPDF_StreamContentParser::Initialize()
{
    return TRUE;
}
CPDF_StreamContentParser::~CPDF_StreamContentParser()
{
    ClearAllParams();
    int i = 0;
    for (i = 0; i < m_StateStack.GetSize(); i ++) {
        delete (CPDF_AllStates*)m_StateStack[i];
    }
    if (m_pPathPoints) {
        FX_Free(m_pPathPoints);
    }
    delete m_pCurStates;
    if (m_pLastImageDict) {
        m_pLastImageDict->Release();
    }
    if (m_pLastCloneImageDict) {
        m_pLastCloneImageDict->Release();
    }
}
void CPDF_StreamContentParser::PrepareParse(CPDF_Document* pDocument,
        CPDF_Dictionary* pPageResources, CPDF_Dictionary* pParentResources, CFX_AffineMatrix* pmtContentToUser, CPDF_PageObjects* pObjList,
        CPDF_Dictionary* pResources, CPDF_Rect* pBBox, CPDF_ParseOptions* pOptions,
        CPDF_AllStates* pStates, int level)
{
    for (int i = 0; i < 6; i ++) {
        m_Type3Data[i] = 0;
    }
    m_pDocument = pDocument;
    m_pPageResources = pPageResources;
    m_pParentResources = pParentResources;
    if (pmtContentToUser) {
        m_mtContentToUser = *pmtContentToUser;
    }
    if (pOptions) {
        m_Options = *pOptions;
    }
    m_pObjectList = pObjList;
    m_pResources = pResources;
    if (pResources == NULL) {
        m_pResources = m_pParentResources;
    }
    if (m_pResources == NULL) {
        m_pResources = pPageResources;
    }
    if (pBBox) {
        m_BBox = *pBBox;
    }
    m_Level = level;
    m_pCurStates = new CPDF_AllStates;
    if (pStates) {
        m_pCurStates->Copy(*pStates);
    } else {
        m_pCurStates->m_GeneralState.New();
        m_pCurStates->m_GraphState.New();
        m_pCurStates->m_TextState.New();
        m_pCurStates->m_ColorState.New();
    }
}
int CPDF_StreamContentParser::GetNextParamPos()
{
    if (m_ParamCount == PARAM_BUF_SIZE) {
        m_ParamStartPos ++;
        if (m_ParamStartPos == PARAM_BUF_SIZE) {
            m_ParamStartPos = 0;
        }
        if (m_ParamBuf1[m_ParamStartPos].m_Type == 0) {
            if (CPDF_Object* pObject = m_ParamBuf1[m_ParamStartPos].m_pObject)
                pObject->Release();
        }
        return m_ParamStartPos;
    }
    int index = m_ParamStartPos + m_ParamCount;
    if (index >= PARAM_BUF_SIZE) {
        index -= PARAM_BUF_SIZE;
    }
    m_ParamCount ++;
    return index;
}
void CPDF_StreamContentParser::AddNameParam(const FX_CHAR* name, int len)
{
    int index = GetNextParamPos();
    if (len > 32) {
        m_ParamBuf1[index].m_Type = 0;
        m_ParamBuf1[index].m_pObject = CPDF_Name::Create(PDF_NameDecode(CFX_ByteStringC(name, len)));
    } else {
        m_ParamBuf1[index].m_Type = PDFOBJ_NAME;
        if (FXSYS_memchr(name, '#', len) == NULL) {
            FXSYS_memcpy(m_ParamBuf1[index].m_Name.m_Buffer, name, len);
            m_ParamBuf1[index].m_Name.m_Len = len;
        } else {
            CFX_ByteString str = PDF_NameDecode(CFX_ByteStringC(name, len));
            FXSYS_memcpy(m_ParamBuf1[index].m_Name.m_Buffer, str.c_str(), str.GetLength());
            m_ParamBuf1[index].m_Name.m_Len = str.GetLength();
        }
    }
}
void CPDF_StreamContentParser::AddNumberParam(const FX_CHAR* str, int len)
{
    int index = GetNextParamPos();
    m_ParamBuf1[index].m_Type = PDFOBJ_NUMBER;
    FX_atonum(CFX_ByteStringC(str, len), m_ParamBuf1[index].m_Number.m_bInteger,
              &m_ParamBuf1[index].m_Number.m_Integer);
}
void CPDF_StreamContentParser::AddObjectParam(CPDF_Object* pObj)
{
    int index = GetNextParamPos();
    m_ParamBuf1[index].m_Type = 0;
    m_ParamBuf1[index].m_pObject = pObj;
}
void CPDF_StreamContentParser::ClearAllParams()
{
    FX_DWORD index = m_ParamStartPos;
    for (FX_DWORD i = 0; i < m_ParamCount; i ++) {
        if (m_ParamBuf1[index].m_Type == 0) {
            if (CPDF_Object* pObject = m_ParamBuf1[index].m_pObject)
                pObject->Release();
        }
        index ++;
        if (index == PARAM_BUF_SIZE) {
            index = 0;
        }
    }
    m_ParamStartPos = 0;
    m_ParamCount = 0;
}
CPDF_Object* CPDF_StreamContentParser::GetObject(FX_DWORD index)
{
    if (index >= m_ParamCount) {
        return NULL;
    }
    int real_index = m_ParamStartPos + m_ParamCount - index - 1;
    if (real_index >= PARAM_BUF_SIZE) {
        real_index -= PARAM_BUF_SIZE;
    }
    _ContentParam& param = m_ParamBuf1[real_index];
    if (param.m_Type == PDFOBJ_NUMBER) {
        CPDF_Number* pNumber = CPDF_Number::Create(param.m_Number.m_bInteger, &param.m_Number.m_Integer);
        param.m_Type = 0;
        param.m_pObject = pNumber;
        return pNumber;
    }
    if (param.m_Type == PDFOBJ_NAME) {
        CPDF_Name* pName = CPDF_Name::Create(CFX_ByteString(param.m_Name.m_Buffer, param.m_Name.m_Len));
        param.m_Type = 0;
        param.m_pObject = pName;
        return pName;
    }
    if (param.m_Type == 0) {
        return param.m_pObject;
    }
    ASSERT(FALSE);
    return NULL;
}
CFX_ByteString CPDF_StreamContentParser::GetString(FX_DWORD index)
{
    if (index >= m_ParamCount) {
        return CFX_ByteString();
    }
    int real_index = m_ParamStartPos + m_ParamCount - index - 1;
    if (real_index >= PARAM_BUF_SIZE) {
        real_index -= PARAM_BUF_SIZE;
    }
    _ContentParam& param = m_ParamBuf1[real_index];
    if (param.m_Type == PDFOBJ_NAME) {
        return CFX_ByteString(param.m_Name.m_Buffer, param.m_Name.m_Len);
    }
    if (param.m_Type == 0 && param.m_pObject) {
        return param.m_pObject->GetString();
    }
    return CFX_ByteString();
}
FX_FLOAT CPDF_StreamContentParser::GetNumber(FX_DWORD index)
{
    if (index >= m_ParamCount) {
        return 0;
    }
    int real_index = m_ParamStartPos + m_ParamCount - index - 1;
    if (real_index >= PARAM_BUF_SIZE) {
        real_index -= PARAM_BUF_SIZE;
    }
    _ContentParam& param = m_ParamBuf1[real_index];
    if (param.m_Type == PDFOBJ_NUMBER) {
        return param.m_Number.m_bInteger ? (FX_FLOAT)param.m_Number.m_Integer : param.m_Number.m_Float;
    }
    if (param.m_Type == 0 && param.m_pObject) {
        return param.m_pObject->GetNumber();
    }
    return 0;
}
FX_FLOAT CPDF_StreamContentParser::GetNumber16(FX_DWORD index)
{
    return GetNumber(index);
}
void CPDF_StreamContentParser::SetGraphicStates(CPDF_PageObject* pObj, FX_BOOL bColor, FX_BOOL bText, FX_BOOL bGraph)
{
    pObj->m_GeneralState = m_pCurStates->m_GeneralState;
    pObj->m_ClipPath = m_pCurStates->m_ClipPath;
    pObj->m_ContentMark = m_CurContentMark;
    if (bColor) {
        pObj->m_ColorState = m_pCurStates->m_ColorState;
    }
    if (bGraph) {
        pObj->m_GraphState = m_pCurStates->m_GraphState;
    }
    if (bText) {
        pObj->m_TextState = m_pCurStates->m_TextState;
    }
}
const struct _OpCode {
    FX_DWORD	m_OpId;
    void (CPDF_StreamContentParser::*m_OpHandler)();
} g_OpCodes[] = {
    {FXBSTR_ID('"', 0, 0, 0),		&CPDF_StreamContentParser::Handle_NextLineShowText_Space},
    {FXBSTR_ID('\'', 0, 0, 0),		&CPDF_StreamContentParser::Handle_NextLineShowText},
    {FXBSTR_ID('B', 0, 0, 0),		&CPDF_StreamContentParser::Handle_FillStrokePath},
    {FXBSTR_ID('B', '*', 0, 0),	&CPDF_StreamContentParser::Handle_EOFillStrokePath},
    {FXBSTR_ID('B', 'D', 'C', 0),	&CPDF_StreamContentParser::Handle_BeginMarkedContent_Dictionary},
    {FXBSTR_ID('B', 'I', 0, 0),	&CPDF_StreamContentParser::Handle_BeginImage},
    {FXBSTR_ID('B', 'M', 'C', 0),	&CPDF_StreamContentParser::Handle_BeginMarkedContent},
    {FXBSTR_ID('B', 'T', 0, 0),	&CPDF_StreamContentParser::Handle_BeginText},
    {FXBSTR_ID('B', 'X', 0, 0),	&CPDF_StreamContentParser::Handle_BeginSectionUndefined},
    {FXBSTR_ID('C', 'S', 0, 0),	&CPDF_StreamContentParser::Handle_SetColorSpace_Stroke},
    {FXBSTR_ID('D', 'P', 0, 0),	&CPDF_StreamContentParser::Handle_MarkPlace_Dictionary},
    {FXBSTR_ID('D', 'o', 0, 0),	&CPDF_StreamContentParser::Handle_ExecuteXObject},
    {FXBSTR_ID('E', 'I', 0, 0),	&CPDF_StreamContentParser::Handle_EndImage},
    {FXBSTR_ID('E', 'M', 'C', 0),	&CPDF_StreamContentParser::Handle_EndMarkedContent},
    {FXBSTR_ID('E', 'T', 0, 0),	&CPDF_StreamContentParser::Handle_EndText},
    {FXBSTR_ID('E', 'X', 0, 0),	&CPDF_StreamContentParser::Handle_EndSectionUndefined},
    {FXBSTR_ID('F', 0, 0, 0),		&CPDF_StreamContentParser::Handle_FillPathOld},
    {FXBSTR_ID('G', 0, 0, 0),		&CPDF_StreamContentParser::Handle_SetGray_Stroke},
    {FXBSTR_ID('I', 'D', 0, 0),	&CPDF_StreamContentParser::Handle_BeginImageData},
    {FXBSTR_ID('J', 0, 0, 0),		&CPDF_StreamContentParser::Handle_SetLineCap},
    {FXBSTR_ID('K', 0, 0, 0),		&CPDF_StreamContentParser::Handle_SetCMYKColor_Stroke},
    {FXBSTR_ID('M', 0, 0, 0),		&CPDF_StreamContentParser::Handle_SetMiterLimit},
    {FXBSTR_ID('M', 'P', 0, 0),	&CPDF_StreamContentParser::Handle_MarkPlace},
    {FXBSTR_ID('Q', 0, 0, 0),		&CPDF_StreamContentParser::Handle_RestoreGraphState},
    {FXBSTR_ID('R', 'G', 0, 0),	&CPDF_StreamContentParser::Handle_SetRGBColor_Stroke},
    {FXBSTR_ID('S', 0, 0, 0),		&CPDF_StreamContentParser::Handle_StrokePath},
    {FXBSTR_ID('S', 'C', 0, 0),	&CPDF_StreamContentParser::Handle_SetColor_Stroke},
    {FXBSTR_ID('S', 'C', 'N', 0),	&CPDF_StreamContentParser::Handle_SetColorPS_Stroke},
    {FXBSTR_ID('T', '*', 0, 0),	&CPDF_StreamContentParser::Handle_MoveToNextLine},
    {FXBSTR_ID('T', 'D', 0, 0),	&CPDF_StreamContentParser::Handle_MoveTextPoint_SetLeading},
    {FXBSTR_ID('T', 'J', 0, 0),	&CPDF_StreamContentParser::Handle_ShowText_Positioning},
    {FXBSTR_ID('T', 'L', 0, 0),	&CPDF_StreamContentParser::Handle_SetTextLeading},
    {FXBSTR_ID('T', 'c', 0, 0),	&CPDF_StreamContentParser::Handle_SetCharSpace},
    {FXBSTR_ID('T', 'd', 0, 0),	&CPDF_StreamContentParser::Handle_MoveTextPoint},
    {FXBSTR_ID('T', 'f', 0, 0),	&CPDF_StreamContentParser::Handle_SetFont},
    {FXBSTR_ID('T', 'j', 0, 0),	&CPDF_StreamContentParser::Handle_ShowText},
    {FXBSTR_ID('T', 'm', 0, 0),	&CPDF_StreamContentParser::Handle_SetTextMatrix},
    {FXBSTR_ID('T', 'r', 0, 0),	&CPDF_StreamContentParser::Handle_SetTextRenderMode},
    {FXBSTR_ID('T', 's', 0, 0),	&CPDF_StreamContentParser::Handle_SetTextRise},
    {FXBSTR_ID('T', 'w', 0, 0),	&CPDF_StreamContentParser::Handle_SetWordSpace},
    {FXBSTR_ID('T', 'z', 0, 0),	&CPDF_StreamContentParser::Handle_SetHorzScale},
    {FXBSTR_ID('W', 0, 0, 0),		&CPDF_StreamContentParser::Handle_Clip},
    {FXBSTR_ID('W', '*', 0, 0),	&CPDF_StreamContentParser::Handle_EOClip},
    {FXBSTR_ID('b', 0, 0, 0),		&CPDF_StreamContentParser::Handle_CloseFillStrokePath},
    {FXBSTR_ID('b', '*', 0, 0),	&CPDF_StreamContentParser::Handle_CloseEOFillStrokePath},
    {FXBSTR_ID('c', 0, 0, 0),		&CPDF_StreamContentParser::Handle_CurveTo_123},
    {FXBSTR_ID('c', 'm', 0, 0),	&CPDF_StreamContentParser::Handle_ConcatMatrix},
    {FXBSTR_ID('c', 's', 0, 0),	&CPDF_StreamContentParser::Handle_SetColorSpace_Fill},
    {FXBSTR_ID('d', 0, 0, 0),		&CPDF_StreamContentParser::Handle_SetDash},
    {FXBSTR_ID('d', '0', 0, 0),	&CPDF_StreamContentParser::Handle_SetCharWidth},
    {FXBSTR_ID('d', '1', 0, 0),	&CPDF_StreamContentParser::Handle_SetCachedDevice},
    {FXBSTR_ID('f', 0, 0, 0),		&CPDF_StreamContentParser::Handle_FillPath},
    {FXBSTR_ID('f', '*', 0, 0),	&CPDF_StreamContentParser::Handle_EOFillPath},
    {FXBSTR_ID('g', 0, 0, 0),		&CPDF_StreamContentParser::Handle_SetGray_Fill},
    {FXBSTR_ID('g', 's', 0, 0),	&CPDF_StreamContentParser::Handle_SetExtendGraphState},
    {FXBSTR_ID('h', 0, 0, 0),		&CPDF_StreamContentParser::Handle_ClosePath},
    {FXBSTR_ID('i', 0, 0, 0),		&CPDF_StreamContentParser::Handle_SetFlat},
    {FXBSTR_ID('j', 0, 0, 0),		&CPDF_StreamContentParser::Handle_SetLineJoin},
    {FXBSTR_ID('k', 0, 0, 0),		&CPDF_StreamContentParser::Handle_SetCMYKColor_Fill},
    {FXBSTR_ID('l', 0, 0, 0),		&CPDF_StreamContentParser::Handle_LineTo},
    {FXBSTR_ID('m', 0, 0, 0),		&CPDF_StreamContentParser::Handle_MoveTo},
    {FXBSTR_ID('n', 0, 0, 0),		&CPDF_StreamContentParser::Handle_EndPath},
    {FXBSTR_ID('q', 0, 0, 0),		&CPDF_StreamContentParser::Handle_SaveGraphState},
    {FXBSTR_ID('r', 'e', 0, 0),	&CPDF_StreamContentParser::Handle_Rectangle},
    {FXBSTR_ID('r', 'g', 0, 0),	&CPDF_StreamContentParser::Handle_SetRGBColor_Fill},
    {FXBSTR_ID('r', 'i', 0, 0),	&CPDF_StreamContentParser::Handle_SetRenderIntent},
    {FXBSTR_ID('s', 0, 0, 0),		&CPDF_StreamContentParser::Handle_CloseStrokePath},
    {FXBSTR_ID('s', 'c', 0, 0),	&CPDF_StreamContentParser::Handle_SetColor_Fill},
    {FXBSTR_ID('s', 'c', 'n', 0),	&CPDF_StreamContentParser::Handle_SetColorPS_Fill},
    {FXBSTR_ID('s', 'h', 0, 0),	&CPDF_StreamContentParser::Handle_ShadeFill},
    {FXBSTR_ID('v', 0, 0, 0),		&CPDF_StreamContentParser::Handle_CurveTo_23},
    {FXBSTR_ID('w', 0, 0, 0),		&CPDF_StreamContentParser::Handle_SetLineWidth},
    {FXBSTR_ID('y', 0, 0, 0),		&CPDF_StreamContentParser::Handle_CurveTo_13},
};
FX_BOOL CPDF_StreamContentParser::OnOperator(const FX_CHAR* op)
{
    int i = 0;
    FX_DWORD opid = 0;
    while (i < 4 && op[i]) {
        opid = (opid << 8) + op[i];
        i ++;
    }
    while (i < 4) {
        opid <<= 8;
        i ++;
    };
    int low = 0, high = sizeof g_OpCodes / sizeof(struct _OpCode) - 1;
    while (low <= high) {
        int middle = (low + high) / 2;
        int compare = opid - g_OpCodes[middle].m_OpId;
        if (compare == 0) {
            (this->*g_OpCodes[middle].m_OpHandler)();
            return TRUE;
        } else if (compare < 0) {
            high = middle - 1;
        } else {
            low = middle + 1;
        }
    }
    return m_CompatCount != 0;
}
void CPDF_StreamContentParser::Handle_CloseFillStrokePath()
{
    if (m_Options.m_bTextOnly) {
        return;
    }
    Handle_ClosePath();
    AddPathObject(FXFILL_WINDING, TRUE);
}
void CPDF_StreamContentParser::Handle_FillStrokePath()
{
    if (m_Options.m_bTextOnly) {
        return;
    }
    AddPathObject(FXFILL_WINDING, TRUE);
}
void CPDF_StreamContentParser::Handle_CloseEOFillStrokePath()
{
    if (m_Options.m_bTextOnly) {
        return;
    }
    AddPathPoint(m_PathStartX, m_PathStartY, FXPT_LINETO | FXPT_CLOSEFIGURE);
    AddPathObject(FXFILL_ALTERNATE, TRUE);
}
void CPDF_StreamContentParser::Handle_EOFillStrokePath()
{
    if (m_Options.m_bTextOnly) {
        return;
    }
    AddPathObject(FXFILL_ALTERNATE, TRUE);
}
void CPDF_StreamContentParser::Handle_BeginMarkedContent_Dictionary()
{
    if (!m_Options.m_bMarkedContent) {
        return;
    }
    CFX_ByteString tag = GetString(1);
    CPDF_Object* pProperty = GetObject(0);
    if (pProperty == NULL) {
        return;
    }
    FX_BOOL bDirect = TRUE;
    if (pProperty->GetType() == PDFOBJ_NAME) {
        pProperty = FindResourceObj(FX_BSTRC("Properties"), pProperty->GetString());
        if (pProperty == NULL) {
            return;
        }
        bDirect = FALSE;
    }
    if (pProperty->GetType() != PDFOBJ_DICTIONARY) {
        return;
    }
    m_CurContentMark.GetModify()->AddMark(tag, (CPDF_Dictionary*)pProperty, bDirect);
}
void CPDF_StreamContentParser::Handle_BeginMarkedContent()
{
    if (!m_Options.m_bMarkedContent) {
        return;
    }
    CFX_ByteString tag = GetString(0);
    m_CurContentMark.GetModify()->AddMark(tag, NULL, FALSE);
}
struct _FX_BSTR {
    const FX_CHAR*	m_Ptr;
    int			m_Size;
};
#define _FX_BSTRC(str) {str, sizeof(str)-1}
const _FX_BSTR _PDF_InlineKeyAbbr[] = {
    _FX_BSTRC("BitsPerComponent"), _FX_BSTRC("BPC"),
    _FX_BSTRC("ColorSpace"), _FX_BSTRC("CS"),
    _FX_BSTRC("Decode"), _FX_BSTRC("D"),
    _FX_BSTRC("DecodeParms"), _FX_BSTRC("DP"),
    _FX_BSTRC("Filter"), _FX_BSTRC("F"),
    _FX_BSTRC("Height"), _FX_BSTRC("H"),
    _FX_BSTRC("ImageMask"), _FX_BSTRC("IM"),
    _FX_BSTRC("Interpolate"), _FX_BSTRC("I"),
    _FX_BSTRC("Width"), _FX_BSTRC("W"),
};
const _FX_BSTR _PDF_InlineValueAbbr[] = {
    _FX_BSTRC("DeviceGray"), _FX_BSTRC("G"),
    _FX_BSTRC("DeviceRGB"), _FX_BSTRC("RGB"),
    _FX_BSTRC("DeviceCMYK"), _FX_BSTRC("CMYK"),
    _FX_BSTRC("Indexed"), _FX_BSTRC("I"),
    _FX_BSTRC("ASCIIHexDecode"), _FX_BSTRC("AHx"),
    _FX_BSTRC("ASCII85Decode"), _FX_BSTRC("A85"),
    _FX_BSTRC("LZWDecode"), _FX_BSTRC("LZW"),
    _FX_BSTRC("FlateDecode"), _FX_BSTRC("Fl"),
    _FX_BSTRC("RunLengthDecode"), _FX_BSTRC("RL"),
    _FX_BSTRC("CCITTFaxDecode"), _FX_BSTRC("CCF"),
    _FX_BSTRC("DCTDecode"), _FX_BSTRC("DCT"),
};
static CFX_ByteStringC _PDF_FindFullName(const _FX_BSTR* table, int count, const CFX_ByteStringC& abbr)
{
    int i = 0;
    while (i < count) {
        if (abbr.GetLength() == table[i + 1].m_Size && FXSYS_memcmp(abbr.GetPtr(), table[i + 1].m_Ptr, abbr.GetLength()) == 0) {
            return CFX_ByteStringC(table[i].m_Ptr, table[i].m_Size);
        }
        i += 2;
    }
    return CFX_ByteStringC();
}
void _PDF_ReplaceAbbr(CPDF_Object* pObj)
{
    switch (pObj->GetType()) {
        case PDFOBJ_DICTIONARY: {
                CPDF_Dictionary* pDict = (CPDF_Dictionary*)pObj;
                FX_POSITION pos = pDict->GetStartPos();
                while (pos) {
                    CFX_ByteString key;
                    CPDF_Object* value = pDict->GetNextElement(pos, key);
                    CFX_ByteStringC fullname = _PDF_FindFullName(_PDF_InlineKeyAbbr,
                                               sizeof _PDF_InlineKeyAbbr / sizeof(_FX_BSTR), key);
                    if (!fullname.IsEmpty()) {
                        pDict->ReplaceKey(key, fullname);
                        key = fullname;
                    }
                    if (value->GetType() == PDFOBJ_NAME) {
                        CFX_ByteString name = value->GetString();
                        fullname = _PDF_FindFullName(_PDF_InlineValueAbbr,
                                                     sizeof _PDF_InlineValueAbbr / sizeof(_FX_BSTR), name);
                        if (!fullname.IsEmpty()) {
                            pDict->SetAtName(key, fullname);
                        }
                    } else {
                        _PDF_ReplaceAbbr(value);
                    }
                }
                break;
            }
        case PDFOBJ_ARRAY: {
                CPDF_Array* pArray = (CPDF_Array*)pObj;
                for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) {
                    CPDF_Object* pElement = pArray->GetElement(i);
                    if (pElement->GetType() == PDFOBJ_NAME) {
                        CFX_ByteString name = pElement->GetString();
                        CFX_ByteStringC fullname = _PDF_FindFullName(_PDF_InlineValueAbbr,
                                                   sizeof _PDF_InlineValueAbbr / sizeof(_FX_BSTR), name);
                        if (!fullname.IsEmpty()) {
                            pArray->SetAt(i, CPDF_Name::Create(fullname));
                        }
                    } else {
                        _PDF_ReplaceAbbr(pElement);
                    }
                }
                break;
            }
    }
}
static CFX_ByteStringC _PDF_FindAbbrName(const _FX_BSTR* table, int count, const CFX_ByteStringC& fullName)
{
    int i = 0;
    while (i < count) {
        if (fullName.GetLength() == table[i].m_Size && FXSYS_memcmp(fullName.GetPtr(), table[i].m_Ptr, fullName.GetLength()) == 0) {
            return CFX_ByteStringC(table[i + 1].m_Ptr, table[i + 1].m_Size);
        }
        i += 2;
    }
    return CFX_ByteStringC();
}
void _PDF_ReplaceFull(CPDF_Object* pObj)
{
    switch (pObj->GetType()) {
        case PDFOBJ_DICTIONARY: {
                CPDF_Dictionary* pDict = (CPDF_Dictionary*)pObj;
                FX_POSITION pos = pDict->GetStartPos();
                while (pos) {
                    CFX_ByteString key;
                    CPDF_Object* value = pDict->GetNextElement(pos, key);
                    CFX_ByteStringC abbrName = _PDF_FindAbbrName(_PDF_InlineKeyAbbr,
                                               sizeof(_PDF_InlineKeyAbbr) / sizeof(_FX_BSTR), key);
                    if (!abbrName.IsEmpty()) {
                        pDict->ReplaceKey(key, abbrName);
                        key = abbrName;
                    }
                    if (value->GetType() == PDFOBJ_NAME) {
                        CFX_ByteString name = value->GetString();
                        abbrName = _PDF_FindAbbrName(_PDF_InlineValueAbbr,
                                                     sizeof(_PDF_InlineValueAbbr) / sizeof(_FX_BSTR), name);
                        if (!abbrName.IsEmpty()) {
                            pDict->SetAtName(key, abbrName);
                        }
                    } else {
                        _PDF_ReplaceFull(value);
                    }
                }
                break;
            }
        case PDFOBJ_ARRAY: {
                CPDF_Array* pArray = (CPDF_Array*)pObj;
                for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) {
                    CPDF_Object* pElement = pArray->GetElement(i);
                    if (pElement->GetType() == PDFOBJ_NAME) {
                        CFX_ByteString name = pElement->GetString();
                        CFX_ByteStringC abbrName = _PDF_FindAbbrName(_PDF_InlineValueAbbr,
                                                   sizeof _PDF_InlineValueAbbr / sizeof(_FX_BSTR), name);
                        if (!abbrName.IsEmpty()) {
                            pArray->SetAt(i, CPDF_Name::Create(abbrName));
                        }
                    } else {
                        _PDF_ReplaceFull(pElement);
                    }
                }
                break;
            }
    }
}
void CPDF_StreamContentParser::Handle_BeginText()
{
    m_pCurStates->m_TextMatrix.Set(1.0f, 0, 0, 1.0f, 0, 0);
    OnChangeTextMatrix();
    m_pCurStates->m_TextX = 0;
    m_pCurStates->m_TextY = 0;
    m_pCurStates->m_TextLineX = 0;
    m_pCurStates->m_TextLineY = 0;
}
void CPDF_StreamContentParser::Handle_BeginSectionUndefined()
{
    m_CompatCount ++;
}
void CPDF_StreamContentParser::Handle_CurveTo_123()
{
    if (m_Options.m_bTextOnly) {
        return;
    }
    AddPathPoint(GetNumber(5), GetNumber(4), FXPT_BEZIERTO);
    AddPathPoint(GetNumber(3), GetNumber(2), FXPT_BEZIERTO);
    AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO);
}
void CPDF_StreamContentParser::Handle_ConcatMatrix()
{
    FX_FLOAT a2 = GetNumber16(5), b2 = GetNumber16(4), c2 = GetNumber16(3), d2 = GetNumber16(2);
    FX_FLOAT e2 = GetNumber(1), f2 = GetNumber(0);
    CFX_AffineMatrix new_matrix(a2, b2, c2, d2, e2, f2);
    new_matrix.Concat(m_pCurStates->m_CTM);
    m_pCurStates->m_CTM = new_matrix;
    OnChangeTextMatrix();
}
void CPDF_StreamContentParser::Handle_SetColorSpace_Fill()
{
    if (m_Options.m_bTextOnly) {
        return;
    }
    CFX_ByteString csname = GetString(0);
    CPDF_ColorSpace* pCS = FindColorSpace(csname);
    if (pCS == NULL) {
        return;
    }
    m_pCurStates->m_ColorState.GetModify()->m_FillColor.SetColorSpace(pCS);
}
void CPDF_StreamContentParser::Handle_SetColorSpace_Stroke()
{
    if (m_Options.m_bTextOnly) {
        return;
    }
    CFX_ByteString csname = GetString(0);
    CPDF_ColorSpace* pCS = FindColorSpace(csname);
    if (pCS == NULL) {
        return;
    }
    m_pCurStates->m_ColorState.GetModify()->m_StrokeColor.SetColorSpace(pCS);
}
void CPDF_StreamContentParser::Handle_SetDash()
{
    if (m_Options.m_bTextOnly) {
        return;
    }
    CPDF_Array* pArray = GetObject(1) ? GetObject(1)->GetArray() : NULL;
    if (pArray == NULL) {
        return;
    }
    m_pCurStates->SetLineDash(pArray, GetNumber(0), 1.0f);
}
void CPDF_StreamContentParser::Handle_SetCharWidth()
{
    m_Type3Data[0] = GetNumber(1);
    m_Type3Data[1] = GetNumber(0);
    m_bColored = TRUE;
}
void CPDF_StreamContentParser::Handle_SetCachedDevice()
{
    for (int i = 0; i < 6; i ++) {
        m_Type3Data[i] = GetNumber(5 - i);
    }
    m_bColored = FALSE;
}
void CPDF_StreamContentParser::Handle_ExecuteXObject()
{
    CFX_ByteString name = GetString(0);
    if (name == m_LastImageName && m_pLastImage && m_pLastImage->GetStream() && m_pLastImage->GetStream()->GetObjNum()) {
        AddImage(NULL, m_pLastImage, FALSE);
        return;
    }
    if (m_Options.m_bTextOnly) {
        CPDF_Object* pRes = NULL;
        if (m_pResources == NULL) {
            return;
        }
        if (m_pResources == m_pPageResources) {
            CPDF_Dictionary* pList = m_pResources->GetDict(FX_BSTRC("XObject"));
            if (pList == NULL) {
                return;
            }
            pRes = pList->GetElement(name);
            if (pRes == NULL || pRes->GetType() != PDFOBJ_REFERENCE) {
                return;
            }
        } else {
            CPDF_Dictionary* pList = m_pResources->GetDict(FX_BSTRC("XObject"));
            if (pList == NULL) {
                if (m_pPageResources == NULL) {
                    return;
                }
                CPDF_Dictionary* pList = m_pPageResources->GetDict(FX_BSTRC("XObject"));
                if (pList == NULL) {
                    return;
                }
                pRes = pList->GetElement(name);
                if (pRes == NULL || pRes->GetType() != PDFOBJ_REFERENCE) {
                    return;
                }
            } else {
                pRes = pList->GetElement(name);
                if (pRes == NULL || pRes->GetType() != PDFOBJ_REFERENCE) {
                    return;
                }
            }
        }
        FX_BOOL bForm;
        if (m_pDocument->IsFormStream(((CPDF_Reference*)pRes)->GetRefObjNum(), bForm) && !bForm) {
            return;
        }
    }
    CPDF_Stream* pXObject = (CPDF_Stream*)FindResourceObj(FX_BSTRC("XObject"), name);
    if (pXObject == NULL || pXObject->GetType() != PDFOBJ_STREAM) {
        m_bResourceMissing = TRUE;
        return;
    }
    CFX_ByteStringC type = pXObject->GetDict() ? pXObject->GetDict()->GetConstString(FX_BSTRC("Subtype")) : CFX_ByteStringC();
    if (type == FX_BSTRC("Image")) {
        if (m_Options.m_bTextOnly) {
            return;
        }
        CPDF_ImageObject* pObj = AddImage(pXObject, NULL, FALSE);
        m_LastImageName = name;
        m_pLastImage = pObj->m_pImage;
    } else if (type == FX_BSTRC("Form")) {
        AddForm(pXObject);
    } else {
        return;
    }
}
void CPDF_StreamContentParser::AddForm(CPDF_Stream* pStream)
{
    if (!m_Options.m_bSeparateForm) {
        CPDF_Dictionary* pResources = pStream->GetDict()->GetDict(FX_BSTRC("Resources"));
        CFX_AffineMatrix form_matrix = pStream->GetDict()->GetMatrix(FX_BSTRC("Matrix"));
        form_matrix.Concat(m_pCurStates->m_CTM);
        CPDF_Array* pBBox = pStream->GetDict()->GetArray(FX_BSTRC("BBox"));
        CFX_FloatRect form_bbox;
        CPDF_Path ClipPath;
        if (pBBox) {
            form_bbox = pStream->GetDict()->GetRect(FX_BSTRC("BBox"));
            ClipPath.New();
            ClipPath.AppendRect(form_bbox.left, form_bbox.bottom, form_bbox.right, form_bbox.top);
            ClipPath.Transform(&form_matrix);
            form_bbox.Transform(&form_matrix);
        }
        CPDF_StreamContentParser parser;
        parser.Initialize();
        parser.PrepareParse(m_pDocument, m_pPageResources, m_pResources, &m_mtContentToUser,
                            m_pObjectList, pResources, &form_bbox, &m_Options, m_pCurStates, m_Level + 1);
        parser.m_pCurStates->m_CTM = form_matrix;
        if (ClipPath.NotNull()) {
            parser.m_pCurStates->m_ClipPath.AppendPath(ClipPath, FXFILL_WINDING, TRUE);
        }
        CPDF_StreamAcc stream;
        stream.LoadAllData(pStream, FALSE);
        if (stream.GetSize() == 0) {
            return;
        }
        parser.Parse(stream.GetData(), stream.GetSize(), 0);
        return;
    }
    CPDF_FormObject* pFormObj = new CPDF_FormObject;
    pFormObj->m_pForm = new CPDF_Form(m_pDocument, m_pPageResources, pStream, m_pResources);
    pFormObj->m_FormMatrix = m_pCurStates->m_CTM;
    pFormObj->m_FormMatrix.Concat(m_mtContentToUser);
    CPDF_AllStates status;
    status.m_GeneralState = m_pCurStates->m_GeneralState;
    status.m_GraphState = m_pCurStates->m_GraphState;
    status.m_ColorState = m_pCurStates->m_ColorState;
    status.m_TextState = m_pCurStates->m_TextState;
    pFormObj->m_pForm->ParseContent(&status, NULL, NULL, &m_Options, m_Level + 1);
    if (!m_pObjectList->m_bBackgroundAlphaNeeded && pFormObj->m_pForm->m_bBackgroundAlphaNeeded) {
        m_pObjectList->m_bBackgroundAlphaNeeded = TRUE;
    }
    pFormObj->CalcBoundingBox();
    SetGraphicStates(pFormObj, TRUE, TRUE, TRUE);
    m_pObjectList->m_ObjectList.AddTail(pFormObj);
}
CPDF_ImageObject* CPDF_StreamContentParser::AddImage(CPDF_Stream* pStream, CPDF_Image* pImage, FX_BOOL bInline)
{
    if (pStream == NULL && pImage == NULL) {
        return NULL;
    }
    CFX_AffineMatrix ImageMatrix;
    ImageMatrix.Copy(m_pCurStates->m_CTM);
    ImageMatrix.Concat(m_mtContentToUser);
    CPDF_ImageObject* pImageObj = new CPDF_ImageObject;
    if (pImage) {
        pImageObj->m_pImage = m_pDocument->GetPageData()->GetImage(pImage->GetStream());
    } else if (pStream->GetObjNum()) {
        pImageObj->m_pImage = m_pDocument->LoadImageF(pStream);
    } else {
        pImageObj->m_pImage = new CPDF_Image(m_pDocument);
        pImageObj->m_pImage->LoadImageF(pStream, bInline);
    }
    SetGraphicStates(pImageObj, pImageObj->m_pImage->IsMask(), FALSE, FALSE);
    pImageObj->m_Matrix = ImageMatrix;
    pImageObj->CalcBoundingBox();
    m_pObjectList->m_ObjectList.AddTail(pImageObj);
    return pImageObj;
}
void CPDF_StreamContentParser::Handle_MarkPlace_Dictionary()
{
}
void CPDF_StreamContentParser::Handle_EndImage()
{
}
void CPDF_StreamContentParser::Handle_EndMarkedContent()
{
    if (!m_Options.m_bMarkedContent) {
        return;
    }
    if (m_CurContentMark.IsNull()) {
        return;
    }
    int count = m_CurContentMark.GetObject()->CountItems();
    if (count == 1) {
        m_CurContentMark.SetNull();
        return;
    }
    m_CurContentMark.GetModify()->DeleteLastMark();
}
void CPDF_StreamContentParser::Handle_EndText()
{
    int count = m_ClipTextList.GetSize();
    if (count == 0) {
        return;
    }
    if (m_pCurStates->m_TextState.GetObject()->m_TextMode < 4) {
        for (int i = 0; i < count; i ++) {
            CPDF_TextObject* pText = (CPDF_TextObject*)m_ClipTextList.GetAt(i);
            delete pText;
        }
    } else {
        m_pCurStates->m_ClipPath.AppendTexts((CPDF_TextObject**)m_ClipTextList.GetData(), count);
    }
    m_ClipTextList.RemoveAll();
}
void CPDF_StreamContentParser::Handle_EndSectionUndefined()
{
    if (m_CompatCount) {
        m_CompatCount --;
    }
}
void CPDF_StreamContentParser::Handle_FillPath()
{
    if (m_Options.m_bTextOnly) {
        return;
    }
    AddPathObject(FXFILL_WINDING, FALSE);
}
void CPDF_StreamContentParser::Handle_FillPathOld()
{
    if (m_Options.m_bTextOnly) {
        return;
    }
    AddPathObject(FXFILL_WINDING, FALSE);
}
void CPDF_StreamContentParser::Handle_EOFillPath()
{
    if (m_Options.m_bTextOnly) {
        return;
    }
    AddPathObject(FXFILL_ALTERNATE, FALSE);
}
void CPDF_StreamContentParser::Handle_SetGray_Fill()
{
    FX_FLOAT value = GetNumber(0);
    CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY);
    m_pCurStates->m_ColorState.SetFillColor(pCS, &value, 1);
}
void CPDF_StreamContentParser::Handle_SetGray_Stroke()
{
    FX_FLOAT value = GetNumber(0);
    CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY);
    m_pCurStates->m_ColorState.SetStrokeColor(pCS, &value, 1);
}
void CPDF_StreamContentParser::Handle_SetExtendGraphState()
{
    CFX_ByteString name = GetString(0);
    CPDF_Dictionary* pGS = (CPDF_Dictionary*)FindResourceObj(FX_BSTRC("ExtGState"), name);
    if (pGS == NULL || pGS->GetType() != PDFOBJ_DICTIONARY) {
        m_bResourceMissing = TRUE;
        return;
    }
    m_pCurStates->ProcessExtGS(pGS, this);
}
void CPDF_StreamContentParser::Handle_ClosePath()
{
    if (m_Options.m_bTextOnly) {
        return;
    }
    if (m_PathPointCount == 0) {
        return;
    }
    if (m_PathStartX != m_PathCurrentX || m_PathStartY != m_PathCurrentY) {
        AddPathPoint(m_PathStartX, m_PathStartY, FXPT_LINETO | FXPT_CLOSEFIGURE);
    } else if (m_pPathPoints[m_PathPointCount - 1].m_Flag != FXPT_MOVETO) {
        m_pPathPoints[m_PathPointCount - 1].m_Flag |= FXPT_CLOSEFIGURE;
    }
}
void CPDF_StreamContentParser::Handle_SetFlat()
{
    m_pCurStates->m_GeneralState.GetModify()->m_Flatness = GetNumber(0);
}
void CPDF_StreamContentParser::Handle_BeginImageData()
{
}
void CPDF_StreamContentParser::Handle_SetLineJoin()
{
    m_pCurStates->m_GraphState.GetModify()->m_LineJoin = (CFX_GraphStateData::LineJoin)GetInteger(0);
}
void CPDF_StreamContentParser::Handle_SetLineCap()
{
    m_pCurStates->m_GraphState.GetModify()->m_LineCap = (CFX_GraphStateData::LineCap)GetInteger(0);
}
void CPDF_StreamContentParser::Handle_SetCMYKColor_Fill()
{
    REQUIRE_PARAMS(4);
    FX_FLOAT values[4];
    for (int i = 0; i < 4; i ++) {
        values[i] = GetNumber(3 - i);
    }
    CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK);
    m_pCurStates->m_ColorState.SetFillColor(pCS, values, 4);
}
void CPDF_StreamContentParser::Handle_SetCMYKColor_Stroke()
{
    REQUIRE_PARAMS(4);
    FX_FLOAT values[4];
    for (int i = 0; i < 4; i ++) {
        values[i] = GetNumber(3 - i);
    }
    CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK);
    m_pCurStates->m_ColorState.SetStrokeColor(pCS, values, 4);
}
void CPDF_StreamContentParser::Handle_LineTo()
{
    REQUIRE_PARAMS(2);
    if (m_Options.m_bTextOnly) {
        return;
    }
    AddPathPoint(GetNumber(1), GetNumber(0), FXPT_LINETO);
}
void CPDF_StreamContentParser::Handle_MoveTo()
{
    REQUIRE_PARAMS(2);
    if (m_Options.m_bTextOnly) {
        m_pSyntax->SkipPathObject();
        return;
    }
    AddPathPoint(GetNumber(1), GetNumber(0), FXPT_MOVETO);
    ParsePathObject();
}
void CPDF_StreamContentParser::Handle_SetMiterLimit()
{
    m_pCurStates->m_GraphState.GetModify()->m_MiterLimit = GetNumber(0);
}
void CPDF_StreamContentParser::Handle_MarkPlace()
{
}
void CPDF_StreamContentParser::Handle_EndPath()
{
    if (m_Options.m_bTextOnly) {
        return;
    }
    AddPathObject(0, FALSE);
}
void CPDF_StreamContentParser::Handle_SaveGraphState()
{
    CPDF_AllStates* pStates = new CPDF_AllStates;
    pStates->Copy(*m_pCurStates);
    m_StateStack.Add(pStates);
}
void CPDF_StreamContentParser::Handle_RestoreGraphState()
{
    int size = m_StateStack.GetSize();
    if (size == 0) {
        return;
    }
    CPDF_AllStates* pStates = (CPDF_AllStates*)m_StateStack.GetAt(size - 1);
    m_pCurStates->Copy(*pStates);
    delete pStates;
    m_StateStack.RemoveAt(size - 1);
}
void CPDF_StreamContentParser::Handle_Rectangle()
{
    if (m_Options.m_bTextOnly) {
        return;
    }
    FX_FLOAT x = GetNumber(3), y = GetNumber(2);
    FX_FLOAT w = GetNumber(1), h = GetNumber(0);
    AddPathRect(x, y, w, h);
}
void CPDF_StreamContentParser::AddPathRect(FX_FLOAT x, FX_FLOAT y, FX_FLOAT w, FX_FLOAT h)
{
    AddPathPoint(x, y, FXPT_MOVETO);
    AddPathPoint(x + w, y, FXPT_LINETO);
    AddPathPoint(x + w, y + h, FXPT_LINETO);
    AddPathPoint(x, y + h, FXPT_LINETO);
    AddPathPoint(x, y, FXPT_LINETO | FXPT_CLOSEFIGURE);
}
void CPDF_StreamContentParser::Handle_SetRGBColor_Fill()
{
    REQUIRE_PARAMS(3);
    FX_FLOAT values[3];
    for (int i = 0; i < 3; i ++) {
        values[i] = GetNumber(2 - i);
    }
    CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB);
    m_pCurStates->m_ColorState.SetFillColor(pCS, values, 3);
}
void CPDF_StreamContentParser::Handle_SetRGBColor_Stroke()
{
    REQUIRE_PARAMS(3);
    FX_FLOAT values[3];
    for (int i = 0; i < 3; i ++) {
        values[i] = GetNumber(2 - i);
    }
    CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB);
    m_pCurStates->m_ColorState.SetStrokeColor(pCS, values, 3);
}
void CPDF_StreamContentParser::Handle_SetRenderIntent()
{
}
void CPDF_StreamContentParser::Handle_CloseStrokePath()
{
    if (m_Options.m_bTextOnly) {
        return;
    }
    Handle_ClosePath();
    AddPathObject(0, TRUE);
}
void CPDF_StreamContentParser::Handle_StrokePath()
{
    if (m_Options.m_bTextOnly) {
        return;
    }
    AddPathObject(0, TRUE);
}
void CPDF_StreamContentParser::Handle_SetColor_Fill()
{
    if (m_Options.m_bTextOnly) {
        return;
    }
    FX_FLOAT values[4];
    int nargs = m_ParamCount;
    if (nargs > 4) {
        nargs = 4;
    }
    for (int i = 0; i < nargs; i ++) {
        values[i] = GetNumber(nargs - i - 1);
    }
    m_pCurStates->m_ColorState.SetFillColor(NULL, values, nargs);
}
void CPDF_StreamContentParser::Handle_SetColor_Stroke()
{
    if (m_Options.m_bTextOnly) {
        return;
    }
    FX_FLOAT values[4];
    int nargs = m_ParamCount;
    if (nargs > 4) {
        nargs = 4;
    }
    for (int i = 0; i < nargs; i ++) {
        values[i] = GetNumber(nargs - i - 1);
    }
    m_pCurStates->m_ColorState.SetStrokeColor(NULL, values, nargs);
}
void CPDF_StreamContentParser::Handle_SetColorPS_Fill()
{
    if (m_Options.m_bTextOnly) {
        return;
    }
    CPDF_Object* pLastParam = GetObject(0);
    if (pLastParam == NULL) {
        return;
    }
    int nargs = m_ParamCount;
    int nvalues = nargs;
    if (pLastParam->GetType() == PDFOBJ_NAME) {
        nvalues --;
    }
    FX_FLOAT* values = NULL;
    if (nvalues) {
        values = FX_Alloc(FX_FLOAT, nvalues);
        for (int i = 0; i < nvalues; i ++) {
            values[i] = GetNumber(nargs - i - 1);
        }
    }
    if (nvalues != nargs) {
        CPDF_Pattern* pPattern = FindPattern(GetString(0), FALSE);
        if (pPattern) {
            m_pCurStates->m_ColorState.SetFillPattern(pPattern, values, nvalues);
        }
    } else {
        m_pCurStates->m_ColorState.SetFillColor(NULL, values, nvalues);
    }
    if (values) {
        FX_Free(values);
    }
}
void CPDF_StreamContentParser::Handle_SetColorPS_Stroke()
{
    if (m_Options.m_bTextOnly) {
        return;
    }
    CPDF_Object* pLastParam = GetObject(0);
    if (pLastParam == NULL) {
        return;
    }
    int nargs = m_ParamCount;
    int nvalues = nargs;
    if (pLastParam->GetType() == PDFOBJ_NAME) {
        nvalues --;
    }
    FX_FLOAT* values = NULL;
    if (nvalues) {
        values = FX_Alloc(FX_FLOAT, nvalues);
        for (int i = 0; i < nvalues; i ++) {
            values[i] = GetNumber(nargs - i - 1);
        }
    }
    if (nvalues != nargs) {
        CPDF_Pattern* pPattern = FindPattern(GetString(0), FALSE);
        if (pPattern) {
            m_pCurStates->m_ColorState.SetStrokePattern(pPattern, values, nvalues);
        }
    } else {
        m_pCurStates->m_ColorState.SetStrokeColor(NULL, values, nvalues);
    }
    if (values) {
        FX_Free(values);
    }
}
CFX_FloatRect _GetShadingBBox(CPDF_Stream* pStream, int type, const CFX_AffineMatrix* pMatrix,
                              CPDF_Function** pFuncs, int nFuncs, CPDF_ColorSpace* pCS);
void CPDF_StreamContentParser::Handle_ShadeFill()
{
    if (m_Options.m_bTextOnly) {
        return;
    }
    CPDF_Pattern* pPattern = FindPattern(GetString(0), TRUE);
    if (pPattern == NULL) {
        return;
    }
    if (pPattern->m_PatternType != PATTERN_SHADING) {
        return;
    }
    CPDF_ShadingPattern* pShading = (CPDF_ShadingPattern*)pPattern;
    if (!pShading->m_bShadingObj) {
        return;
    }
    if (!pShading->Load()) {
        return;
    }
    CPDF_ShadingObject* pObj = new CPDF_ShadingObject;
    pObj->m_pShading = pShading;
    SetGraphicStates(pObj, FALSE, FALSE, FALSE);
    pObj->m_Matrix = m_pCurStates->m_CTM;
    pObj->m_Matrix.Concat(m_mtContentToUser);
    CFX_FloatRect bbox;
    if (!pObj->m_ClipPath.IsNull()) {
        bbox = pObj->m_ClipPath.GetClipBox();
    } else {
        bbox = m_BBox;
    }
    if (pShading->m_ShadingType >= 4) {
        bbox.Intersect(_GetShadingBBox((CPDF_Stream*)pShading->m_pShadingObj, pShading->m_ShadingType, &pObj->m_Matrix,
                                       pShading->m_pFunctions, pShading->m_nFuncs, pShading->m_pCS));
    }
    pObj->m_Left = bbox.left;
    pObj->m_Right = bbox.right;
    pObj->m_Top = bbox.top;
    pObj->m_Bottom = bbox.bottom;
    m_pObjectList->m_ObjectList.AddTail(pObj);
}
void CPDF_StreamContentParser::Handle_SetCharSpace()
{
    m_pCurStates->m_TextState.GetModify()->m_CharSpace = GetNumber(0);
}
void CPDF_StreamContentParser::Handle_MoveTextPoint()
{
    m_pCurStates->m_TextLineX += GetNumber(1);
    m_pCurStates->m_TextLineY += GetNumber(0);
    m_pCurStates->m_TextX = m_pCurStates->m_TextLineX;
    m_pCurStates->m_TextY = m_pCurStates->m_TextLineY;
}
void CPDF_StreamContentParser::Handle_MoveTextPoint_SetLeading()
{
    Handle_MoveTextPoint();
    m_pCurStates->m_TextLeading = -GetNumber(0);
}
void CPDF_StreamContentParser::Handle_SetFont()
{
    FX_FLOAT fs = GetNumber(0);
    if (fs == 0) {
        fs = m_DefFontSize;
    }
    m_pCurStates->m_TextState.GetModify()->m_FontSize = fs;
    CPDF_Font* pFont = FindFont(GetString(1));
    if (pFont) {
        m_pCurStates->m_TextState.SetFont(pFont);
    }
}
CPDF_Object* CPDF_StreamContentParser::FindResourceObj(const CFX_ByteStringC& type, const CFX_ByteString& name)
{
    if (m_pResources == NULL) {
        return NULL;
    }
    if (m_pResources == m_pPageResources) {
        CPDF_Dictionary* pList = m_pResources->GetDict(type);
        if (pList == NULL) {
            return NULL;
        }
        CPDF_Object* pRes = pList->GetElementValue(name);
        return pRes;
    }
    CPDF_Dictionary* pList = m_pResources->GetDict(type);
    if (pList == NULL) {
        if (m_pPageResources == NULL) {
            return NULL;
        }
        CPDF_Dictionary* pList = m_pPageResources->GetDict(type);
        if (pList == NULL) {
            return NULL;
        }
        CPDF_Object* pRes = pList->GetElementValue(name);
        return pRes;
    }
    CPDF_Object* pRes = pList->GetElementValue(name);
    return pRes;
}
CPDF_Font* CPDF_StreamContentParser::FindFont(const CFX_ByteString& name)
{
    CPDF_Dictionary* pFontDict = (CPDF_Dictionary*)FindResourceObj(FX_BSTRC("Font"), name);
    if (pFontDict == NULL || pFontDict->GetType() != PDFOBJ_DICTIONARY) {
        m_bResourceMissing = TRUE;
        return CPDF_Font::GetStockFont(m_pDocument, FX_BSTRC("Helvetica"));
    }
    CPDF_Font* pFont = m_pDocument->LoadFont(pFontDict);
    if (pFont && pFont->GetType3Font()) {
        pFont->GetType3Font()->SetPageResources(m_pResources);
        pFont->GetType3Font()->CheckType3FontMetrics();
    }
    return pFont;
}
CPDF_ColorSpace* CPDF_StreamContentParser::FindColorSpace(const CFX_ByteString& name)
{
    if (name == FX_BSTRC("Pattern")) {
        return CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN);
    }
    if (name == FX_BSTRC("DeviceGray") || name == FX_BSTRC("DeviceCMYK") || name == FX_BSTRC("DeviceRGB")) {
        CFX_ByteString defname = "Default";
        defname += name.Mid(7);
        CPDF_Object* pDefObj = FindResourceObj(FX_BSTRC("ColorSpace"), defname);
        if (pDefObj == NULL) {
            if (name == FX_BSTRC("DeviceGray")) {
                return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY);
            }
            if (name == FX_BSTRC("DeviceRGB")) {
                return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB);
            }
            return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK);
        }
        return m_pDocument->LoadColorSpace(pDefObj);
    }
    CPDF_Object* pCSObj = FindResourceObj(FX_BSTRC("ColorSpace"), name);
    if (pCSObj == NULL) {
        m_bResourceMissing = TRUE;
        return NULL;
    }
    return m_pDocument->LoadColorSpace(pCSObj);
}
CPDF_Pattern* CPDF_StreamContentParser::FindPattern(const CFX_ByteString& name, FX_BOOL bShading)
{
    CPDF_Object* pPattern = FindResourceObj(bShading ? FX_BSTRC("Shading") : FX_BSTRC("Pattern"), name);
    if (pPattern == NULL || (pPattern->GetType() != PDFOBJ_DICTIONARY &&
                             pPattern->GetType() != PDFOBJ_STREAM)) {
        m_bResourceMissing = TRUE;
        return NULL;
    }
    return m_pDocument->LoadPattern(pPattern, bShading, &m_pCurStates->m_ParentMatrix);
}
void CPDF_StreamContentParser::ConvertTextSpace(FX_FLOAT& x, FX_FLOAT& y)
{
    m_pCurStates->m_TextMatrix.Transform(x, y, x, y);
    ConvertUserSpace(x, y);
}
void CPDF_StreamContentParser::ConvertUserSpace(FX_FLOAT& x, FX_FLOAT& y)
{
    m_pCurStates->m_CTM.Transform(x, y, x, y);
    m_mtContentToUser.Transform(x, y, x, y);
}
void CPDF_StreamContentParser::AddTextObject(CFX_ByteString* pStrs, FX_FLOAT fInitKerning, FX_FLOAT* pKerning, int nsegs)
{
    CPDF_Font* pFont = m_pCurStates->m_TextState.GetFont();
    if (pFont == NULL) {
        return;
    }
    if (fInitKerning != 0) {
        if (!pFont->IsVertWriting()) {
            m_pCurStates->m_TextX -= FXSYS_Mul(fInitKerning, m_pCurStates->m_TextState.GetFontSize()) / 1000;
        } else {
            m_pCurStates->m_TextY -= FXSYS_Mul(fInitKerning, m_pCurStates->m_TextState.GetFontSize()) / 1000;
        }
    }
    if (nsegs == 0) {
        return;
    }
    int textmode;
    if (pFont->GetFontType() == PDFFONT_TYPE3) {
        textmode = 0;
    } else {
        textmode = m_pCurStates->m_TextState.GetObject()->m_TextMode;
    }
    CPDF_TextObject* pText = new CPDF_TextObject;
    m_pLastTextObject = pText;
    SetGraphicStates(pText, TRUE, TRUE, TRUE);
    if (textmode && textmode != 3 && textmode != 4 && textmode != 7) {
        FX_FLOAT* pCTM = pText->m_TextState.GetModify()->m_CTM;
        pCTM[0] = m_pCurStates->m_CTM.a;
        pCTM[1] = m_pCurStates->m_CTM.c;
        pCTM[2] = m_pCurStates->m_CTM.b;
        pCTM[3] = m_pCurStates->m_CTM.d;
    }
    pText->SetSegments(pStrs, pKerning, nsegs);
    pText->m_PosX = m_pCurStates->m_TextX;
    pText->m_PosY = m_pCurStates->m_TextY + m_pCurStates->m_TextRise;
    ConvertTextSpace(pText->m_PosX, pText->m_PosY);
    FX_FLOAT x_advance, y_advance;
    pText->CalcPositionData(&x_advance, &y_advance, m_pCurStates->m_TextHorzScale, m_Level);
    m_pCurStates->m_TextX += x_advance;
    m_pCurStates->m_TextY += y_advance;
    if (textmode > 3) {
        CPDF_TextObject* pCopy = new CPDF_TextObject;
        pCopy->Copy(pText);
        m_ClipTextList.Add(pCopy);
    }
    m_pObjectList->m_ObjectList.AddTail(pText);
    if (pKerning && pKerning[nsegs - 1] != 0) {
        if (!pFont->IsVertWriting()) {
            m_pCurStates->m_TextX -= FXSYS_Mul(pKerning[nsegs - 1], m_pCurStates->m_TextState.GetFontSize()) / 1000;
        } else {
            m_pCurStates->m_TextY -= FXSYS_Mul(pKerning[nsegs - 1], m_pCurStates->m_TextState.GetFontSize()) / 1000;
        }
    }
}
void CPDF_StreamContentParser::Handle_ShowText()
{
    CFX_ByteString str = GetString(0);
    if (str.IsEmpty()) {
        return;
    }
    AddTextObject(&str, 0, NULL, 1);
}
void CPDF_StreamContentParser::Handle_ShowText_Positioning()
{
    CPDF_Array* pArray = GetObject(0) ? GetObject(0)->GetArray() : NULL;
    if (pArray == NULL) {
        return;
    }
    int n = pArray->GetCount(), nsegs = 0, i;
    for (i = 0; i < n; i ++) {
        CPDF_Object* pObj = pArray->GetElementValue(i);
        if (pObj->GetType() == PDFOBJ_STRING) {
            nsegs ++;
        }
    }
    if (nsegs == 0) {
        for (i = 0; i < n; i ++) {
            m_pCurStates->m_TextX -= FXSYS_Mul(pArray->GetNumber(i), m_pCurStates->m_TextState.GetFontSize()) / 1000;
        };
        return;
    }
    CFX_ByteString* pStrs = new CFX_ByteString[nsegs];
    FX_FLOAT* pKerning = FX_Alloc(FX_FLOAT, nsegs);
    int iSegment = 0;
    FX_FLOAT fInitKerning = 0;
    for (i = 0; i < n; i ++) {
        CPDF_Object* pObj = pArray->GetElementValue(i);
        if (pObj->GetType() == PDFOBJ_STRING) {
            CFX_ByteString str = pObj->GetString();
            if (str.IsEmpty()) {
                continue;
            }
            pStrs[iSegment] = str;
            pKerning[iSegment ++] = 0;
        } else {
            FX_FLOAT num = pObj ? pObj->GetNumber() : 0;
            if (iSegment == 0) {
                fInitKerning += num;
            } else {
                pKerning[iSegment - 1] += num;
            }
        }
    }
    AddTextObject(pStrs, fInitKerning, pKerning, iSegment);
    delete[] pStrs;
    FX_Free(pKerning);
}
void CPDF_StreamContentParser::Handle_SetTextLeading()
{
    m_pCurStates->m_TextLeading = GetNumber(0);
}
void CPDF_StreamContentParser::Handle_SetTextMatrix()
{
    m_pCurStates->m_TextMatrix.Set(GetNumber16(5), GetNumber16(4), GetNumber16(3),
                                   GetNumber16(2), GetNumber(1), GetNumber(0));
    OnChangeTextMatrix();
    m_pCurStates->m_TextX = 0;
    m_pCurStates->m_TextY = 0;
    m_pCurStates->m_TextLineX = 0;
    m_pCurStates->m_TextLineY = 0;
}
void CPDF_StreamContentParser::OnChangeTextMatrix()
{
    CFX_AffineMatrix text_matrix(m_pCurStates->m_TextHorzScale, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
    text_matrix.Concat(m_pCurStates->m_TextMatrix);
    text_matrix.Concat(m_pCurStates->m_CTM);
    text_matrix.Concat(m_mtContentToUser);
    FX_FLOAT* pTextMatrix = m_pCurStates->m_TextState.GetModify()->m_Matrix;
    pTextMatrix[0] = text_matrix.a;
    pTextMatrix[1] = text_matrix.c;
    pTextMatrix[2] = text_matrix.b;
    pTextMatrix[3] = text_matrix.d;
}
void CPDF_StreamContentParser::Handle_SetTextRenderMode()
{
    int mode = GetInteger(0);
    if (mode < 0 || mode > 7) {
        return;
    }
    m_pCurStates->m_TextState.GetModify()->m_TextMode = mode;
}
void CPDF_StreamContentParser::Handle_SetTextRise()
{
    m_pCurStates->m_TextRise = GetNumber(0);
}
void CPDF_StreamContentParser::Handle_SetWordSpace()
{
    m_pCurStates->m_TextState.GetModify()->m_WordSpace = GetNumber(0);
}
void CPDF_StreamContentParser::Handle_SetHorzScale()
{
    if (m_ParamCount != 1) {
        return;
    }
    m_pCurStates->m_TextHorzScale = GetNumber(0) / 100;
    OnChangeTextMatrix();
}
void CPDF_StreamContentParser::Handle_MoveToNextLine()
{
    m_pCurStates->m_TextLineY -= m_pCurStates->m_TextLeading;
    m_pCurStates->m_TextX = m_pCurStates->m_TextLineX;
    m_pCurStates->m_TextY = m_pCurStates->m_TextLineY;
}
void CPDF_StreamContentParser::Handle_CurveTo_23()
{
    if (m_Options.m_bTextOnly) {
        return;
    }
    AddPathPoint(m_PathCurrentX, m_PathCurrentY, FXPT_BEZIERTO);
    AddPathPoint(GetNumber(3), GetNumber(2), FXPT_BEZIERTO);
    AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO);
}
void CPDF_StreamContentParser::Handle_SetLineWidth()
{
    FX_FLOAT width = GetNumber(0);
    m_pCurStates->m_GraphState.GetModify()->m_LineWidth = width;
}
void CPDF_StreamContentParser::Handle_Clip()
{
    m_PathClipType = FXFILL_WINDING;
}
void CPDF_StreamContentParser::Handle_EOClip()
{
    m_PathClipType = FXFILL_ALTERNATE;
}
void CPDF_StreamContentParser::Handle_CurveTo_13()
{
    if (m_Options.m_bTextOnly) {
        return;
    }
    AddPathPoint(GetNumber(3), GetNumber(2), FXPT_BEZIERTO);
    AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO);
    AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO);
}
void CPDF_StreamContentParser::Handle_NextLineShowText()
{
    Handle_MoveToNextLine();
    Handle_ShowText();
}
void CPDF_StreamContentParser::Handle_NextLineShowText_Space()
{
    m_pCurStates->m_TextState.GetModify()->m_WordSpace = GetNumber(2);
    m_pCurStates->m_TextState.GetModify()->m_CharSpace = GetNumber(1);
    Handle_NextLineShowText();
}
void CPDF_StreamContentParser::Handle_Invalid()
{
}
void CPDF_StreamContentParser::AddPathPoint(FX_FLOAT x, FX_FLOAT y, int flag)
{
    m_PathCurrentX = x;
    m_PathCurrentY = y;
    if (flag == FXPT_MOVETO) {
        m_PathStartX = x;
        m_PathStartY = y;
        if (m_PathPointCount && m_pPathPoints[m_PathPointCount - 1].m_Flag == FXPT_MOVETO) {
            m_pPathPoints[m_PathPointCount - 1].m_PointX = x;
            m_pPathPoints[m_PathPointCount - 1].m_PointY = y;
            return;
        }
    } else if (m_PathPointCount == 0) {
        return;
    }
    m_PathPointCount ++;
    if (m_PathPointCount > m_PathAllocSize) {
        int newsize = m_PathPointCount + 256;
        FX_PATHPOINT* pNewPoints = FX_Alloc(FX_PATHPOINT, newsize);
        if (m_PathAllocSize) {
            FXSYS_memcpy(pNewPoints, m_pPathPoints, m_PathAllocSize * sizeof(FX_PATHPOINT));
            FX_Free(m_pPathPoints);
        }
        m_pPathPoints = pNewPoints;
        m_PathAllocSize = newsize;
    }
    m_pPathPoints[m_PathPointCount - 1].m_Flag = flag;
    m_pPathPoints[m_PathPointCount - 1].m_PointX = x;
    m_pPathPoints[m_PathPointCount - 1].m_PointY = y;
}
void CPDF_StreamContentParser::AddPathObject(int FillType, FX_BOOL bStroke)
{
    int PathPointCount = m_PathPointCount, PathClipType = m_PathClipType;
    m_PathPointCount = 0;
    m_PathClipType = 0;
    if (PathPointCount <= 1) {
        if (PathPointCount && PathClipType) {
            CPDF_Path path;
            path.New()->AppendRect(0, 0, 0, 0);
            m_pCurStates->m_ClipPath.AppendPath(path, FXFILL_WINDING, TRUE);
        }
        return;
    }
    if (PathPointCount && m_pPathPoints[PathPointCount - 1].m_Flag == FXPT_MOVETO) {
        PathPointCount --;
    }
    CPDF_Path Path;
    CFX_PathData* pPathData = Path.New();
    pPathData->SetPointCount(PathPointCount);
    FXSYS_memcpy(pPathData->GetPoints(), m_pPathPoints, sizeof(FX_PATHPOINT) * PathPointCount);
    CFX_AffineMatrix matrix = m_pCurStates->m_CTM;
    matrix.Concat(m_mtContentToUser);
    if (bStroke || FillType) {
        CPDF_PathObject* pPathObj = new CPDF_PathObject;
        pPathObj->m_bStroke = bStroke;
        pPathObj->m_FillType = FillType;
        pPathObj->m_Path = Path;
        pPathObj->m_Matrix = matrix;
        SetGraphicStates(pPathObj, TRUE, FALSE, TRUE);
        pPathObj->CalcBoundingBox();
        m_pObjectList->m_ObjectList.AddTail(pPathObj);
    }
    if (PathClipType) {
        if (!matrix.IsIdentity()) {
            Path.Transform(&matrix);
            matrix.SetIdentity();
        }
        m_pCurStates->m_ClipPath.AppendPath(Path, PathClipType, TRUE);
    }
}
CFX_ByteString _FPDF_ByteStringFromHex(CFX_BinaryBuf& src_buf)
{
    CFX_ByteTextBuf buf;
    FX_BOOL bFirst = TRUE;
    int code = 0;
    const uint8_t* str = src_buf.GetBuffer();
    FX_DWORD size = src_buf.GetSize();
    for (FX_DWORD i = 0; i < size; i ++) {
        uint8_t ch = str[i];
        if (ch >= '0' && ch <= '9') {
            if (bFirst) {
                code = (ch - '0') * 16;
            } else {
                code += ch - '0';
                buf.AppendChar((char)code);
            }
            bFirst = !bFirst;
        } else if (ch >= 'A' && ch <= 'F') {
            if (bFirst) {
                code = (ch - 'A' + 10) * 16;
            } else {
                code += ch - 'A' + 10;
                buf.AppendChar((char)code);
            }
            bFirst = !bFirst;
        } else if (ch >= 'a' && ch <= 'f') {
            if (bFirst) {
                code = (ch - 'a' + 10) * 16;
            } else {
                code += ch - 'a' + 10;
                buf.AppendChar((char)code);
            }
            bFirst = !bFirst;
        }
    }
    if (!bFirst) {
        buf.AppendChar((char)code);
    }
    return buf.GetByteString();
}
