// 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 "pageint.h"

#include "core/include/fpdfapi/fpdf_module.h"
#include "core/include/fpdfapi/fpdf_page.h"
#include "core/include/fpdfapi/fpdf_serial.h"

#define REQUIRE_PARAMS(count)  \
  if (m_ParamCount != count) { \
    return;                    \
  }

CPDF_StreamContentParser::CPDF_StreamContentParser(
    CPDF_Document* pDocument,
    CPDF_Dictionary* pPageResources,
    CPDF_Dictionary* pParentResources,
    CFX_Matrix* pmtContentToUser,
    CPDF_PageObjects* pObjList,
    CPDF_Dictionary* pResources,
    CPDF_Rect* pBBox,
    CPDF_ParseOptions* pOptions,
    CPDF_AllStates* pStates,
    int level)
    : m_pDocument(pDocument),
      m_pPageResources(pPageResources),
      m_pParentResources(pParentResources),
      m_pResources(pResources),
      m_pObjectList(pObjList),
      m_Level(level),
      m_ParamStartPos(0),
      m_ParamCount(0),
      m_pCurStates(new CPDF_AllStates),
      m_pLastTextObject(nullptr),
      m_DefFontSize(0),
      m_pPathPoints(nullptr),
      m_PathPointCount(0),
      m_PathAllocSize(0),
      m_PathCurrentX(0.0f),
      m_PathCurrentY(0.0f),
      m_PathClipType(0),
      m_pLastImage(nullptr),
      m_pLastImageDict(nullptr),
      m_pLastCloneImageDict(nullptr),
      m_bReleaseLastDict(TRUE),
      m_bColored(FALSE),
      m_bResourceMissing(FALSE) {
  if (pmtContentToUser) {
    m_mtContentToUser = *pmtContentToUser;
  }
  if (pOptions) {
    m_Options = *pOptions;
  }
  if (!m_pResources) {
    m_pResources = m_pParentResources;
  }
  if (!m_pResources) {
    m_pResources = m_pPageResources;
  }
  if (pBBox) {
    m_BBox = *pBBox;
  }
  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();
  }
  for (size_t i = 0; i < FX_ArraySize(m_Type3Data); ++i) {
    m_Type3Data[i] = 0.0;
  }
}

