CPDF_Object* CPDF_Dictionary::GetElementValue(
    const CFX_ByteStringC& key) const {
  CPDF_Object* p = GetElement(key);
  return p ? p->GetDirect() : nullptr;
}
Example #2
0
CPDF_Object* CPDF_Dictionary::GetElementValue(FX_BSTR key) const
{
    CPDF_Object* p = NULL;
    m_Map.Lookup(key, (void*&)p);
    return p ? p->GetDirect() : NULL;
}
Example #3
0
DLLEXPORT void STDCALL FPDFPage_InsertClipPath(FPDF_PAGE page,
                                               FPDF_CLIPPATH clipPath) {
  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
  if (!pPage)
    return;

  CPDF_Dictionary* pPageDic = pPage->m_pFormDict;
  CPDF_Object* pContentObj =
      pPageDic ? pPageDic->GetElement("Contents") : nullptr;
  if (!pContentObj)
    pContentObj = pPageDic ? pPageDic->GetArrayBy("Contents") : nullptr;
  if (!pContentObj)
    return;

  CFX_ByteTextBuf strClip;
  CPDF_ClipPath* pClipPath = (CPDF_ClipPath*)clipPath;
  FX_DWORD i;
  for (i = 0; i < pClipPath->GetPathCount(); i++) {
    CPDF_Path path = pClipPath->GetPath(i);
    int iClipType = pClipPath->GetClipType(i);
    if (path.GetPointCount() == 0) {
      // Empty clipping (totally clipped out)
      strClip << "0 0 m W n ";
    } else {
      OutputPath(strClip, path);
      if (iClipType == FXFILL_WINDING)
        strClip << "W n\n";
      else
        strClip << "W* n\n";
    }
  }
  CPDF_Dictionary* pDic = new CPDF_Dictionary;
  CPDF_Stream* pStream = new CPDF_Stream(nullptr, 0, pDic);
  pStream->SetData(strClip.GetBuffer(), strClip.GetSize(), FALSE, FALSE);
  CPDF_Document* pDoc = pPage->m_pDocument;
  if (!pDoc)
    return;
  pDoc->AddIndirectObject(pStream);

  CPDF_Array* pContentArray = nullptr;
  if (CPDF_Array* pArray = ToArray(pContentObj)) {
    pContentArray = pArray;
    CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum());
    pContentArray->InsertAt(0, pRef);
  } else if (CPDF_Reference* pReference = ToReference(pContentObj)) {
    CPDF_Object* pDirectObj = pReference->GetDirect();
    if (pDirectObj) {
      if (CPDF_Array* pArray = pDirectObj->AsArray()) {
        pContentArray = pArray;
        CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum());
        pContentArray->InsertAt(0, pRef);
      } else if (pDirectObj->IsStream()) {
        pContentArray = new CPDF_Array();
        pContentArray->AddReference(pDoc, pStream->GetObjNum());
        pContentArray->AddReference(pDoc, pDirectObj->GetObjNum());
        pPageDic->SetAtReference("Contents", pDoc,
                                 pDoc->AddIndirectObject(pContentArray));
      }
    }
  }
}
void CPDF_StreamContentParser::EndImageDict()
{
    if (m_StringBuf.GetSize() != m_LastImageDict.GetSize() ||
            FXSYS_memcmp32(m_StringBuf.GetBuffer(), m_LastImageDict.GetBuffer(), m_StringBuf.GetSize())) {
        m_WordState = 0;
        StartDict();
        InputData(m_StringBuf.GetBuffer(), m_StringBuf.GetSize());
        Finish();
        m_bSameLastDict = FALSE;
        if (m_pLastImageDict && m_bReleaseLastDict) {
            m_pLastImageDict->Release();
            m_pLastImageDict = NULL;
        }
        if (!m_ObjectSize) {
            m_InlineImageState = 0;
            return;
        }
        m_pLastImageDict = (CPDF_Dictionary*)m_pObjectStack[--m_ObjectSize];
        m_bReleaseLastDict = !m_pObjectState[m_ObjectSize];
        m_pObjectState[m_ObjectSize] = FALSE;
        _PDF_ReplaceAbbr(m_pLastImageDict);
        m_LastImageDict.TakeOver(m_StringBuf);
        if (m_pLastImageDict->KeyExist(FX_BSTRC("ColorSpace"))) {
            CPDF_Object* pCSObj = m_pLastImageDict->GetElementValue(FX_BSTRC("ColorSpace"));
            if (pCSObj->GetType() == PDFOBJ_NAME) {
                CFX_ByteString name = pCSObj->GetString();
                if (name != FX_BSTRC("DeviceRGB") && name != FX_BSTRC("DeviceGray") && name != FX_BSTRC("DeviceCMYK")) {
                    pCSObj = FindResourceObj(FX_BSTRC("ColorSpace"), name);
                    if (pCSObj) {
                        if (!pCSObj->GetObjNum()) {
                            pCSObj = pCSObj->Clone();
                        }
                        m_pLastImageDict->SetAt(FX_BSTRC("ColorSpace"), pCSObj, m_pDocument);
                    }
                }
            }
        }
    } else {
        m_bSameLastDict = TRUE;
    }
    m_ImageSrcBuf.Clear();
    if (m_pLastCloneImageDict) {
        m_pLastCloneImageDict->Release();
    }
    m_pLastCloneImageDict = (CPDF_Dictionary*)m_pLastImageDict->Clone();
    if (m_pLastCloneImageDict->KeyExist(FX_BSTRC("Filter"))) {
        m_WordState = 10;
        m_InlineImageState = 0;
    } else {
        int width = m_pLastCloneImageDict->GetInteger(FX_BSTRC("Width"));
        int height = m_pLastCloneImageDict->GetInteger(FX_BSTRC("Height"));
        int OrigSize = 0;
        CPDF_Object* pCSObj = m_pLastCloneImageDict->GetElementValue(FX_BSTRC("ColorSpace"));
        if (pCSObj != NULL) {
            int bpc = m_pLastCloneImageDict->GetInteger(FX_BSTRC("BitsPerComponent"));
            int nComponents = 1;
            CPDF_ColorSpace* pCS = m_pDocument->LoadColorSpace(pCSObj);
            if (pCS == NULL) {
                nComponents = 3;
            } else {
                nComponents = pCS->CountComponents();
                m_pDocument->GetPageData()->ReleaseColorSpace(pCSObj);
            }
            int pitch = (width * bpc * nComponents + 7) / 8;
            OrigSize = pitch * height;
        } else {
            OrigSize = ((width + 7) / 8) * height;
        }
        m_ImageSrcBuf.AppendBlock(NULL, OrigSize);
        m_WordState = 11;
        m_InlineImageState = 0;
    }
}
Example #5
0
bool CPDF_DataAvail::CheckUnkownPageNode(uint32_t dwPageNo,
                                         PageNode* pPageNode,
                                         DownloadHints* pHints) {
  bool bExist = false;
  std::unique_ptr<CPDF_Object> pPage = GetObject(dwPageNo, pHints, &bExist);
  if (!bExist) {
    m_docStatus = PDF_DATAAVAIL_ERROR;
    return false;
  }

  if (!pPage) {
    if (m_docStatus == PDF_DATAAVAIL_ERROR)
      m_docStatus = PDF_DATAAVAIL_ERROR;
    return false;
  }

  if (pPage->IsArray()) {
    pPageNode->m_dwPageNo = dwPageNo;
    pPageNode->m_type = PDF_PAGENODE_ARRAY;
    return true;
  }

  if (!pPage->IsDictionary()) {
    m_docStatus = PDF_DATAAVAIL_ERROR;
    return false;
  }

  pPageNode->m_dwPageNo = dwPageNo;
  CPDF_Dictionary* pDict = pPage->GetDict();
  CFX_ByteString type = pDict->GetStringFor("Type");
  if (type == "Pages") {
    pPageNode->m_type = PDF_PAGENODE_PAGES;
    CPDF_Object* pKids = pDict->GetObjectFor("Kids");
    if (!pKids) {
      m_docStatus = PDF_DATAAVAIL_PAGE;
      return true;
    }

    switch (pKids->GetType()) {
      case CPDF_Object::REFERENCE: {
        CPDF_Reference* pKid = pKids->AsReference();
        PageNode* pNode = new PageNode();
        pPageNode->m_childNode.Add(pNode);
        pNode->m_dwPageNo = pKid->GetRefObjNum();
      } break;
      case CPDF_Object::ARRAY: {
        CPDF_Array* pKidsArray = pKids->AsArray();
        for (size_t i = 0; i < pKidsArray->GetCount(); ++i) {
          CPDF_Reference* pKid = ToReference(pKidsArray->GetObjectAt(i));
          if (!pKid)
            continue;

          PageNode* pNode = new PageNode();
          pPageNode->m_childNode.Add(pNode);
          pNode->m_dwPageNo = pKid->GetRefObjNum();
        }
      } break;
      default:
        break;
    }
  } else if (type == "Page") {
    pPageNode->m_type = PDF_PAGENODE_PAGE;
  } else {
    m_docStatus = PDF_DATAAVAIL_ERROR;
    return false;
  }
  return true;
}
DLLEXPORT FPDF_BOOL STDCALL FPDFPage_TransFormWithClip(FPDF_PAGE page, FS_MATRIX* matrix, FS_RECTF* clipRect)
{
	if(!page)
		return FALSE;

	CFX_ByteTextBuf textBuf;
	textBuf<<"q ";
	CFX_FloatRect rect(clipRect->left, clipRect->bottom, clipRect->right, clipRect->top);
	rect.Normalize();
	CFX_ByteString bsClipping;
	bsClipping.Format("%f %f %f %f re W* n ", rect.left, rect.bottom, rect.Width(), rect.Height());
	textBuf<<bsClipping;

	CFX_ByteString bsMatix;
	bsMatix.Format("%f %f %f %f %f %f cm ", matrix->a, matrix->b,matrix->c,matrix->d,matrix->e,matrix->f);
	textBuf<<bsMatix;
	

	CPDF_Page* pPage = (CPDF_Page*)page;
	CPDF_Dictionary* pPageDic = pPage->m_pFormDict;
	CPDF_Object* pContentObj = pPageDic->GetElement("Contents");
	if(!pContentObj)
		pContentObj = pPageDic->GetArray("Contents");
	if(!pContentObj)
		return FALSE;
	
	CPDF_Dictionary* pDic = FX_NEW CPDF_Dictionary;
	CPDF_Stream* pStream = FX_NEW CPDF_Stream(NULL,0, pDic);
	pStream->SetData(textBuf.GetBuffer(), textBuf.GetSize(), FALSE, FALSE);
	CPDF_Document* pDoc = pPage->m_pDocument;
	if(!pDoc)
		return FALSE;
	pDoc->AddIndirectObject(pStream);

	pDic = FX_NEW CPDF_Dictionary;
	CPDF_Stream* pEndStream = FX_NEW CPDF_Stream(NULL,0, pDic);
	pEndStream->SetData((FX_LPCBYTE)" Q", 2, FALSE, FALSE);
	pDoc->AddIndirectObject(pEndStream);
	
	CPDF_Array* pContentArray = NULL;
	if (pContentObj && pContentObj->GetType() == PDFOBJ_ARRAY)
	{
		pContentArray = (CPDF_Array*)pContentObj;
		CPDF_Reference* pRef = FX_NEW CPDF_Reference(pDoc, pStream->GetObjNum());
		pContentArray->InsertAt(0, pRef);
		pContentArray->AddReference(pDoc,pEndStream);
		
	}
	else if(pContentObj && pContentObj->GetType() == PDFOBJ_REFERENCE)
	{
		CPDF_Reference* pReference = (CPDF_Reference*)pContentObj;
		CPDF_Object* pDirectObj = pReference->GetDirect();
		if(pDirectObj != NULL)
		{
			if(pDirectObj->GetType() == PDFOBJ_ARRAY)
			{
				pContentArray = (CPDF_Array*)pDirectObj;
				CPDF_Reference* pRef = FX_NEW CPDF_Reference(pDoc, pStream->GetObjNum());
				pContentArray->InsertAt(0, pRef);
				pContentArray->AddReference(pDoc,pEndStream);
				
			}
			else if(pDirectObj->GetType() == PDFOBJ_STREAM)
			{
				pContentArray = FX_NEW CPDF_Array();
				pContentArray->AddReference(pDoc,pStream->GetObjNum());
				pContentArray->AddReference(pDoc,pDirectObj->GetObjNum());
				pContentArray->AddReference(pDoc, pEndStream);
				pPageDic->SetAtReference("Contents", pDoc, pDoc->AddIndirectObject(pContentArray));
			}
		}
	}	

	//Need to transform the patterns as well.
	CPDF_Dictionary* pRes = pPageDic->GetDict(FX_BSTRC("Resources"));
	if(pRes)
	{
		CPDF_Dictionary* pPattenDict = pRes->GetDict(FX_BSTRC("Pattern"));
		if(pPattenDict)
		{
			FX_POSITION pos = pPattenDict->GetStartPos();
			while(pos)
			{
				CPDF_Dictionary* pDict = NULL;
				CFX_ByteString key;
				CPDF_Object* pObj = pPattenDict->GetNextElement(pos, key);
				if(pObj->GetType() == PDFOBJ_REFERENCE)
					pObj = pObj->GetDirect();
				if(pObj->GetType() == PDFOBJ_DICTIONARY)
				{
					pDict = (CPDF_Dictionary*)pObj;
				}
				else if(pObj->GetType() == PDFOBJ_STREAM)
				{
					pDict = ((CPDF_Stream*)pObj)->GetDict();
				}
				else
					continue;
				
				CFX_AffineMatrix m = pDict->GetMatrix(FX_BSTRC("Matrix"));
				CFX_AffineMatrix t = *(CFX_AffineMatrix*)matrix;
				m.Concat(t);
				pDict->SetAtMatrix(FX_BSTRC("Matrix"), m);
			}
		}
	}

	return TRUE;
}
CPDF_Object* CPDF_StreamParser::ReadNextObject(FX_BOOL bAllowNestedArray, FX_BOOL bInArray)
{
    FX_BOOL bIsNumber;
    GetNextWord(bIsNumber);
    if (m_WordSize == 0) {
        return NULL;
    }
    if (bIsNumber) {
        m_WordBuffer[m_WordSize] = 0;
        return CPDF_Number::Create(CFX_ByteStringC(m_WordBuffer, m_WordSize));
    }
    int first_char = m_WordBuffer[0];
    if (first_char == '/') {
        return CPDF_Name::Create(PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)));
    }
    if (first_char == '(') {
        return CPDF_String::Create(ReadString());
    }
    if (first_char == '<') {
        if (m_WordSize == 1) {
            return CPDF_String::Create(ReadHexString(), TRUE);
        }
        CPDF_Dictionary* pDict = CPDF_Dictionary::Create();
        while (1) {
            GetNextWord(bIsNumber);
            if (m_WordSize == 0) {
                pDict->Release();
                return NULL;
            }
            if (m_WordSize == 2 && m_WordBuffer[0] == '>') {
                break;
            }
            if (m_WordBuffer[0] != '/') {
                pDict->Release();
                return NULL;
            }
            CFX_ByteString key = PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1));
            CPDF_Object* pObj = ReadNextObject(TRUE);
            if (pObj == NULL) {
                if (pDict) {
                    pDict->Release();
                }
                return NULL;
            }
            if (!key.IsEmpty()) {
                pDict->SetAt(key, pObj);
            } else {
                pObj->Release();
            }
        }
        return pDict;
    }
    if (first_char == '[') {
        if (!bAllowNestedArray && bInArray) {
            return NULL;
        }
        CPDF_Array* pArray = CPDF_Array::Create();
        while (1) {
            CPDF_Object* pObj = ReadNextObject(bAllowNestedArray, TRUE);
            if (pObj == NULL) {
                if (m_WordSize == 0 || m_WordBuffer[0] == ']') {
                    return pArray;
                }
                if (m_WordBuffer[0] == '[') {
                    continue;
                }
            } else {
                pArray->Add(pObj);
            }
        }
    }
    if (m_WordSize == 4) {
        if (*(FX_DWORD*)m_WordBuffer == FXDWORD_TRUE) {
            return CPDF_Boolean::Create(TRUE);
        }
        if (*(FX_DWORD*)m_WordBuffer == FXDWORD_NULL) {
            return CPDF_Null::Create();
        }
    } else if (m_WordSize == 5) {
        if (*(FX_DWORD*)m_WordBuffer == FXDWORD_FALS && m_WordBuffer[4] == 'e') {
            return CPDF_Boolean::Create(FALSE);
        }
    }
    return NULL;
}
FX_BOOL CPDF_FormField::ResetField(FX_BOOL bNotify) {
  switch (m_Type) {
    case CPDF_FormField::CheckBox:
    case CPDF_FormField::RadioButton: {
      int iCount = CountControls();
      if (iCount) {
        // TODO(weili): Check whether anything special needs to be done for
        // unison field. Otherwise, merge these branches.
        if (PDF_FormField_IsUnison(this)) {
          for (int i = 0; i < iCount; i++) {
            CheckControl(i, GetControl(i)->IsDefaultChecked(), FALSE);
          }
        } else {
          for (int i = 0; i < iCount; i++) {
            CheckControl(i, GetControl(i)->IsDefaultChecked(), FALSE);
          }
        }
      }
      if (bNotify && m_pForm->m_pFormNotify) {
        m_pForm->m_pFormNotify->AfterCheckedStatusChange(this);
      }
    } break;
    case CPDF_FormField::ComboBox:
    case CPDF_FormField::ListBox: {
      CFX_WideString csValue;
      ClearSelection();
      int iIndex = GetDefaultSelectedItem();
      if (iIndex >= 0)
        csValue = GetOptionLabel(iIndex);

      if (bNotify && !NotifyListOrComboBoxBeforeChange(csValue))
        return FALSE;

      SetItemSelection(iIndex, TRUE);
      if (bNotify)
        NotifyListOrComboBoxAfterChange();
    } break;
    case CPDF_FormField::Text:
    case CPDF_FormField::RichText:
    case CPDF_FormField::File:
    default: {
      CPDF_Object* pDV = FPDF_GetFieldAttr(m_pDict, "DV");
      CFX_WideString csDValue;
      if (pDV)
        csDValue = pDV->GetUnicodeText();

      CPDF_Object* pV = FPDF_GetFieldAttr(m_pDict, "V");
      CFX_WideString csValue;
      if (pV)
        csValue = pV->GetUnicodeText();

      CPDF_Object* pRV = FPDF_GetFieldAttr(m_pDict, "RV");
      if (!pRV && (csDValue == csValue))
        return FALSE;

      if (bNotify && !NotifyBeforeValueChange(csDValue))
        return FALSE;

      if (pDV) {
        CPDF_Object* pClone = pDV->Clone();
        if (!pClone)
          return FALSE;

        m_pDict->SetAt("V", pClone);
        if (pRV) {
          CPDF_Object* pCloneR = pDV->Clone();
          m_pDict->SetAt("RV", pCloneR);
        }
      } else {
        m_pDict->RemoveAt("V");
        m_pDict->RemoveAt("RV");
      }
      if (bNotify)
        NotifyAfterValueChange();
    } break;
  }
  return TRUE;
}
CPDF_AAction CPDF_FormField::GetAdditionalAction() const {
  CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "AA");
  return CPDF_AAction(pObj ? pObj->GetDict() : nullptr);
}
Example #10
0
CFX_WideString CPDF_FormField::GetRichTextString() const {
  CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "RV");
  return pObj ? pObj->GetUnicodeText() : L"";
}
Example #11
0
FX_BOOL CPDF_FormField::SetItemSelection(int index,
                                         FX_BOOL bSelected,
                                         FX_BOOL bNotify) {
  ASSERT(GetType() == ComboBox || GetType() == ListBox);
  if (index < 0 || index >= CountOptions())
    return FALSE;

  CFX_WideString opt_value = GetOptionValue(index);
  if (bNotify && !NotifyListOrComboBoxBeforeChange(opt_value))
    return FALSE;

  if (bSelected) {
    if (GetType() == ListBox) {
      SelectOption(index, TRUE);
      if (!(m_Flags & kFormListMultiSelect)) {
        m_pDict->SetStringFor("V", PDF_EncodeText(opt_value));
      } else {
        CPDF_Array* pArray = new CPDF_Array;
        for (int i = 0; i < CountOptions(); i++) {
          if (i == index || IsItemSelected(i)) {
            opt_value = GetOptionValue(i);
            pArray->AddString(PDF_EncodeText(opt_value));
          }
        }
        m_pDict->SetFor("V", pArray);
      }
    } else {
      m_pDict->SetStringFor("V", PDF_EncodeText(opt_value));
      CPDF_Array* pI = new CPDF_Array;
      pI->AddInteger(index);
      m_pDict->SetFor("I", pI);
    }
  } else {
    CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "V");
    if (pValue) {
      if (GetType() == ListBox) {
        SelectOption(index, FALSE);
        if (pValue->IsString()) {
          if (pValue->GetUnicodeText() == opt_value)
            m_pDict->RemoveFor("V");
        } else if (pValue->IsArray()) {
          std::unique_ptr<CPDF_Array, ReleaseDeleter<CPDF_Array>> pArray(
              new CPDF_Array);
          for (int i = 0; i < CountOptions(); i++) {
            if (i != index && IsItemSelected(i)) {
              opt_value = GetOptionValue(i);
              pArray->AddString(PDF_EncodeText(opt_value));
            }
          }
          if (pArray->GetCount() > 0)
            m_pDict->SetFor("V", pArray.release());  // std::move someday
        }
      } else {
        m_pDict->RemoveFor("V");
        m_pDict->RemoveFor("I");
      }
    }
  }
  if (bNotify)
    NotifyListOrComboBoxAfterChange();
  return TRUE;
}
Example #12
0
CFX_ByteString CPDF_FormField::GetDefaultStyle() const {
  CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "DS");
  return pObj ? pObj->GetString() : "";
}
Example #13
0
uint32_t CPDF_FormField::GetFieldFlags() const {
  CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "Ff");
  return pObj ? pObj->GetInteger() : 0;
}
Example #14
0
CFX_WideString CPDF_FormField::GetMappingName() const {
  CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "TM");
  return pObj ? pObj->GetUnicodeText() : L"";
}
Example #15
0
std::unique_ptr<CFDF_Document> CPDF_InterForm::ExportToFDF(
    const CFX_WideStringC& pdf_path,
    const std::vector<CPDF_FormField*>& fields,
    bool bIncludeOrExclude,
    bool bSimpleFileSpec) const {
  std::unique_ptr<CFDF_Document> pDoc = CFDF_Document::CreateNewDoc();
  if (!pDoc)
    return nullptr;

  CPDF_Dictionary* pMainDict = pDoc->GetRoot()->GetDictFor("FDF");
  if (!pdf_path.IsEmpty()) {
    if (bSimpleFileSpec) {
      CFX_WideString wsFilePath = CPDF_FileSpec::EncodeFileName(pdf_path);
      pMainDict->SetNewFor<CPDF_String>(
          "F", CFX_ByteString::FromUnicode(wsFilePath), false);
      pMainDict->SetNewFor<CPDF_String>("UF", PDF_EncodeText(wsFilePath),
                                        false);
    } else {
      CPDF_FileSpec filespec(pDoc->GetByteStringPool());
      filespec.SetFileName(pdf_path);
      pMainDict->SetFor("F", pdfium::WrapUnique(filespec.GetObj()));
    }
  }

  CPDF_Array* pFields = pMainDict->SetNewFor<CPDF_Array>("Fields");
  size_t nCount = m_pFieldTree->m_Root.CountFields();
  for (size_t i = 0; i < nCount; ++i) {
    CPDF_FormField* pField = m_pFieldTree->m_Root.GetFieldAtIndex(i);
    if (!pField || pField->GetType() == CPDF_FormField::PushButton)
      continue;

    uint32_t dwFlags = pField->GetFieldFlags();
    if (dwFlags & 0x04)
      continue;

    if (bIncludeOrExclude == pdfium::ContainsValue(fields, pField)) {
      if ((dwFlags & 0x02) != 0 && pField->m_pDict->GetStringFor("V").IsEmpty())
        continue;

      CFX_WideString fullname = FPDF_GetFullName(pField->GetFieldDict());
      auto pFieldDict =
          pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool());
      pFieldDict->SetNewFor<CPDF_String>("T", fullname);
      if (pField->GetType() == CPDF_FormField::CheckBox ||
          pField->GetType() == CPDF_FormField::RadioButton) {
        CFX_WideString csExport = pField->GetCheckValue(false);
        CFX_ByteString csBExport = PDF_EncodeText(csExport);
        CPDF_Object* pOpt = FPDF_GetFieldAttr(pField->m_pDict, "Opt");
        if (pOpt)
          pFieldDict->SetNewFor<CPDF_String>("V", csBExport, false);
        else
          pFieldDict->SetNewFor<CPDF_Name>("V", csBExport);
      } else {
        CPDF_Object* pV = FPDF_GetFieldAttr(pField->m_pDict, "V");
        if (pV)
          pFieldDict->SetFor("V", pV->CloneDirectObject());
      }
      pFields->Add(std::move(pFieldDict));
    }
  }
  return pDoc;
}
FX_BOOL CPDF_FormField::SetItemSelection(int index,
                                         FX_BOOL bSelected,
                                         FX_BOOL bNotify) {
  ASSERT(GetType() == ComboBox || GetType() == ListBox);
  if (index < 0 || index >= CountOptions())
    return FALSE;

  CFX_WideString opt_value = GetOptionValue(index);
  if (bNotify && !NotifyListOrComboBoxBeforeChange(opt_value))
    return FALSE;

  if (bSelected) {
    if (GetType() == ListBox) {
      SelectOption(index, TRUE);
      if (!(m_Flags & FORMLIST_MULTISELECT)) {
        m_pDict->SetAtString("V", PDF_EncodeText(opt_value));
      } else {
        CPDF_Array* pArray = new CPDF_Array;
        for (int i = 0; i < CountOptions(); i++) {
          if (i == index || IsItemSelected(i)) {
            opt_value = GetOptionValue(i);
            pArray->AddString(PDF_EncodeText(opt_value));
          }
        }
        m_pDict->SetAt("V", pArray);
      }
    } else {
      m_pDict->SetAtString("V", PDF_EncodeText(opt_value));
      CPDF_Array* pI = new CPDF_Array;
      pI->AddInteger(index);
      m_pDict->SetAt("I", pI);
    }
  } else {
    CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "V");
    if (pValue) {
      if (GetType() == ListBox) {
        SelectOption(index, FALSE);
        if (pValue->IsString()) {
          if (pValue->GetUnicodeText() == opt_value)
            m_pDict->RemoveAt("V");
        } else if (pValue->IsArray()) {
          CPDF_Array* pArray = new CPDF_Array;
          for (int i = 0; i < CountOptions(); i++) {
            if (i != index && IsItemSelected(i)) {
              opt_value = GetOptionValue(i);
              pArray->AddString(PDF_EncodeText(opt_value));
            }
          }
          if (pArray->GetCount() < 1)
            pArray->Release();
          else
            m_pDict->SetAt("V", pArray);
        }
      } else {
        m_pDict->RemoveAt("V");
        m_pDict->RemoveAt("I");
      }
    }
  }
  if (bNotify)
    NotifyListOrComboBoxAfterChange();
  return TRUE;
}
DLLEXPORT void STDCALL FPDFPage_InsertClipPath(FPDF_PAGE page,FPDF_CLIPPATH clipPath)
{
	if(!page)
		return;
	CPDF_Page* pPage = (CPDF_Page*)page;
	CPDF_Dictionary* pPageDic = pPage->m_pFormDict;
	CPDF_Object* pContentObj = pPageDic->GetElement("Contents");
	if(!pContentObj)
		pContentObj = pPageDic->GetArray("Contents");
	if(!pContentObj)
		return;

	CFX_ByteTextBuf strClip;
	CPDF_ClipPath* pClipPath = (CPDF_ClipPath*)clipPath;
	FX_DWORD i;
	for (i = 0; i < pClipPath->GetPathCount(); i ++) {
		CPDF_Path path = pClipPath->GetPath(i);
		int iClipType = pClipPath->GetClipType(i);
		if (path.GetPointCount() == 0) {
			// Empty clipping (totally clipped out)
			strClip << "0 0 m W n ";
		} else {
			OutputPath(strClip, path);
			if (iClipType == FXFILL_WINDING)
				strClip << "W n\n";
			else
				strClip << "W* n\n";
		}
	}
	CPDF_Dictionary* pDic = FX_NEW CPDF_Dictionary;
	CPDF_Stream* pStream = FX_NEW CPDF_Stream(NULL,0, pDic);
	pStream->SetData(strClip.GetBuffer(), strClip.GetSize(), FALSE, FALSE);
	CPDF_Document* pDoc = pPage->m_pDocument;
	if(!pDoc)
		return;
	pDoc->AddIndirectObject(pStream);
	
	CPDF_Array* pContentArray = NULL;
	if (pContentObj && pContentObj->GetType() == PDFOBJ_ARRAY)
	{
		pContentArray = (CPDF_Array*)pContentObj;
		CPDF_Reference* pRef = FX_NEW CPDF_Reference(pDoc, pStream->GetObjNum());
		pContentArray->InsertAt(0, pRef);
		
	}
	else if(pContentObj && pContentObj->GetType() == PDFOBJ_REFERENCE)
	{
		CPDF_Reference* pReference = (CPDF_Reference*)pContentObj;
		CPDF_Object* pDirectObj = pReference->GetDirect();
		if(pDirectObj != NULL)
		{
			if(pDirectObj->GetType() == PDFOBJ_ARRAY)
			{
				pContentArray = (CPDF_Array*)pDirectObj;
				CPDF_Reference* pRef = FX_NEW CPDF_Reference(pDoc, pStream->GetObjNum());
				pContentArray->InsertAt(0, pRef);
				
			}
			else if(pDirectObj->GetType() == PDFOBJ_STREAM)
			{
				pContentArray = FX_NEW CPDF_Array();
				pContentArray->AddReference(pDoc,pStream->GetObjNum());
				pContentArray->AddReference(pDoc,pDirectObj->GetObjNum());
				pPageDic->SetAtReference("Contents", pDoc, pDoc->AddIndirectObject(pContentArray));
			}
		}
	}	
}
int CPDF_FormField::GetTopVisibleIndex() const {
  CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "TI");
  return pObj ? pObj->GetInteger() : 0;
}
CPDF_Stream* CPDF_StreamParser::ReadInlineStream(CPDF_Document* pDoc, CPDF_Dictionary* pDict, CPDF_Object* pCSObj, FX_BOOL bDecode)
{
    if (m_Pos == m_Size) {
        return NULL;
    }
    if (PDF_CharType[m_pBuf[m_Pos]] == 'W') {
        m_Pos ++;
    }
    CFX_ByteString Decoder;
    CPDF_Dictionary* pParam = NULL;
    CPDF_Object* pFilter = pDict->GetElementValue(FX_BSTRC("Filter"));
    if (pFilter == NULL) {
    } else if (pFilter->GetType() == PDFOBJ_ARRAY) {
        Decoder = ((CPDF_Array*)pFilter)->GetString(0);
        CPDF_Array* pParams = pDict->GetArray(FX_BSTRC("DecodeParms"));
        if (pParams) {
            pParam = pParams->GetDict(0);
        }
    } else {
        Decoder = pFilter->GetString();
        pParam = pDict->GetDict(FX_BSTRC("DecodeParms"));
    }
    FX_DWORD width = pDict->GetInteger(FX_BSTRC("Width"));
    FX_DWORD height = pDict->GetInteger(FX_BSTRC("Height"));
    FX_DWORD OrigSize = 0;
    if (pCSObj != NULL) {
        FX_DWORD bpc = pDict->GetInteger(FX_BSTRC("BitsPerComponent"));
        FX_DWORD nComponents = 1;
        CPDF_ColorSpace* pCS = pDoc->LoadColorSpace(pCSObj);
        if (pCS == NULL) {
            nComponents = 3;
        } else {
            nComponents = pCS->CountComponents();
            pDoc->GetPageData()->ReleaseColorSpace(pCSObj);
        }
        FX_DWORD pitch = width;
        if (bpc && pitch > INT_MAX / bpc) {
            return NULL;
        }
        pitch *= bpc;
        if (nComponents && pitch > INT_MAX / nComponents) {
            return NULL;
        }
        pitch *= nComponents;
        if (pitch > INT_MAX - 7) {
            return NULL;
        }
        pitch += 7;
        pitch /= 8;
        OrigSize = pitch;
    } else {
        if (width > INT_MAX - 7) {
            return NULL;
        }
        OrigSize = ((width + 7) / 8);
    }
    if (height && OrigSize > INT_MAX / height) {
        return NULL;
    }
    OrigSize *= height;
    uint8_t* pData = NULL;
    FX_DWORD dwStreamSize;
    if (Decoder.IsEmpty()) {
        if (OrigSize > m_Size - m_Pos) {
            OrigSize = m_Size - m_Pos;
        }
        pData = FX_Alloc(uint8_t, OrigSize);
        FXSYS_memcpy(pData, m_pBuf + m_Pos, OrigSize);
        dwStreamSize = OrigSize;
        m_Pos += OrigSize;
    } else {
        FX_DWORD dwDestSize = OrigSize;
        dwStreamSize = PDF_DecodeInlineStream(m_pBuf + m_Pos, m_Size - m_Pos, width, height, Decoder, pParam,
                                              pData, dwDestSize);
        if ((int)dwStreamSize < 0) {
            return NULL;
        }
        if (bDecode) {
            m_Pos += dwStreamSize;
            dwStreamSize = dwDestSize;
            if (pFilter->GetType() == PDFOBJ_ARRAY) {
                ((CPDF_Array*)pFilter)->RemoveAt(0);
                CPDF_Array* pParams = pDict->GetArray(FX_BSTRC("DecodeParms"));
                if (pParams) {
                    pParams->RemoveAt(0);
                }
            } else {
                pDict->RemoveAt(FX_BSTRC("Filter"));
                pDict->RemoveAt(FX_BSTRC("DecodeParms"));
            }
        } else {
            if (pData) {
                FX_Free(pData);
            }
            FX_DWORD dwSavePos = m_Pos;
            m_Pos += dwStreamSize;
            while (1) {
                FX_DWORD dwPrevPos = m_Pos;
                CPDF_StreamParser::SyntaxType type = ParseNextElement();
                if (type == CPDF_StreamParser::EndOfData) {
                    break;
                }
                if (type != CPDF_StreamParser::Keyword) {
                    dwStreamSize += m_Pos - dwPrevPos;
                    continue;
                }
                if (GetWordSize() == 2 && GetWordBuf()[0] == 'E' &&
                        GetWordBuf()[1] == 'I') {
                    m_Pos = dwPrevPos;
                    break;
                }
                dwStreamSize += m_Pos - dwPrevPos;
            }
            m_Pos = dwSavePos;
            pData = FX_Alloc(uint8_t, dwStreamSize);
            FXSYS_memcpy(pData, m_pBuf + m_Pos, dwStreamSize);
            m_Pos += dwStreamSize;
        }
    }
    pDict->SetAtInteger(FX_BSTRC("Length"), (int)dwStreamSize);
    return CPDF_Stream::Create(pData, dwStreamSize, pDict);
}
void CPDFXFA_DocEnvironment::ExportData(CXFA_FFDoc* hDoc,
                                        const CFX_WideString& wsFilePath,
                                        bool bXDP) {
  if (hDoc != m_pContext->GetXFADoc())
    return;

  if (m_pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
      m_pContext->GetDocType() != DOCTYPE_STATIC_XFA) {
    return;
  }

  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
  if (!pFormFillEnv)
    return;

  int fileType = bXDP ? FXFA_SAVEAS_XDP : FXFA_SAVEAS_XML;
  CFX_ByteString bs = wsFilePath.UTF16LE_Encode();
  if (wsFilePath.IsEmpty()) {
    if (!pFormFillEnv->GetFormFillInfo() ||
        !pFormFillEnv->GetFormFillInfo()->m_pJsPlatform) {
      return;
    }

    CFX_WideString filepath = pFormFillEnv->JS_fieldBrowse();
    bs = filepath.UTF16LE_Encode();
  }
  int len = bs.GetLength();
  FPDF_FILEHANDLER* pFileHandler =
      pFormFillEnv->OpenFile(bXDP ? FXFA_SAVEAS_XDP : FXFA_SAVEAS_XML,
                             (FPDF_WIDESTRING)bs.GetBuffer(len), "wb");
  bs.ReleaseBuffer(len);
  if (!pFileHandler)
    return;

  CFX_RetainPtr<IFX_SeekableStream> fileWrite =
      MakeSeekableStream(pFileHandler);
  CFX_ByteString content;
  if (fileType == FXFA_SAVEAS_XML) {
    content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";
    fileWrite->WriteBlock(content.c_str(), fileWrite->GetSize(),
                          content.GetLength());
    m_pContext->GetXFADocView()->GetDoc()->SavePackage(XFA_HASHCODE_Data,
                                                       fileWrite, nullptr);
  } else if (fileType == FXFA_SAVEAS_XDP) {
    if (!m_pContext->GetPDFDoc())
      return;

    CPDF_Dictionary* pRoot = m_pContext->GetPDFDoc()->GetRoot();
    if (!pRoot)
      return;

    CPDF_Dictionary* pAcroForm = pRoot->GetDictFor("AcroForm");
    if (!pAcroForm)
      return;

    CPDF_Array* pArray = ToArray(pAcroForm->GetObjectFor("XFA"));
    if (!pArray)
      return;

    int size = pArray->GetCount();
    for (int i = 1; i < size; i += 2) {
      CPDF_Object* pPDFObj = pArray->GetObjectAt(i);
      CPDF_Object* pPrePDFObj = pArray->GetObjectAt(i - 1);
      if (!pPrePDFObj->IsString())
        continue;
      if (!pPDFObj->IsReference())
        continue;

      CPDF_Stream* pStream = ToStream(pPDFObj->GetDirect());
      if (!pStream)
        continue;
      if (pPrePDFObj->GetString() == "form") {
        m_pContext->GetXFADocView()->GetDoc()->SavePackage(XFA_HASHCODE_Form,
                                                           fileWrite, nullptr);
        continue;
      }
      if (pPrePDFObj->GetString() == "datasets") {
        m_pContext->GetXFADocView()->GetDoc()->SavePackage(
            XFA_HASHCODE_Datasets, fileWrite, nullptr);
        continue;
      }
      if (i == size - 1) {
        CFX_WideString wPath = CFX_WideString::FromUTF16LE(
            reinterpret_cast<const unsigned short*>(bs.c_str()),
            bs.GetLength() / sizeof(unsigned short));
        CFX_ByteString bPath = wPath.UTF8Encode();
        const char* szFormat =
            "\n<pdf href=\"%s\" xmlns=\"http://ns.adobe.com/xdp/pdf/\"/>";
        content.Format(szFormat, bPath.c_str());
        fileWrite->WriteBlock(content.c_str(), fileWrite->GetSize(),
                              content.GetLength());
      }
      std::unique_ptr<CPDF_StreamAcc> pAcc(new CPDF_StreamAcc);
      pAcc->LoadAllData(pStream);
      fileWrite->WriteBlock(pAcc->GetData(), fileWrite->GetSize(),
                            pAcc->GetSize());
    }
  }
  fileWrite->Flush();
}
void CPDF_StreamContentParser::Handle_BeginImage()
{
    FX_FILESIZE savePos = m_pSyntax->GetPos();
    CPDF_Dictionary* pDict = CPDF_Dictionary::Create();
    while (1) {
        CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement();
        if (type == CPDF_StreamParser::Keyword) {
            CFX_ByteString bsKeyword(m_pSyntax->GetWordBuf(), m_pSyntax->GetWordSize());
            if (bsKeyword != FX_BSTRC("ID")) {
                m_pSyntax->SetPos(savePos);
                pDict->Release();
                return;
            }
        }
        if (type != CPDF_StreamParser::Name) {
            break;
        }
        CFX_ByteString key((const FX_CHAR*)m_pSyntax->GetWordBuf() + 1, m_pSyntax->GetWordSize() - 1);
        CPDF_Object* pObj = m_pSyntax->ReadNextObject();
        if (!key.IsEmpty()) {
            pDict->SetAt(key, pObj, m_pDocument);
        } else if (pObj) {
            pObj->Release();
        }
    }
    _PDF_ReplaceAbbr(pDict);
    CPDF_Object* pCSObj = NULL;
    if (pDict->KeyExist(FX_BSTRC("ColorSpace"))) {
        pCSObj = pDict->GetElementValue(FX_BSTRC("ColorSpace"));
        if (pCSObj->GetType() == PDFOBJ_NAME) {
            CFX_ByteString name = pCSObj->GetString();
            if (name != FX_BSTRC("DeviceRGB") && name != FX_BSTRC("DeviceGray") && name != FX_BSTRC("DeviceCMYK")) {
                pCSObj = FindResourceObj(FX_BSTRC("ColorSpace"), name);
                if (pCSObj && !pCSObj->GetObjNum()) {
                    pCSObj = pCSObj->Clone();
                    pDict->SetAt(FX_BSTRC("ColorSpace"), pCSObj, m_pDocument);
                }
            }
        }
    }
    CPDF_Stream* pStream = m_pSyntax->ReadInlineStream(m_pDocument, pDict, pCSObj, m_Options.m_bDecodeInlineImage);
    while (1) {
        CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement();
        if (type == CPDF_StreamParser::EndOfData) {
            break;
        }
        if (type != CPDF_StreamParser::Keyword) {
            continue;
        }
        if (m_pSyntax->GetWordSize() == 2 && m_pSyntax->GetWordBuf()[0] == 'E' &&
                m_pSyntax->GetWordBuf()[1] == 'I') {
            break;
        }
    }
    if (m_Options.m_bTextOnly) {
        if (pStream) {
            pStream->Release();
        } else {
            pDict->Release();
        }
        return;
    }
    pDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Image"));
    CPDF_ImageObject *pImgObj = AddImage(pStream, NULL, TRUE);
    if (!pImgObj) {
        if (pStream) {
            pStream->Release();
        } else {
            pDict->Release();
        }
    }
}
bool CPDFXFA_DocEnvironment::ExportSubmitFile(FPDF_FILEHANDLER* pFileHandler,
                                              int fileType,
                                              FPDF_DWORD encodeType,
                                              FPDF_DWORD flag) {
  if (!m_pContext->GetXFADocView())
    return false;

  CFX_ByteString content;
  CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv();
  if (!pFormFillEnv)
    return false;

  CFX_RetainPtr<IFX_SeekableStream> fileStream =
      MakeSeekableStream(pFileHandler);

  if (fileType == FXFA_SAVEAS_XML) {
    const char kContent[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";
    fileStream->WriteBlock(kContent, 0, strlen(kContent));
    m_pContext->GetXFADoc()->SavePackage(XFA_HASHCODE_Data, fileStream,
                                         nullptr);
    return true;
  }

  if (fileType != FXFA_SAVEAS_XDP)
    return true;

  if (!flag) {
    flag = FXFA_CONFIG | FXFA_TEMPLATE | FXFA_LOCALESET | FXFA_DATASETS |
           FXFA_XMPMETA | FXFA_XFDF | FXFA_FORM;
  }
  if (!m_pContext->GetPDFDoc()) {
    fileStream->Flush();
    return false;
  }

  CPDF_Dictionary* pRoot = m_pContext->GetPDFDoc()->GetRoot();
  if (!pRoot) {
    fileStream->Flush();
    return false;
  }

  CPDF_Dictionary* pAcroForm = pRoot->GetDictFor("AcroForm");
  if (!pAcroForm) {
    fileStream->Flush();
    return false;
  }

  CPDF_Array* pArray = ToArray(pAcroForm->GetObjectFor("XFA"));
  if (!pArray) {
    fileStream->Flush();
    return false;
  }

  int size = pArray->GetCount();
  for (int i = 1; i < size; i += 2) {
    CPDF_Object* pPDFObj = pArray->GetObjectAt(i);
    CPDF_Object* pPrePDFObj = pArray->GetObjectAt(i - 1);
    if (!pPrePDFObj->IsString())
      continue;
    if (!pPDFObj->IsReference())
      continue;

    CPDF_Object* pDirectObj = pPDFObj->GetDirect();
    if (!pDirectObj->IsStream())
      continue;
    if (pPrePDFObj->GetString() == "config" && !(flag & FXFA_CONFIG))
      continue;
    if (pPrePDFObj->GetString() == "template" && !(flag & FXFA_TEMPLATE))
      continue;
    if (pPrePDFObj->GetString() == "localeSet" && !(flag & FXFA_LOCALESET))
      continue;
    if (pPrePDFObj->GetString() == "datasets" && !(flag & FXFA_DATASETS))
      continue;
    if (pPrePDFObj->GetString() == "xmpmeta" && !(flag & FXFA_XMPMETA))
      continue;
    if (pPrePDFObj->GetString() == "xfdf" && !(flag & FXFA_XFDF))
      continue;
    if (pPrePDFObj->GetString() == "form" && !(flag & FXFA_FORM))
      continue;
    if (pPrePDFObj->GetString() == "form") {
      m_pContext->GetXFADoc()->SavePackage(XFA_HASHCODE_Form, fileStream,
                                           nullptr);
    } else if (pPrePDFObj->GetString() == "datasets") {
      m_pContext->GetXFADoc()->SavePackage(XFA_HASHCODE_Datasets, fileStream,
                                           nullptr);
    } else {
      // PDF,creator.
    }
  }
  return true;
}
void CPDF_ContentParser::Continue(IFX_Pause* pPause)
{
    while (m_Status == ToBeContinued) {
        if (m_InternalStage == PAGEPARSE_STAGE_PARSE) {
            if (m_pStreamFilter == NULL) {
                if (m_CurrentOffset == m_nStreams) {
                    m_InternalStage = PAGEPARSE_STAGE_CHECKCLIP;
                    if (m_pType3Char) {
                        m_pType3Char->m_bColored = m_pParser->m_bColored;
                        m_pType3Char->m_Width = FXSYS_round(m_pParser->m_Type3Data[0] * 1000);
                        m_pType3Char->m_BBox.left = FXSYS_round(m_pParser->m_Type3Data[2] * 1000);
                        m_pType3Char->m_BBox.bottom = FXSYS_round(m_pParser->m_Type3Data[3] * 1000);
                        m_pType3Char->m_BBox.right = FXSYS_round(m_pParser->m_Type3Data[4] * 1000);
                        m_pType3Char->m_BBox.top = FXSYS_round(m_pParser->m_Type3Data[5] * 1000);
                        m_pType3Char->m_bPageRequired = m_pParser->m_bResourceMissing;
                    }
                    delete m_pParser;
                    m_pParser = NULL;
                    continue;
                }
                CPDF_Object* pContent = m_pObjects->m_pFormDict->GetElementValue(FX_BSTRC("Contents"));
                if (pContent->GetType() == PDFOBJ_STREAM) {
                    m_pStreamFilter = ((CPDF_Stream*)pContent)->GetStreamFilter();
                } else {
                    CPDF_Stream* pStream = ((CPDF_Array*)pContent)->GetStream(m_CurrentOffset);
                    if (pStream == NULL) {
                        m_CurrentOffset ++;
                        continue;
                    }
                    m_pStreamFilter = pStream->GetStreamFilter();
                }
            }
            FX_DWORD len = m_pStreamFilter->ReadBlock(m_pParser->m_pStreamBuf, STREAM_PARSE_BUFSIZE);
            m_pParser->InputData(m_pParser->m_pStreamBuf, len);
            if (m_pParser->m_bAbort) {
                delete m_pStreamFilter;
                m_pStreamFilter = NULL;
                m_Status = Done;
                delete m_pParser;
                m_pParser = NULL;
                return;
            }
            if (len < STREAM_PARSE_BUFSIZE) {
                m_pParser->Finish();
                m_CurrentOffset ++;
                delete m_pStreamFilter;
                m_pStreamFilter = NULL;
            }
            if (pPause && pPause->NeedToPauseNow()) {
                return;
            }
        }
        if (m_InternalStage == PAGEPARSE_STAGE_CHECKCLIP) {
            FX_POSITION pos = m_pObjects->m_ObjectList.GetHeadPosition();
            while (pos) {
                CPDF_PageObject* pObj = (CPDF_PageObject*)m_pObjects->m_ObjectList.GetNext(pos);
                if (pObj == NULL) {
                    continue;
                }
                if (pObj->m_ClipPath.IsNull()) {
                    continue;
                }
                if (pObj->m_ClipPath.GetPathCount() != 1) {
                    continue;
                }
                if (pObj->m_ClipPath.GetTextCount()) {
                    continue;
                }
                CPDF_Path ClipPath = pObj->m_ClipPath.GetPath(0);
                if (!ClipPath.IsRect() || pObj->m_Type == PDFPAGE_SHADING) {
                    continue;
                }
                CFX_FloatRect old_rect(ClipPath.GetPointX(0), ClipPath.GetPointY(0),
                                       ClipPath.GetPointX(2), ClipPath.GetPointY(2));
                CFX_FloatRect obj_rect(pObj->m_Left, pObj->m_Bottom, pObj->m_Right, pObj->m_Top);
                if (old_rect.Contains(obj_rect)) {
                    pObj->m_ClipPath.SetNull();
                }
            }
            if (m_pObjects->m_ObjectList.GetCount() == 1) {
                CPDF_PageObject* pObj = (CPDF_PageObject*)m_pObjects->m_ObjectList.GetAt(m_pObjects->m_ObjectList.GetHeadPosition());
                if (pObj && pObj->m_Type == PDFPAGE_TEXT) {
                    CPDF_TextObject* pText = (CPDF_TextObject*)pObj;
                }
            }
            m_Status = Done;
            return;
        }
    }
}
Example #24
0
CPDF_FormField* CPDF_InterForm::AddTerminalField(CPDF_Dictionary* pFieldDict) {
  if (!pFieldDict->KeyExist("T"))
    return nullptr;

  CPDF_Dictionary* pDict = pFieldDict;
  CFX_WideString csWName = FPDF_GetFullName(pFieldDict);
  if (csWName.IsEmpty())
    return nullptr;

  CPDF_FormField* pField = nullptr;
  pField = m_pFieldTree->GetField(csWName);
  if (!pField) {
    CPDF_Dictionary* pParent = pFieldDict;
    if (!pFieldDict->KeyExist("T") &&
        pFieldDict->GetStringBy("Subtype") == "Widget") {
      pParent = pFieldDict->GetDictBy("Parent");
      if (!pParent)
        pParent = pFieldDict;
    }

    if (pParent && pParent != pFieldDict && !pParent->KeyExist("FT")) {
      if (pFieldDict->KeyExist("FT")) {
        CPDF_Object* pFTValue = pFieldDict->GetDirectObjectBy("FT");
        if (pFTValue)
          pParent->SetAt("FT", pFTValue->Clone());
      }

      if (pFieldDict->KeyExist("Ff")) {
        CPDF_Object* pFfValue = pFieldDict->GetDirectObjectBy("Ff");
        if (pFfValue)
          pParent->SetAt("Ff", pFfValue->Clone());
      }
    }

    pField = new CPDF_FormField(this, pParent);
    CPDF_Object* pTObj = pDict->GetObjectBy("T");
    if (ToReference(pTObj)) {
      CPDF_Object* pClone = pTObj->CloneDirectObject();
      if (pClone)
        pDict->SetAt("T", pClone);
      else
        pDict->SetAtName("T", "");
    }
    m_pFieldTree->SetField(csWName, pField);
  }

  CPDF_Array* pKids = pFieldDict->GetArrayBy("Kids");
  if (!pKids) {
    if (pFieldDict->GetStringBy("Subtype") == "Widget")
      AddControl(pField, pFieldDict);
  } else {
    for (size_t i = 0; i < pKids->GetCount(); i++) {
      CPDF_Dictionary* pKid = pKids->GetDictAt(i);
      if (!pKid)
        continue;
      if (pKid->GetStringBy("Subtype") != "Widget")
        continue;

      AddControl(pField, pKid);
    }
  }
  return pField;
}
Example #25
0
CPDF_Object* CPDF_Object::CloneInternal(FX_BOOL bDirect, CFX_MapPtrToPtr* visited) const
{
    switch (m_Type) {
        case PDFOBJ_BOOLEAN:
            return new CPDF_Boolean(((CPDF_Boolean*)this)->m_bValue);
        case PDFOBJ_NUMBER:
            return new CPDF_Number(((CPDF_Number*)this)->m_bInteger, &((CPDF_Number*)this)->m_Integer);
        case PDFOBJ_STRING:
            return new CPDF_String(((CPDF_String*)this)->m_String, ((CPDF_String*)this)->IsHex());
        case PDFOBJ_NAME:
            return new CPDF_Name(((CPDF_Name*)this)->m_Name);
        case PDFOBJ_ARRAY: {
                CPDF_Array* pCopy = new CPDF_Array();
                CPDF_Array* pThis = (CPDF_Array*)this;
                int n = pThis->GetCount();
                for (int i = 0; i < n; i ++) {
                    CPDF_Object* value = (CPDF_Object*)pThis->m_Objects.GetAt(i);
                    pCopy->m_Objects.Add(value->CloneInternal(bDirect, visited));
                }
                return pCopy;
            }
        case PDFOBJ_DICTIONARY: {
                CPDF_Dictionary* pCopy = new CPDF_Dictionary();
                CPDF_Dictionary* pThis = (CPDF_Dictionary*)this;
                FX_POSITION pos = pThis->m_Map.GetStartPosition();
                while (pos) {
                    CFX_ByteString key;
                    CPDF_Object* value;
                    pThis->m_Map.GetNextAssoc(pos, key, (void*&)value);
                    pCopy->m_Map.SetAt(key, value->CloneInternal(bDirect, visited));
                }
                return pCopy;
            }
        case PDFOBJ_NULL: {
                return new CPDF_Null;
            }
        case PDFOBJ_STREAM: {
                CPDF_Stream* pThis = (CPDF_Stream*)this;
                CPDF_StreamAcc acc;
                acc.LoadAllData(pThis, TRUE);
                FX_DWORD streamSize = acc.GetSize();
                CPDF_Stream* pObj;
                if (pThis->GetDict())
                    pObj = new CPDF_Stream(acc.DetachData(), streamSize, (CPDF_Dictionary*)((CPDF_Object*)pThis->GetDict())->CloneInternal(bDirect, visited));
                else
                    pObj = new CPDF_Stream(acc.DetachData(), streamSize, NULL);
                return pObj;
            }
        case PDFOBJ_REFERENCE: {
                CPDF_Reference* pRef = (CPDF_Reference*)this;
                FX_DWORD obj_num = pRef->m_RefObjNum;
                if (bDirect && !visited->GetValueAt((void*)(FX_UINTPTR)obj_num)) {
                    visited->SetAt((void*)(FX_UINTPTR)obj_num, (void*)1);
                    CPDF_Object* ret;
                    if (pRef->GetDirect())
                        ret = pRef->GetDirect()->CloneInternal(TRUE, visited);
                    else
                        ret = NULL;
                    return ret;
                } else {
                    return new CPDF_Reference(pRef->m_pObjList, obj_num);
                }
            }
    }
    return NULL;
}
bool CPDF_ImageRenderer::StartRenderDIBSource() {
  if (!m_Loader.m_pBitmap)
    return false;

  m_BitmapAlpha =
      FXSYS_round(255 * m_pImageObject->m_GeneralState.GetFillAlpha());
  m_pDIBSource = m_Loader.m_pBitmap;
  if (m_pRenderStatus->m_Options.m_ColorMode == RENDER_COLOR_ALPHA &&
      !m_Loader.m_pMask) {
    return StartBitmapAlpha();
  }
  if (m_pImageObject->m_GeneralState.GetTR()) {
    if (!m_pImageObject->m_GeneralState.GetTransferFunc()) {
      m_pImageObject->m_GeneralState.SetTransferFunc(
          m_pRenderStatus->GetTransferFunc(
              m_pImageObject->m_GeneralState.GetTR()));
    }
    if (m_pImageObject->m_GeneralState.GetTransferFunc() &&
        !m_pImageObject->m_GeneralState.GetTransferFunc()->m_bIdentity) {
      m_pDIBSource = m_Loader.m_pBitmap =
          m_pImageObject->m_GeneralState.GetTransferFunc()->TranslateImage(
              m_Loader.m_pBitmap, !m_Loader.m_bCached);
      if (m_Loader.m_bCached && m_Loader.m_pMask)
        m_Loader.m_pMask = m_Loader.m_pMask->Clone().release();
      m_Loader.m_bCached = false;
    }
  }
  m_FillArgb = 0;
  m_bPatternColor = false;
  m_pPattern = nullptr;
  if (m_pDIBSource->IsAlphaMask()) {
    const CPDF_Color* pColor = m_pImageObject->m_ColorState.GetFillColor();
    if (pColor && pColor->IsPattern()) {
      m_pPattern = pColor->GetPattern();
      if (m_pPattern)
        m_bPatternColor = true;
    }
    m_FillArgb = m_pRenderStatus->GetFillArgb(m_pImageObject);
  } else if (m_pRenderStatus->m_Options.m_ColorMode == RENDER_COLOR_GRAY) {
    m_pClone = m_pDIBSource->Clone();
    m_pClone->ConvertColorScale(m_pRenderStatus->m_Options.m_BackColor,
                                m_pRenderStatus->m_Options.m_ForeColor);
    m_pDIBSource = m_pClone.get();
  }
  m_Flags = 0;
  if (m_pRenderStatus->m_Options.m_Flags & RENDER_FORCE_DOWNSAMPLE)
    m_Flags |= RENDER_FORCE_DOWNSAMPLE;
  else if (m_pRenderStatus->m_Options.m_Flags & RENDER_FORCE_HALFTONE)
    m_Flags |= RENDER_FORCE_HALFTONE;
  if (m_pRenderStatus->m_pDevice->GetDeviceClass() != FXDC_DISPLAY) {
    CPDF_Object* pFilters =
        m_pImageObject->GetImage()->GetStream()->GetDict()->GetDirectObjectFor(
            "Filter");
    if (pFilters) {
      if (pFilters->IsName()) {
        CFX_ByteString bsDecodeType = pFilters->GetString();
        if (bsDecodeType == "DCTDecode" || bsDecodeType == "JPXDecode")
          m_Flags |= FXRENDER_IMAGE_LOSSY;
      } else if (CPDF_Array* pArray = pFilters->AsArray()) {
        for (size_t i = 0; i < pArray->GetCount(); i++) {
          CFX_ByteString bsDecodeType = pArray->GetStringAt(i);
          if (bsDecodeType == "DCTDecode" || bsDecodeType == "JPXDecode") {
            m_Flags |= FXRENDER_IMAGE_LOSSY;
            break;
          }
        }
      }
    }
  }
  if (m_pRenderStatus->m_Options.m_Flags & RENDER_NOIMAGESMOOTH)
    m_Flags |= FXDIB_NOSMOOTH;
  else if (m_pImageObject->GetImage()->IsInterpol())
    m_Flags |= FXDIB_INTERPOL;
  if (m_Loader.m_pMask)
    return DrawMaskedImage();

  if (m_bPatternColor)
    return DrawPatternImage(m_pObj2Device);

  if (m_BitmapAlpha != 255 || !m_pImageObject->m_GeneralState ||
      !m_pImageObject->m_GeneralState.GetFillOP() ||
      m_pImageObject->m_GeneralState.GetOPMode() != 0 ||
      m_pImageObject->m_GeneralState.GetBlendType() != FXDIB_BLEND_NORMAL ||
      m_pImageObject->m_GeneralState.GetStrokeAlpha() != 1.0f ||
      m_pImageObject->m_GeneralState.GetFillAlpha() != 1.0f) {
    return StartDIBSource();
  }
  CPDF_Document* pDocument = nullptr;
  CPDF_Page* pPage = nullptr;
  if (m_pRenderStatus->m_pContext->GetPageCache()) {
    pPage = m_pRenderStatus->m_pContext->GetPageCache()->GetPage();
    pDocument = pPage->m_pDocument;
  } else {
    pDocument = m_pImageObject->GetImage()->GetDocument();
  }
  CPDF_Dictionary* pPageResources = pPage ? pPage->m_pPageResources : nullptr;
  CPDF_Object* pCSObj =
      m_pImageObject->GetImage()->GetStream()->GetDict()->GetDirectObjectFor(
          "ColorSpace");
  CPDF_ColorSpace* pColorSpace =
      pDocument->LoadColorSpace(pCSObj, pPageResources);
  if (!pColorSpace)
    return StartDIBSource();
  int format = pColorSpace->GetFamily();
  if (format == PDFCS_DEVICECMYK || format == PDFCS_SEPARATION ||
      format == PDFCS_DEVICEN) {
    m_BlendType = FXDIB_BLEND_DARKEN;
  }
  pDocument->GetPageData()->ReleaseColorSpace(pCSObj);
  return StartDIBSource();
}
Example #27
0
void CPDF_Font::LoadPDFEncoding(CPDF_Object* pEncoding,
                                int& iBaseEncoding,
                                std::vector<CFX_ByteString>* pCharNames,
                                bool bEmbedded,
                                bool bTrueType) {
  if (!pEncoding) {
    if (m_BaseFont == "Symbol") {
      iBaseEncoding = bTrueType ? PDFFONT_ENCODING_MS_SYMBOL
                                : PDFFONT_ENCODING_ADOBE_SYMBOL;
    } else if (!bEmbedded && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {
      iBaseEncoding = PDFFONT_ENCODING_WINANSI;
    }
    return;
  }
  if (pEncoding->IsName()) {
    if (iBaseEncoding == PDFFONT_ENCODING_ADOBE_SYMBOL ||
        iBaseEncoding == PDFFONT_ENCODING_ZAPFDINGBATS) {
      return;
    }
    if ((m_Flags & PDFFONT_SYMBOLIC) && m_BaseFont == "Symbol") {
      if (!bTrueType) {
        iBaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL;
      }
      return;
    }
    CFX_ByteString bsEncoding = pEncoding->GetString();
    if (bsEncoding.Compare("MacExpertEncoding") == 0) {
      bsEncoding = "WinAnsiEncoding";
    }
    GetPredefinedEncoding(bsEncoding, &iBaseEncoding);
    return;
  }

  CPDF_Dictionary* pDict = pEncoding->AsDictionary();
  if (!pDict)
    return;

  if (iBaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL &&
      iBaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS) {
    CFX_ByteString bsEncoding = pDict->GetStringFor("BaseEncoding");
    if (bsEncoding.Compare("MacExpertEncoding") == 0 && bTrueType) {
      bsEncoding = "WinAnsiEncoding";
    }
    GetPredefinedEncoding(bsEncoding, &iBaseEncoding);
  }
  if ((!bEmbedded || bTrueType) && iBaseEncoding == PDFFONT_ENCODING_BUILTIN)
    iBaseEncoding = PDFFONT_ENCODING_STANDARD;

  CPDF_Array* pDiffs = pDict->GetArrayFor("Differences");
  if (!pDiffs)
    return;

  pCharNames->resize(256);
  uint32_t cur_code = 0;
  for (uint32_t i = 0; i < pDiffs->GetCount(); i++) {
    CPDF_Object* pElement = pDiffs->GetDirectObjectAt(i);
    if (!pElement)
      continue;

    if (CPDF_Name* pName = pElement->AsName()) {
      if (cur_code < 256)
        (*pCharNames)[cur_code] = pName->GetString();
      cur_code++;
    } else {
      cur_code = pElement->GetInteger();
    }
  }
}
Example #28
0
CPDF_FormField* CPDF_InterForm::AddTerminalField(CPDF_Dictionary* pFieldDict) {
  if (!pFieldDict->KeyExist("FT")) {
    // Key "FT" is required for terminal fields, it is also inheritable.
    CPDF_Dictionary* pParentDict = pFieldDict->GetDictFor("Parent");
    if (!pParentDict || !pParentDict->KeyExist("FT"))
      return nullptr;
  }

  CPDF_Dictionary* pDict = pFieldDict;
  CFX_WideString csWName = FPDF_GetFullName(pFieldDict);
  if (csWName.IsEmpty())
    return nullptr;

  CPDF_FormField* pField = nullptr;
  pField = m_pFieldTree->GetField(csWName);
  if (!pField) {
    CPDF_Dictionary* pParent = pFieldDict;
    if (!pFieldDict->KeyExist("T") &&
        pFieldDict->GetStringFor("Subtype") == "Widget") {
      pParent = pFieldDict->GetDictFor("Parent");
      if (!pParent)
        pParent = pFieldDict;
    }

    if (pParent && pParent != pFieldDict && !pParent->KeyExist("FT")) {
      if (pFieldDict->KeyExist("FT")) {
        CPDF_Object* pFTValue = pFieldDict->GetDirectObjectFor("FT");
        if (pFTValue)
          pParent->SetFor("FT", pFTValue->Clone());
      }

      if (pFieldDict->KeyExist("Ff")) {
        CPDF_Object* pFfValue = pFieldDict->GetDirectObjectFor("Ff");
        if (pFfValue)
          pParent->SetFor("Ff", pFfValue->Clone());
      }
    }

    pField = new CPDF_FormField(this, pParent);
    CPDF_Object* pTObj = pDict->GetObjectFor("T");
    if (ToReference(pTObj)) {
      std::unique_ptr<CPDF_Object> pClone = pTObj->CloneDirectObject();
      if (pClone)
        pDict->SetFor("T", std::move(pClone));
      else
        pDict->SetNewFor<CPDF_Name>("T", "");
    }
    m_pFieldTree->SetField(csWName, pField);
  }

  CPDF_Array* pKids = pFieldDict->GetArrayFor("Kids");
  if (pKids) {
    for (size_t i = 0; i < pKids->GetCount(); i++) {
      CPDF_Dictionary* pKid = pKids->GetDictAt(i);
      if (!pKid)
        continue;
      if (pKid->GetStringFor("Subtype") != "Widget")
        continue;

      AddControl(pField, pKid);
    }
  } else {
    if (pFieldDict->GetStringFor("Subtype") == "Widget")
      AddControl(pField, pFieldDict);
  }
  return pField;
}
Example #29
0
DLLEXPORT FPDF_BOOL STDCALL FPDFPage_TransFormWithClip(FPDF_PAGE page,
                                                       FS_MATRIX* matrix,
                                                       FS_RECTF* clipRect) {
  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
  if (!pPage)
    return FALSE;

  CFX_ByteTextBuf textBuf;
  textBuf << "q ";
  CFX_FloatRect rect(clipRect->left, clipRect->bottom, clipRect->right,
                     clipRect->top);
  rect.Normalize();
  CFX_ByteString bsClipping;
  bsClipping.Format("%f %f %f %f re W* n ", rect.left, rect.bottom,
                    rect.Width(), rect.Height());
  textBuf << bsClipping;

  CFX_ByteString bsMatix;
  bsMatix.Format("%f %f %f %f %f %f cm ", matrix->a, matrix->b, matrix->c,
                 matrix->d, matrix->e, matrix->f);
  textBuf << bsMatix;

  CPDF_Dictionary* pPageDic = pPage->m_pFormDict;
  CPDF_Object* pContentObj =
      pPageDic ? pPageDic->GetElement("Contents") : nullptr;
  if (!pContentObj)
    pContentObj = pPageDic ? pPageDic->GetArrayBy("Contents") : nullptr;
  if (!pContentObj)
    return FALSE;

  CPDF_Dictionary* pDic = new CPDF_Dictionary;
  CPDF_Stream* pStream = new CPDF_Stream(nullptr, 0, pDic);
  pStream->SetData(textBuf.GetBuffer(), textBuf.GetSize(), FALSE, FALSE);
  CPDF_Document* pDoc = pPage->m_pDocument;
  if (!pDoc)
    return FALSE;
  pDoc->AddIndirectObject(pStream);

  pDic = new CPDF_Dictionary;
  CPDF_Stream* pEndStream = new CPDF_Stream(nullptr, 0, pDic);
  pEndStream->SetData((const uint8_t*)" Q", 2, FALSE, FALSE);
  pDoc->AddIndirectObject(pEndStream);

  CPDF_Array* pContentArray = nullptr;
  if (CPDF_Array* pArray = ToArray(pContentObj)) {
    pContentArray = pArray;
    CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum());
    pContentArray->InsertAt(0, pRef);
    pContentArray->AddReference(pDoc, pEndStream);
  } else if (CPDF_Reference* pReference = ToReference(pContentObj)) {
    CPDF_Object* pDirectObj = pReference->GetDirect();
    if (pDirectObj) {
      if (CPDF_Array* pArray = pDirectObj->AsArray()) {
        pContentArray = pArray;
        CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum());
        pContentArray->InsertAt(0, pRef);
        pContentArray->AddReference(pDoc, pEndStream);
      } else if (pDirectObj->IsStream()) {
        pContentArray = new CPDF_Array();
        pContentArray->AddReference(pDoc, pStream->GetObjNum());
        pContentArray->AddReference(pDoc, pDirectObj->GetObjNum());
        pContentArray->AddReference(pDoc, pEndStream);
        pPageDic->SetAtReference("Contents", pDoc,
                                 pDoc->AddIndirectObject(pContentArray));
      }
    }
  }

  // Need to transform the patterns as well.
  CPDF_Dictionary* pRes = pPageDic->GetDictBy("Resources");
  if (pRes) {
    CPDF_Dictionary* pPattenDict = pRes->GetDictBy("Pattern");
    if (pPattenDict) {
      for (const auto& it : *pPattenDict) {
        CPDF_Object* pObj = it.second;
        if (pObj->IsReference())
          pObj = pObj->GetDirect();

        CPDF_Dictionary* pDict = nullptr;
        if (pObj->IsDictionary())
          pDict = pObj->AsDictionary();
        else if (CPDF_Stream* pStream = pObj->AsStream())
          pDict = pStream->GetDict();
        else
          continue;

        CFX_Matrix m = pDict->GetMatrixBy("Matrix");
        CFX_Matrix t = *(CFX_Matrix*)matrix;
        m.Concat(t);
        pDict->SetAtMatrix("Matrix", m);
      }
    }
  }

  return TRUE;
}
CPDF_Object* CPDF_Object::CloneInternal(FX_BOOL bDirect,
                                        std::set<FX_DWORD>* visited) const {
  switch (m_Type) {
    case PDFOBJ_BOOLEAN:
      return new CPDF_Boolean(AsBoolean()->m_bValue);
    case PDFOBJ_NUMBER: {
      const CPDF_Number* pThis = AsNumber();
      return new CPDF_Number(pThis->m_bInteger ? pThis->m_Integer
                                               : pThis->m_Float);
    }
    case PDFOBJ_STRING: {
      const CPDF_String* pString = AsString();
      return new CPDF_String(pString->m_String, pString->IsHex());
    }
    case PDFOBJ_NAME:
      return new CPDF_Name(AsName()->m_Name);
    case PDFOBJ_ARRAY: {
      CPDF_Array* pCopy = new CPDF_Array();
      const CPDF_Array* pThis = AsArray();
      int n = pThis->GetCount();
      for (int i = 0; i < n; i++) {
        CPDF_Object* value = pThis->m_Objects.GetAt(i);
        pCopy->m_Objects.Add(value->CloneInternal(bDirect, visited));
      }
      return pCopy;
    }
    case PDFOBJ_DICTIONARY: {
      CPDF_Dictionary* pCopy = new CPDF_Dictionary();
      const CPDF_Dictionary* pThis = AsDictionary();
      for (const auto& it : *pThis) {
        pCopy->m_Map.insert(std::make_pair(
            it.first, it.second->CloneInternal(bDirect, visited)));
      }
      return pCopy;
    }
    case PDFOBJ_NULL: {
      return new CPDF_Null;
    }
    case PDFOBJ_STREAM: {
      const CPDF_Stream* pThis = AsStream();
      CPDF_StreamAcc acc;
      acc.LoadAllData(pThis, TRUE);
      FX_DWORD streamSize = acc.GetSize();
      CPDF_Dictionary* pDict = pThis->GetDict();
      if (pDict) {
        pDict = ToDictionary(pDict->CloneInternal(bDirect, visited));
      }
      return new CPDF_Stream(acc.DetachData(), streamSize, pDict);
    }
    case PDFOBJ_REFERENCE: {
      const CPDF_Reference* pRef = AsReference();
      FX_DWORD obj_num = pRef->GetRefObjNum();
      if (bDirect && !pdfium::ContainsKey(*visited, obj_num)) {
        visited->insert(obj_num);
        auto* pDirect = pRef->GetDirect();
        return pDirect ? pDirect->CloneInternal(TRUE, visited) : nullptr;
      }
      return new CPDF_Reference(pRef->m_pObjList, obj_num);
    }
  }
  return NULL;
}