void CPDF_FormControl::DrawControl(CFX_RenderDevice* pDevice, CFX_Matrix* pMatrix, CPDF_Page* pPage, CPDF_Annot::AppearanceMode mode, const CPDF_RenderOptions* pOptions) { if (m_pWidgetDict->GetIntegerBy("F") & ANNOTFLAG_HIDDEN) return; CPDF_Stream* pStream = FPDFDOC_GetAnnotAP(m_pWidgetDict, mode); if (!pStream) return; CFX_FloatRect form_bbox = pStream->GetDict()->GetRectBy("BBox"); CFX_Matrix form_matrix = pStream->GetDict()->GetMatrixBy("Matrix"); form_matrix.TransformRect(form_bbox); CFX_FloatRect arect = m_pWidgetDict->GetRectBy("Rect"); CFX_Matrix matrix; matrix.MatchRect(arect, form_bbox); matrix.Concat(*pMatrix); CPDF_Form form(m_pField->m_pForm->m_pDocument, m_pField->m_pForm->m_pFormDict->GetDictBy("DR"), pStream); form.ParseContent(nullptr, nullptr, nullptr); CPDF_RenderContext context(pPage); context.AppendLayer(&form, &matrix); context.Render(pDevice, pOptions, nullptr); }
CPDF_Stream* CPDF_Stream::Clone(FX_BOOL bDirect, FPDF_LPFCloneStreamCallback lpfCallback, FX_LPVOID pUserData) const { CPDF_Dictionary *pCloneDict = (CPDF_Dictionary*)m_pDict->Clone(bDirect); IFX_FileStream *pFS = NULL; if (lpfCallback) { pFS = lpfCallback((CPDF_Stream*)this, pUserData); } if (!pFS) { CPDF_StreamAcc acc; acc.LoadAllData(this, TRUE); FX_DWORD streamSize = acc.GetSize(); return new CPDF_Stream(acc.DetachData(), streamSize, pCloneDict); } CPDF_Stream* pObj = new CPDF_Stream(NULL, 0, NULL); CPDF_StreamFilter *pSF = GetStreamFilter(TRUE); if (pSF) { FX_LPBYTE pBuf = FX_Alloc(FX_BYTE, 4096); FX_DWORD dwRead; do { dwRead = pSF->ReadBlock(pBuf, 4096); if (dwRead) { pFS->WriteBlock(pBuf, dwRead); } } while (dwRead == 4096); pFS->Flush(); FX_Free(pBuf); delete pSF; } pObj->InitStream((IFX_FileRead*)pFS, pCloneDict); return pObj; }
void CPDF_FormControl::DrawControl(CFX_RenderDevice* pDevice, CFX_AffineMatrix* pMatrix, CPDF_Page* pPage, CPDF_Annot::AppearanceMode mode, const CPDF_RenderOptions* pOptions) { if (m_pWidgetDict->GetInteger("F") & ANNOTFLAG_HIDDEN) { return; } CPDF_Stream* pStream = FPDFDOC_GetAnnotAP(m_pWidgetDict, mode); if (pStream == NULL) { return; } CFX_FloatRect form_bbox = pStream->GetDict()->GetRect("BBox"); CFX_AffineMatrix form_matrix = pStream->GetDict()->GetMatrix("Matrix"); form_matrix.TransformRect(form_bbox); CFX_FloatRect arect = m_pWidgetDict->GetRect("Rect"); CFX_AffineMatrix matrix; matrix.MatchRect(arect, form_bbox); matrix.Concat(*pMatrix); CPDF_Form form(m_pField->m_pForm->m_pDocument, m_pField->m_pForm->m_pFormDict->GetDict("DR"), pStream); form.ParseContent(NULL, NULL, NULL, NULL); CPDF_RenderContext context; context.Create(pPage); context.DrawObjectList(pDevice, &form, &matrix, pOptions); }
void CBA_FontMap::AddFontToAnnotDict(CPDF_Font* pFont, const CFX_ByteString& sAlias) { if (!pFont) return; ASSERT(m_pAnnotDict != NULL); ASSERT(m_pDocument != NULL); CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDict("AP"); if (pAPDict == NULL) { pAPDict = new CPDF_Dictionary; m_pAnnotDict->SetAt("AP", pAPDict); } //to avoid checkbox and radiobutton CPDF_Object* pObject = pAPDict->GetElement(m_sAPType); if (pObject && pObject->GetType() == PDFOBJ_DICTIONARY) return; CPDF_Stream* pStream = pAPDict->GetStream(m_sAPType); if (pStream == NULL) { pStream = new CPDF_Stream(NULL, 0, NULL); FX_INT32 objnum = m_pDocument->AddIndirectObject(pStream); pAPDict->SetAtReference(m_sAPType, m_pDocument, objnum); } CPDF_Dictionary * pStreamDict = pStream->GetDict(); if (!pStreamDict) { pStreamDict = new CPDF_Dictionary; pStream->InitStream(NULL, 0, pStreamDict); } if (pStreamDict) { CPDF_Dictionary* pStreamResList = pStreamDict->GetDict("Resources"); if (!pStreamResList) { pStreamResList = new CPDF_Dictionary(); pStreamDict->SetAt("Resources", pStreamResList); } if (pStreamResList) { CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDict("Font"); if (!pStreamResFontList) { pStreamResFontList = new CPDF_Dictionary; FX_INT32 objnum = m_pDocument->AddIndirectObject(pStreamResFontList); pStreamResList->SetAtReference("Font", m_pDocument, objnum); } if (!pStreamResFontList->KeyExist(sAlias)) pStreamResFontList->SetAtReference(sAlias, m_pDocument, pFont->GetFontDict()); } } }
FX_BOOL CPDF_SampledFunc::v_Init(CPDF_Object* pObj) { if (pObj->GetType() != PDFOBJ_STREAM) { return FALSE; } CPDF_Stream* pStream = (CPDF_Stream*)pObj; CPDF_Dictionary* pDict = pStream->GetDict(); CPDF_Array* pSize = pDict->GetArray(FX_BSTRC("Size")); CPDF_Array* pEncode = pDict->GetArray(FX_BSTRC("Encode")); CPDF_Array* pDecode = pDict->GetArray(FX_BSTRC("Decode")); m_nBitsPerSample = pDict->GetInteger(FX_BSTRC("BitsPerSample")); if (m_nBitsPerSample > 32) { return FALSE; } m_SampleMax = 0xffffffff >> (32 - m_nBitsPerSample); m_pSampleStream = new CPDF_StreamAcc; m_pSampleStream->LoadAllData(pStream, FALSE); m_pEncodeInfo = FX_Alloc(SampleEncodeInfo, m_nInputs); FX_SAFE_DWORD nTotalSampleBits = 1; for (int i = 0; i < m_nInputs; i++) { m_pEncodeInfo[i].sizes = pSize ? pSize->GetInteger(i) : 0; if (!pSize && i == 0) { m_pEncodeInfo[i].sizes = pDict->GetInteger(FX_BSTRC("Size")); } nTotalSampleBits *= m_pEncodeInfo[i].sizes; if (pEncode) { m_pEncodeInfo[i].encode_min = pEncode->GetFloat(i * 2); m_pEncodeInfo[i].encode_max = pEncode->GetFloat(i * 2 + 1); } else { m_pEncodeInfo[i].encode_min = 0; if (m_pEncodeInfo[i].sizes == 1) { m_pEncodeInfo[i].encode_max = 1; } else { m_pEncodeInfo[i].encode_max = (FX_FLOAT)m_pEncodeInfo[i].sizes - 1; } } } nTotalSampleBits *= m_nBitsPerSample; nTotalSampleBits *= m_nOutputs; FX_SAFE_DWORD nTotalSampleBytes = nTotalSampleBits; nTotalSampleBytes += 7; nTotalSampleBytes /= 8; if (!nTotalSampleBytes.IsValid() || nTotalSampleBytes.ValueOrDie() == 0 || nTotalSampleBytes.ValueOrDie() > m_pSampleStream->GetSize()) { return FALSE; } m_pDecodeInfo = FX_Alloc(SampleDecodeInfo, m_nOutputs); for (int i = 0; i < m_nOutputs; i++) { if (pDecode) { m_pDecodeInfo[i].decode_min = pDecode->GetFloat(2 * i); m_pDecodeInfo[i].decode_max = pDecode->GetFloat(2 * i + 1); } else { m_pDecodeInfo[i].decode_min = m_pRanges[i * 2]; m_pDecodeInfo[i].decode_max = m_pRanges[i * 2 + 1]; } } return TRUE; }
FX_BOOL CPDF_PageOrganizer::UpdateReference(CPDF_Object* pObj, CPDF_Document* pDoc, ObjectNumberMap* pObjNumberMap) { switch (pObj->GetType()) { case CPDF_Object::REFERENCE: { CPDF_Reference* pReference = pObj->AsReference(); uint32_t newobjnum = GetNewObjId(pDoc, pObjNumberMap, pReference); if (newobjnum == 0) return FALSE; pReference->SetRef(pDoc, newobjnum); break; } case CPDF_Object::DICTIONARY: { CPDF_Dictionary* pDict = pObj->AsDictionary(); auto it = pDict->begin(); while (it != pDict->end()) { const CFX_ByteString& key = it->first; CPDF_Object* pNextObj = it->second; ++it; if (key == "Parent" || key == "Prev" || key == "First") continue; if (!pNextObj) return FALSE; if (!UpdateReference(pNextObj, pDoc, pObjNumberMap)) pDict->RemoveFor(key); } break; } case CPDF_Object::ARRAY: { CPDF_Array* pArray = pObj->AsArray(); for (size_t i = 0; i < pArray->GetCount(); ++i) { CPDF_Object* pNextObj = pArray->GetObjectAt(i); if (!pNextObj) return FALSE; if (!UpdateReference(pNextObj, pDoc, pObjNumberMap)) return FALSE; } break; } case CPDF_Object::STREAM: { CPDF_Stream* pStream = pObj->AsStream(); CPDF_Dictionary* pDict = pStream->GetDict(); if (pDict) { if (!UpdateReference(pDict, pDoc, pObjNumberMap)) return FALSE; } else { return FALSE; } break; } default: break; } return TRUE; }
void CPDFSDK_BAAnnot::WriteAppearance(const CFX_ByteString& sAPType, const CPDF_Rect& rcBBox, const CFX_Matrix& matrix, const CFX_ByteString& sContents, const CFX_ByteString& sAPState) { CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictBy("AP"); if (!pAPDict) { pAPDict = new CPDF_Dictionary; m_pAnnot->GetAnnotDict()->SetAt("AP", pAPDict); } CPDF_Stream* pStream = nullptr; CPDF_Dictionary* pParentDict = nullptr; if (sAPState.IsEmpty()) { pParentDict = pAPDict; pStream = pAPDict->GetStreamBy(sAPType); } else { CPDF_Dictionary* pAPTypeDict = pAPDict->GetDictBy(sAPType); if (!pAPTypeDict) { pAPTypeDict = new CPDF_Dictionary; pAPDict->SetAt(sAPType, pAPTypeDict); } pParentDict = pAPTypeDict; pStream = pAPTypeDict->GetStreamBy(sAPState); } if (!pStream) { pStream = new CPDF_Stream(nullptr, 0, nullptr); CPDF_Document* pDoc = m_pPageView->GetPDFDocument(); int32_t objnum = pDoc->AddIndirectObject(pStream); pParentDict->SetAtReference(sAPType, pDoc, objnum); } CPDF_Dictionary* pStreamDict = pStream->GetDict(); if (!pStreamDict) { pStreamDict = new CPDF_Dictionary; pStreamDict->SetAtName("Type", "XObject"); pStreamDict->SetAtName("Subtype", "Form"); pStreamDict->SetAtInteger("FormType", 1); pStream->InitStream(nullptr, 0, pStreamDict); } if (pStreamDict) { pStreamDict->SetAtMatrix("Matrix", matrix); pStreamDict->SetAtRect("BBox", rcBBox); } pStream->SetData((uint8_t*)sContents.c_str(), sContents.GetLength(), FALSE, FALSE); }
FX_BOOL CPDF_SampledFunc::v_Init(CPDF_Object* pObj) { CPDF_Stream* pStream = pObj->AsStream(); if (!pStream) return false; CPDF_Dictionary* pDict = pStream->GetDict(); CPDF_Array* pSize = pDict->GetArrayBy("Size"); CPDF_Array* pEncode = pDict->GetArrayBy("Encode"); CPDF_Array* pDecode = pDict->GetArrayBy("Decode"); m_nBitsPerSample = pDict->GetIntegerBy("BitsPerSample"); if (!IsValidBitsPerSample(m_nBitsPerSample)) return FALSE; m_SampleMax = 0xffffffff >> (32 - m_nBitsPerSample); m_pSampleStream.reset(new CPDF_StreamAcc); m_pSampleStream->LoadAllData(pStream, FALSE); FX_SAFE_UINT32 nTotalSampleBits = 1; m_EncodeInfo.resize(m_nInputs); for (uint32_t i = 0; i < m_nInputs; i++) { m_EncodeInfo[i].sizes = pSize ? pSize->GetIntegerAt(i) : 0; if (!pSize && i == 0) m_EncodeInfo[i].sizes = pDict->GetIntegerBy("Size"); nTotalSampleBits *= m_EncodeInfo[i].sizes; if (pEncode) { m_EncodeInfo[i].encode_min = pEncode->GetFloatAt(i * 2); m_EncodeInfo[i].encode_max = pEncode->GetFloatAt(i * 2 + 1); } else { m_EncodeInfo[i].encode_min = 0; m_EncodeInfo[i].encode_max = m_EncodeInfo[i].sizes == 1 ? 1 : (FX_FLOAT)m_EncodeInfo[i].sizes - 1; } } nTotalSampleBits *= m_nBitsPerSample; nTotalSampleBits *= m_nOutputs; FX_SAFE_UINT32 nTotalSampleBytes = nTotalSampleBits; nTotalSampleBytes += 7; nTotalSampleBytes /= 8; if (!nTotalSampleBytes.IsValid() || nTotalSampleBytes.ValueOrDie() == 0 || nTotalSampleBytes.ValueOrDie() > m_pSampleStream->GetSize()) { return FALSE; } m_DecodeInfo.resize(m_nOutputs); for (uint32_t i = 0; i < m_nOutputs; i++) { if (pDecode) { m_DecodeInfo[i].decode_min = pDecode->GetFloatAt(2 * i); m_DecodeInfo[i].decode_max = pDecode->GetFloatAt(2 * i + 1); } else { m_DecodeInfo[i].decode_min = m_pRanges[i * 2]; m_DecodeInfo[i].decode_max = m_pRanges[i * 2 + 1]; } } return TRUE; }
FX_BOOL CPDF_Document::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) const { auto it = m_IndirectObjs.find(objnum); if (it != m_IndirectObjs.end()) { CPDF_Stream* pStream = it->second->AsStream(); bForm = pStream && pStream->GetDict()->GetString("Subtype") == "Form"; return TRUE; } if (!m_pParser) { bForm = FALSE; return TRUE; } return m_pParser->IsFormStream(objnum, bForm); }
void CBA_FontMap::AddFontToAnnotDict(CPDF_Font* pFont, const CFX_ByteString& sAlias) { if (!pFont) return; CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDictBy("AP"); if (!pAPDict) { pAPDict = new CPDF_Dictionary; m_pAnnotDict->SetAt("AP", pAPDict); } // to avoid checkbox and radiobutton CPDF_Object* pObject = pAPDict->GetObjectBy(m_sAPType); if (ToDictionary(pObject)) return; CPDF_Stream* pStream = pAPDict->GetStreamBy(m_sAPType); if (!pStream) { pStream = new CPDF_Stream(nullptr, 0, nullptr); int32_t objnum = m_pDocument->AddIndirectObject(pStream); pAPDict->SetAtReference(m_sAPType, m_pDocument, objnum); } CPDF_Dictionary* pStreamDict = pStream->GetDict(); if (!pStreamDict) { pStreamDict = new CPDF_Dictionary; pStream->InitStream(nullptr, 0, pStreamDict); } if (pStreamDict) { CPDF_Dictionary* pStreamResList = pStreamDict->GetDictBy("Resources"); if (!pStreamResList) { pStreamResList = new CPDF_Dictionary(); pStreamDict->SetAt("Resources", pStreamResList); } if (pStreamResList) { CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDictBy("Font"); if (!pStreamResFontList) { pStreamResFontList = new CPDF_Dictionary; int32_t objnum = m_pDocument->AddIndirectObject(pStreamResFontList); pStreamResList->SetAtReference("Font", m_pDocument, objnum); } if (!pStreamResFontList->KeyExist(sAlias)) pStreamResFontList->SetAtReference(sAlias, m_pDocument, pFont->GetFontDict()); } } }
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; if (!m_pObjectList->m_bHasImageMask) m_pObjectList->m_bHasImageMask = m_pLastImage->IsMask(); } else if (type == "Form") { AddForm(pXObject); } else { return; } }
void CPDF_PageContentGenerator::ProcessImage(CFX_ByteTextBuf& buf, CPDF_ImageObject* pImageObj) { if ((pImageObj->m_Matrix.a == 0 && pImageObj->m_Matrix.b == 0) || (pImageObj->m_Matrix.c == 0 && pImageObj->m_Matrix.d == 0)) { return; } buf << "q " << pImageObj->m_Matrix << " cm "; CPDF_Image* pImage = pImageObj->GetImage(); if (!pImage->IsInline()) { CPDF_Stream* pStream = pImage->GetStream(); uint32_t dwSavedObjNum = pStream->GetObjNum(); CFX_ByteString name = RealizeResource(pStream, "XObject"); if (dwSavedObjNum == 0) { pImageObj->SetUnownedImage(m_pDocument->GetPageData()->GetImage(pStream)); } buf << "/" << PDF_NameEncode(name) << " Do Q\n"; } }
FPDF_EXPORT void FPDF_CALLCONV FPDFPage_InsertClipPath(FPDF_PAGE page, FPDF_CLIPPATH clipPath) { CPDF_Page* pPage = CPDFPageFromFPDFPage(page); if (!pPage) return; CPDF_Dictionary* pPageDict = pPage->GetDict(); CPDF_Object* pContentObj = GetPageContent(pPageDict); if (!pContentObj) return; std::ostringstream strClip; CPDF_ClipPath* pClipPath = CPDFClipPathFromFPDFClipPath(clipPath); for (size_t i = 0; i < pClipPath->GetPathCount(); ++i) { CPDF_Path path = pClipPath->GetPath(i); if (path.GetPoints().empty()) { // Empty clipping (totally clipped out) strClip << "0 0 m W n "; } else { OutputPath(strClip, path); if (pClipPath->GetClipType(i) == FXFILL_WINDING) strClip << "W n\n"; else strClip << "W* n\n"; } } CPDF_Document* pDoc = pPage->GetDocument(); if (!pDoc) return; CPDF_Stream* pStream = pDoc->NewIndirect<CPDF_Stream>(nullptr, 0, pDoc->New<CPDF_Dictionary>()); pStream->SetDataFromStringstream(&strClip); if (CPDF_Array* pArray = ToArray(pContentObj)) { pArray->InsertAt(0, pStream->MakeReference(pDoc)); } else if (pContentObj->IsStream() && !pContentObj->IsInline()) { CPDF_Array* pContentArray = pDoc->NewIndirect<CPDF_Array>(); pContentArray->Add(pStream->MakeReference(pDoc)); pContentArray->Add(pContentObj->MakeReference(pDoc)); pPageDict->SetFor(pdfium::page_object::kContents, pContentArray->MakeReference(pDoc)); } }
void CPDF_PageContentGenerate::ProcessForm(CFX_ByteTextBuf& buf, const uint8_t* data, FX_DWORD size, CFX_Matrix& matrix) { if (!data || !size) { return; } CPDF_Stream* pStream = new CPDF_Stream(NULL, 0, NULL); CPDF_Dictionary* pFormDict = CPDF_Dictionary::Create(); pFormDict->SetAtName("Type", "XObject"); pFormDict->SetAtName("Subtype", "Form"); CFX_FloatRect bbox = m_pPage->GetPageBBox(); matrix.TransformRect(bbox); pFormDict->SetAtRect("BBox", bbox); pStream->InitStream((uint8_t*)data, size, pFormDict); buf << "q " << matrix << " cm "; CFX_ByteString name = RealizeResource(pStream, "XObject"); buf << "/" << PDF_NameEncode(name) << " Do Q\n"; }
static CPDF_Stream* GetFormStream(CPDF_Document* pDoc, CPDF_Object* pResObj) { if (pResObj->GetType() != PDFOBJ_REFERENCE) { return NULL; } CPDF_Reference* pRef = (CPDF_Reference*)pResObj; FX_BOOL bForm; if (pDoc->IsFormStream(pRef->GetRefObjNum(), bForm) && !bForm) { return NULL; } pResObj = pRef->GetDirect(); if (pResObj->GetType() != PDFOBJ_STREAM) { return NULL; } CPDF_Stream* pXObject = (CPDF_Stream*)pResObj; if (pXObject->GetDict()->GetString(FX_BSTRC("Subtype")) != FX_BSTRC("Form")) { return NULL; } return pXObject; }
void CPDF_PageContentGenerate::GenerateContent() { CFX_ByteTextBuf buf; CPDF_Dictionary* pPageDict = m_pPage->m_pFormDict; for (int i = 0; i < m_pageObjects.GetSize(); ++i) { CPDF_PageObject* pPageObj = (CPDF_PageObject*)m_pageObjects[i]; if (!pPageObj || pPageObj->m_Type != PDFPAGE_IMAGE) { continue; } ProcessImage(buf, (CPDF_ImageObject*)pPageObj); } CPDF_Object* pContent = pPageDict ? pPageDict->GetElementValue("Contents") : NULL; if (pContent != NULL) { pPageDict->RemoveAt("Contents"); } CPDF_Stream* pStream = new CPDF_Stream(NULL, 0, NULL); pStream->SetData(buf.GetBuffer(), buf.GetLength(), FALSE, FALSE); m_pDocument->AddIndirectObject(pStream); pPageDict->SetAtReference("Contents", m_pDocument, pStream->GetObjNum()); }
void CPDF_PageContentGenerator::GenerateContent() { CFX_ByteTextBuf buf; CPDF_Dictionary* pPageDict = m_pPage->m_pFormDict; for (int i = 0; i < m_pageObjects.GetSize(); ++i) { CPDF_PageObject* pPageObj = m_pageObjects[i]; if (!pPageObj || !pPageObj->IsImage()) { continue; } ProcessImage(buf, pPageObj->AsImage()); } CPDF_Object* pContent = pPageDict ? pPageDict->GetDirectObjectFor("Contents") : nullptr; if (pContent) pPageDict->RemoveFor("Contents"); CPDF_Stream* pStream = new CPDF_Stream; pStream->SetData(buf.GetBuffer(), buf.GetLength()); pPageDict->SetReferenceFor("Contents", m_pDocument, m_pDocument->AddIndirectObject(pStream)); }
void CPDF_PageContentGenerator::ProcessForm(CFX_ByteTextBuf& buf, const uint8_t* data, uint32_t size, CFX_Matrix& matrix) { if (!data || !size) return; CPDF_Dictionary* pFormDict = new CPDF_Dictionary(m_pDocument->GetByteStringPool()); pFormDict->SetNameFor("Type", "XObject"); pFormDict->SetNameFor("Subtype", "Form"); CFX_FloatRect bbox = m_pPage->GetPageBBox(); matrix.TransformRect(bbox); pFormDict->SetRectFor("BBox", bbox); CPDF_Stream* pStream = new CPDF_Stream; pStream->InitStream(data, size, pFormDict); buf << "q " << matrix << " cm "; CFX_ByteString name = RealizeResource(pStream, "XObject"); buf << "/" << PDF_NameEncode(name) << " Do Q\n"; }
FX_BOOL CPDF_Function::Init(CPDF_Object* pObj) { CPDF_Stream* pStream = pObj->AsStream(); CPDF_Dictionary* pDict = pStream ? pStream->GetDict() : pObj->AsDictionary(); CPDF_Array* pDomains = pDict->GetArrayBy("Domain"); if (!pDomains) return FALSE; m_nInputs = pDomains->GetCount() / 2; if (m_nInputs == 0) return FALSE; m_pDomains = FX_Alloc2D(FX_FLOAT, m_nInputs, 2); for (uint32_t i = 0; i < m_nInputs * 2; i++) { m_pDomains[i] = pDomains->GetFloatAt(i); } CPDF_Array* pRanges = pDict->GetArrayBy("Range"); m_nOutputs = 0; if (pRanges) { m_nOutputs = pRanges->GetCount() / 2; m_pRanges = FX_Alloc2D(FX_FLOAT, m_nOutputs, 2); for (uint32_t i = 0; i < m_nOutputs * 2; i++) m_pRanges[i] = pRanges->GetFloatAt(i); } uint32_t old_outputs = m_nOutputs; if (!v_Init(pObj)) return FALSE; if (m_pRanges && m_nOutputs > old_outputs) { m_pRanges = FX_Realloc(FX_FLOAT, m_pRanges, m_nOutputs * 2); if (m_pRanges) { FXSYS_memset(m_pRanges + (old_outputs * 2), 0, sizeof(FX_FLOAT) * (m_nOutputs - old_outputs) * 2); } } return TRUE; }
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(); } } }
FX_BOOL CPDF_PageOrganizer::UpdateReference(CPDF_Object* pObj, CPDF_Document* pDoc, ObjectNumberMap* pObjNumberMap) { switch (pObj->GetType()) { case PDFOBJ_REFERENCE: { CPDF_Reference* pReference = pObj->AsReference(); FX_DWORD newobjnum = GetNewObjId(pDoc, pObjNumberMap, pReference); if (newobjnum == 0) return FALSE; pReference->SetRef(pDoc, newobjnum); break; } case PDFOBJ_DICTIONARY: { CPDF_Dictionary* pDict = pObj->AsDictionary(); FX_POSITION pos = pDict->GetStartPos(); while (pos) { CFX_ByteString key(""); CPDF_Object* pNextObj = pDict->GetNextElement(pos, key); if (!FXSYS_strcmp(key, "Parent") || !FXSYS_strcmp(key, "Prev") || !FXSYS_strcmp(key, "First")) { continue; } if (pNextObj) { if (!UpdateReference(pNextObj, pDoc, pObjNumberMap)) pDict->RemoveAt(key); } else { return FALSE; } } break; } case PDFOBJ_ARRAY: { CPDF_Array* pArray = pObj->AsArray(); FX_DWORD count = pArray->GetCount(); for (FX_DWORD i = 0; i < count; ++i) { CPDF_Object* pNextObj = pArray->GetElement(i); if (!pNextObj) return FALSE; if (!UpdateReference(pNextObj, pDoc, pObjNumberMap)) return FALSE; } break; } case PDFOBJ_STREAM: { CPDF_Stream* pStream = pObj->AsStream(); CPDF_Dictionary* pDict = pStream->GetDict(); if (pDict) { if (!UpdateReference(pDict, pDoc, pObjNumberMap)) return FALSE; } else { return FALSE; } break; } default: break; } return TRUE; }
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPage_TransFormWithClip(FPDF_PAGE page, const FS_MATRIX* matrix, const FS_RECTF* clipRect) { if (!matrix && !clipRect) return false; CPDF_Page* pPage = CPDFPageFromFPDFPage(page); if (!pPage) return false; std::ostringstream textBuf; textBuf << "q "; if (clipRect) { CFX_FloatRect rect = CFXFloatRectFromFSRECTF(*clipRect); rect.Normalize(); textBuf << ByteString::Format("%f %f %f %f re W* n ", rect.left, rect.bottom, rect.Width(), rect.Height()); } if (matrix) { textBuf << ByteString::Format("%f %f %f %f %f %f cm ", matrix->a, matrix->b, matrix->c, matrix->d, matrix->e, matrix->f); } CPDF_Dictionary* pPageDict = pPage->GetDict(); CPDF_Object* pContentObj = GetPageContent(pPageDict); if (!pContentObj) return false; CPDF_Document* pDoc = pPage->GetDocument(); if (!pDoc) return false; CPDF_Stream* pStream = pDoc->NewIndirect<CPDF_Stream>(nullptr, 0, pDoc->New<CPDF_Dictionary>()); pStream->SetDataFromStringstream(&textBuf); CPDF_Stream* pEndStream = pDoc->NewIndirect<CPDF_Stream>(nullptr, 0, pDoc->New<CPDF_Dictionary>()); pEndStream->SetData(ByteStringView(" Q").span()); if (CPDF_Array* pContentArray = ToArray(pContentObj)) { pContentArray->InsertAt(0, pStream->MakeReference(pDoc)); pContentArray->Add(pEndStream->MakeReference(pDoc)); } else if (pContentObj->IsStream() && !pContentObj->IsInline()) { pContentArray = pDoc->NewIndirect<CPDF_Array>(); pContentArray->Add(pStream->MakeReference(pDoc)); pContentArray->Add(pContentObj->MakeReference(pDoc)); pContentArray->Add(pEndStream->MakeReference(pDoc)); pPageDict->SetFor(pdfium::page_object::kContents, pContentArray->MakeReference(pDoc)); } // Need to transform the patterns as well. CPDF_Dictionary* pRes = pPageDict->GetDictFor(pdfium::page_object::kResources); if (!pRes) return true; CPDF_Dictionary* pPatternDict = pRes->GetDictFor("Pattern"); if (!pPatternDict) return true; CPDF_DictionaryLocker locker(pPatternDict); for (const auto& it : locker) { CPDF_Object* pObj = it.second.get(); if (pObj->IsReference()) pObj = pObj->GetDirect(); CPDF_Dictionary* pDict = nullptr; if (pObj->IsDictionary()) pDict = pObj->AsDictionary(); else if (CPDF_Stream* pObjStream = pObj->AsStream()) pDict = pObjStream->GetDict(); else continue; if (matrix) { CFX_Matrix m = CFXMatrixFromFSMatrix(*matrix); pDict->SetMatrixFor("Matrix", pDict->GetMatrixFor("Matrix") * m); } } return true; }
FX_BOOL CFFL_Utils::TraceObject(CPDF_Object* pObj) { if (!pObj) return FALSE; FX_DWORD dwObjNum = pObj->GetObjNum(); switch (pObj->GetType()) { case PDFOBJ_ARRAY: { CPDF_Array* pArray = (CPDF_Array*)pObj; for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) { CPDF_Object* pElement = pArray->GetElementValue(i); TraceObject(pElement); } } break; case PDFOBJ_DICTIONARY: { CPDF_Dictionary* pDict = (CPDF_Dictionary*)pObj; FX_POSITION fPos = pDict->GetStartPos(); CFX_ByteString csKey; do { CPDF_Object* pElement = pDict->GetNextElement(fPos, csKey); //TRACE(csKey + "\n"); if (!pElement) break; TraceObject(pElement); }while (TRUE); } break; case PDFOBJ_STREAM: { CPDF_Stream* pStream = (CPDF_Stream*)pObj; CPDF_Dictionary* pDict = pStream->GetDict(); TraceObject(pDict); } break; case PDFOBJ_REFERENCE: { CPDF_Object* pDirectObj = pObj->GetDirect(); TraceObject(pDirectObj); } break; case PDFOBJ_BOOLEAN: break; case PDFOBJ_NUMBER: //TRACE("%d\n",(int32_t)pObj); break; case PDFOBJ_STRING: //TRACE(((CPDF_String*)pObj)->GetString() + "\n"); break; case PDFOBJ_NAME: //TRACE(((CPDF_Name*)pObj)->GetString() + "\n"); break; case PDFOBJ_NULL: // case PDFOBJ_KEYWORD: // case PDFOBJ_EOF: default: break; } if (dwObjNum == 0) return FALSE; return TRUE; }
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; }
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)); } } } }
CFX_DIBitmap* CPDF_RenderStatus::LoadSMask(CPDF_Dictionary* pSMaskDict, FX_RECT* pClipRect, const CFX_AffineMatrix* pMatrix) { if (pSMaskDict == NULL) { return NULL; } int width = pClipRect->right - pClipRect->left; int height = pClipRect->bottom - pClipRect->top; FX_BOOL bLuminosity = FALSE; bLuminosity = pSMaskDict->GetConstString(FX_BSTRC("S")) != FX_BSTRC("Alpha"); CPDF_Stream* pGroup = pSMaskDict->GetStream(FX_BSTRC("G")); if (pGroup == NULL) { return NULL; } nonstd::unique_ptr<CPDF_Function> pFunc; CPDF_Object* pFuncObj = pSMaskDict->GetElementValue(FX_BSTRC("TR")); if (pFuncObj && (pFuncObj->IsDictionary() || pFuncObj->IsStream())) pFunc.reset(CPDF_Function::Load(pFuncObj)); CFX_AffineMatrix matrix = *pMatrix; matrix.TranslateI(-pClipRect->left, -pClipRect->top); CPDF_Form form(m_pContext->m_pDocument, m_pContext->m_pPageResources, pGroup); form.ParseContent(NULL, NULL, NULL, NULL); CFX_FxgeDevice bitmap_device; #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ if (!bitmap_device.Create(width, height, bLuminosity ? FXDIB_Rgb32 : FXDIB_8bppMask)) { return NULL; } #else if (!bitmap_device.Create(width, height, bLuminosity ? FXDIB_Rgb : FXDIB_8bppMask)) { return NULL; } #endif CFX_DIBitmap& bitmap = *bitmap_device.GetBitmap(); CPDF_Object* pCSObj = NULL; CPDF_ColorSpace* pCS = NULL; if (bLuminosity) { CPDF_Array* pBC = pSMaskDict->GetArray(FX_BSTRC("BC")); FX_ARGB back_color = 0xff000000; if (pBC) { CPDF_Dictionary* pDict = pGroup->GetDict(); if (pDict && pDict->GetDict(FX_BSTRC("Group"))) pCSObj = pDict->GetDict(FX_BSTRC("Group"))->GetElementValue(FX_BSTRC("CS")); else pCSObj = NULL; pCS = m_pContext->m_pDocument->LoadColorSpace(pCSObj); if (pCS) { FX_FLOAT R, G, B; FX_DWORD comps = 8; if (pCS->CountComponents() > static_cast<int32_t>(comps)) { comps = (FX_DWORD)pCS->CountComponents(); } CFX_FixedBufGrow<FX_FLOAT, 8> float_array(comps); FX_FLOAT* pFloats = float_array; FX_SAFE_DWORD num_floats = comps; num_floats *= sizeof(FX_FLOAT); if (!num_floats.IsValid()) { return NULL; } FXSYS_memset(pFloats, 0, num_floats.ValueOrDie()); int count = pBC->GetCount() > 8 ? 8 : pBC->GetCount(); for (int i = 0; i < count; i++) { pFloats[i] = pBC->GetNumber(i); } pCS->GetRGB(pFloats, R, G, B); back_color = 0xff000000 | ((int32_t)(R * 255) << 16) | ((int32_t)(G * 255) << 8) | (int32_t)(B * 255); m_pContext->m_pDocument->GetPageData()->ReleaseColorSpace(pCSObj); } } bitmap.Clear(back_color); } else { bitmap.Clear(0); } CPDF_Dictionary* pFormResource = NULL; if (form.m_pFormDict) { pFormResource = form.m_pFormDict->GetDict(FX_BSTRC("Resources")); } CPDF_RenderOptions options; options.m_ColorMode = bLuminosity ? RENDER_COLOR_NORMAL : RENDER_COLOR_ALPHA; CPDF_RenderStatus status; status.Initialize(m_pContext, &bitmap_device, NULL, NULL, NULL, NULL, &options, 0, m_bDropObjects, pFormResource, TRUE, NULL, 0, pCS ? pCS->GetFamily() : 0, bLuminosity); status.RenderObjectList(&form, &matrix); nonstd::unique_ptr<CFX_DIBitmap> pMask(new CFX_DIBitmap); if (!pMask->Create(width, height, FXDIB_8bppMask)) return nullptr; uint8_t* dest_buf = pMask->GetBuffer(); int dest_pitch = pMask->GetPitch(); uint8_t* src_buf = bitmap.GetBuffer(); int src_pitch = bitmap.GetPitch(); std::vector<uint8_t> transfers(256); if (pFunc) { CFX_FixedBufGrow<FX_FLOAT, 16> results(pFunc->CountOutputs()); for (int i = 0; i < 256; i++) { FX_FLOAT input = (FX_FLOAT)i / 255.0f; int nresult; pFunc->Call(&input, 1, results, nresult); transfers[i] = FXSYS_round(results[0] * 255); } } else { for (int i = 0; i < 256; i++) { transfers[i] = i; } } if (bLuminosity) { int Bpp = bitmap.GetBPP() / 8; for (int row = 0; row < height; row++) { uint8_t* dest_pos = dest_buf + row * dest_pitch; uint8_t* src_pos = src_buf + row * src_pitch; for (int col = 0; col < width; col++) { *dest_pos++ = transfers[FXRGB2GRAY(src_pos[2], src_pos[1], *src_pos)]; src_pos += Bpp; } } } else if (pFunc) { int size = dest_pitch * height; for (int i = 0; i < size; i++) { dest_buf[i] = transfers[src_buf[i]]; } } else { FXSYS_memcpy(dest_buf, src_buf, dest_pitch * height); } return pMask.release(); }
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; }
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; } } }
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; }
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)); } } } }