CPDF_StreamContentParser::~CPDF_StreamContentParser() {
  ClearAllParams();
  for (int i = 0; i < m_StateStack.GetSize(); ++i) {
    delete m_StateStack[i];
  }
  FX_Free(m_pPathPoints);
  if (m_pLastImageDict) {
    m_pLastImageDict->Release();
  }
  if (m_pLastCloneImageDict) {
    m_pLastCloneImageDict->Release();
  }
}
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)) {
      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 = param.m_Number.m_bInteger
                               ? CPDF_Number::Create(param.m_Number.m_Integer)
                               : CPDF_Number::Create(param.m_Number.m_Float);

    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 CPDF_StreamContentParser::OpCode CPDF_StreamContentParser::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(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;
    }
    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) {
    return;
  }
  FX_BOOL bDirect = TRUE;
  if (pProperty->IsName()) {
    pProperty = FindResourceObj("Properties", pProperty->GetString());
    if (!pProperty)
      return;
    bDirect = FALSE;
  }
  if (CPDF_Dictionary* pDict = pProperty->AsDictionary()) {
    m_CurContentMark.GetModify()->AddMark(tag, pDict, 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 = pObj->AsDictionary();
      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->IsName()) {
          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 = pObj->AsArray();
      for (FX_DWORD i = 0; i < pArray->GetCount(); i++) {
        CPDF_Object* pElement = pArray->GetElement(i);
        if (pElement->IsName()) {
          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 = pObj->AsDictionary();
      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->IsName()) {
          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 = pObj->AsArray();
      for (FX_DWORD i = 0; i < pArray->GetCount(); i++) {
        CPDF_Object* pElement = pArray->GetElement(i);
        if (pElement->IsName()) {
          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_Matrix 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) {
    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) {
    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) {
    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(nullptr, m_pLastImage, FALSE);
    return;
  }

  if (m_Options.m_bTextOnly) {
    if (!m_pResources)
      return;

    CPDF_Dictionary* pList = m_pResources->GetDict("XObject");
    if (!pList && m_pPageResources && m_pResources != m_pPageResources)
      pList = m_pPageResources->GetDict("XObject");
    if (!pList)
      return;
    CPDF_Reference* pRes = ToReference(pList->GetElement(name));
    if (!pRes)
      return;

    FX_BOOL bForm;
    if (m_pDocument->IsFormStream(pRes->GetRefObjNum(), bForm) && !bForm)
      return;
  }

  CPDF_Stream* pXObject = ToStream(FindResourceObj("XObject", name));
  if (!pXObject) {
    m_bResourceMissing = TRUE;
    return;
  }

  CFX_ByteStringC type = pXObject->GetDict()
                             ? pXObject->GetDict()->GetConstString("Subtype")
                             : CFX_ByteStringC();
  if (type == "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 == "Form") {
    AddForm(pXObject);
  } else {
    return;
  }
}
void CPDF_StreamContentParser::AddForm(CPDF_Stream* pStream) {
  if (!m_Options.m_bSeparateForm) {
    CPDF_Dictionary* pResources = pStream->GetDict()->GetDict("Resources");
    CFX_Matrix form_matrix = pStream->GetDict()->GetMatrix("Matrix");
    form_matrix.Concat(m_pCurStates->m_CTM);
    CPDF_Array* pBBox = pStream->GetDict()->GetArray("BBox");
    CFX_FloatRect form_bbox;
    CPDF_Path ClipPath;
    if (pBBox) {
      form_bbox = pStream->GetDict()->GetRect("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(m_pDocument, m_pPageResources, m_pResources,
                                    &m_mtContentToUser, m_pObjectList,
                                    pResources, &form_bbox, &m_Options,
                                    m_pCurStates.get(), 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 && !pImage) {
    return NULL;
  }
  CFX_Matrix 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++) {
      delete m_ClipTextList.GetAt(i);
    }
  } else {
    m_pCurStates->m_ClipPath.AppendTexts(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 = ToDictionary(FindResourceObj("ExtGState", name));
  if (!pGS) {
    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 = 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) {
    return;
  }
  int nargs = m_ParamCount;
  int nvalues = nargs;
  if (pLastParam->IsName()) {
    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);
  }
  FX_Free(values);
}
void CPDF_StreamContentParser::Handle_SetColorPS_Stroke() {
  if (m_Options.m_bTextOnly) {
    return;
  }
  CPDF_Object* pLastParam = GetObject(0);
  if (!pLastParam) {
    return;
  }
  int nargs = m_ParamCount;
  int nvalues = nargs;
  if (pLastParam->IsName())
    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);
  }
  FX_Free(values);
}
CFX_FloatRect GetShadingBBox(CPDF_Stream* pStream,
                             ShadingType type,
                             const CFX_Matrix* 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) {
    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->IsMeshShading()) {
    bbox.Intersect(GetShadingBBox(ToStream(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) {
    return NULL;
  }
  if (m_pResources == m_pPageResources) {
    CPDF_Dictionary* pList = m_pResources->GetDict(type);
    if (!pList) {
      return NULL;
    }
    CPDF_Object* pRes = pList->GetElementValue(name);
    return pRes;
  }
  CPDF_Dictionary* pList = m_pResources->GetDict(type);
  if (!pList) {
    if (!m_pPageResources) {
      return NULL;
    }
    CPDF_Dictionary* pList = m_pPageResources->GetDict(type);
    if (!pList) {
      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 = ToDictionary(FindResourceObj("Font", name));
  if (!pFontDict) {
    m_bResourceMissing = TRUE;
    return CPDF_Font::GetStockFont(m_pDocument, "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 == "Pattern") {
    return CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN);
  }
  if (name == "DeviceGray" || name == "DeviceCMYK" || name == "DeviceRGB") {
    CFX_ByteString defname = "Default";
    defname += name.Mid(7);
    CPDF_Object* pDefObj = FindResourceObj("ColorSpace", defname);
    if (!pDefObj) {
      if (name == "DeviceGray") {
        return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY);
      }
      if (name == "DeviceRGB") {
        return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB);
      }
      return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK);
    }
    return m_pDocument->LoadColorSpace(pDefObj);
  }
  CPDF_Object* pCSObj = FindResourceObj("ColorSpace", name);
  if (!pCSObj) {
    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 ? "Shading" : "Pattern", name);
  if (!pPattern || (!pPattern->IsDictionary() && !pPattern->IsStream())) {
    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) {
    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) {
    return;
  }
  int n = pArray->GetCount();
  int nsegs = 0;
  for (int i = 0; i < n; i++) {
    if (pArray->GetElementValue(i)->IsString())
      nsegs++;
  }
  if (nsegs == 0) {
    for (int 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 (int i = 0; i < n; i++) {
    CPDF_Object* pObj = pArray->GetElementValue(i);
    if (pObj->IsString()) {
      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_Matrix 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_Matrix 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);
  }
}
