CPDF_Object* CPDF_ActionFields::GetField(FX_DWORD iIndex) const { if (!m_pAction) { return NULL; } CPDF_Dictionary* pDict = m_pAction->GetDict(); if (!pDict) { return NULL; } CFX_ByteString csType = pDict->GetString("S"); CPDF_Object* pFields = NULL; if (csType == "Hide") { pFields = pDict->GetElementValue("T"); } else { pFields = pDict->GetArray("Fields"); } if (!pFields) { return NULL; } CPDF_Object* pFindObj = NULL; if (pFields->IsDictionary() || pFields->IsString()) { if (iIndex == 0) pFindObj = pFields; } else if (CPDF_Array* pArray = pFields->AsArray()) { pFindObj = pArray->GetElementValue(iIndex); } return pFindObj; }
std::vector<CPDF_Object*> CPDF_ActionFields::GetAllFields() const { std::vector<CPDF_Object*> fields; if (!m_pAction) return fields; CPDF_Dictionary* pDict = m_pAction->GetDict(); if (!pDict) return fields; CFX_ByteString csType = pDict->GetStringFor("S"); CPDF_Object* pFields; if (csType == "Hide") pFields = pDict->GetDirectObjectFor("T"); else pFields = pDict->GetArrayFor("Fields"); if (!pFields) return fields; if (pFields->IsDictionary() || pFields->IsString()) { fields.push_back(pFields); } else if (CPDF_Array* pArray = pFields->AsArray()) { for (size_t i = 0; i < pArray->GetCount(); ++i) { CPDF_Object* pObj = pArray->GetDirectObjectAt(i); if (pObj) fields.push_back(pObj); } } return fields; }
FX_BOOL CPDF_StructTreeImpl::AddTopLevelNode(CPDF_Dictionary* pDict, CPDF_StructElementImpl* pElement) { CPDF_Object* pObj = m_pTreeRoot->GetDirectObjectBy("K"); if (!pObj) return FALSE; if (pObj->IsDictionary()) { if (pObj->GetObjNum() != pDict->GetObjNum()) return FALSE; m_Kids[0].Reset(pElement); } if (CPDF_Array* pTopKids = pObj->AsArray()) { bool bSave = false; for (size_t i = 0; i < pTopKids->GetCount(); i++) { CPDF_Reference* pKidRef = ToReference(pTopKids->GetObjectAt(i)); if (pKidRef && pKidRef->GetRefObjNum() == pDict->GetObjNum()) { m_Kids[i].Reset(pElement); bSave = true; } } if (!bSave) return FALSE; } return TRUE; }
std::vector<CPDF_Object*> CPDF_ActionFields::GetAllFields() const { std::vector<CPDF_Object*> fields; if (!m_pAction) return fields; CPDF_Dictionary* pDict = m_pAction->GetDict(); if (!pDict) return fields; CFX_ByteString csType = pDict->GetString("S"); CPDF_Object* pFields; if (csType == "Hide") pFields = pDict->GetElementValue("T"); else pFields = pDict->GetArray("Fields"); if (!pFields) return fields; if (pFields->IsDictionary() || pFields->IsString()) { fields.push_back(pFields); } else if (CPDF_Array* pArray = pFields->AsArray()) { FX_DWORD iCount = pArray->GetCount(); for (FX_DWORD i = 0; i < iCount; ++i) { CPDF_Object* pObj = pArray->GetElementValue(i); if (pObj) { fields.push_back(pObj); } } } return fields; }
CPDF_Object* CPDF_ActionFields::GetField(size_t iIndex) const { if (!m_pAction) return nullptr; CPDF_Dictionary* pDict = m_pAction->GetDict(); if (!pDict) return nullptr; CFX_ByteString csType = pDict->GetStringFor("S"); CPDF_Object* pFields = nullptr; if (csType == "Hide") pFields = pDict->GetDirectObjectFor("T"); else pFields = pDict->GetArrayFor("Fields"); if (!pFields) return nullptr; CPDF_Object* pFindObj = nullptr; if (pFields->IsDictionary() || pFields->IsString()) { if (iIndex == 0) pFindObj = pFields; } else if (CPDF_Array* pArray = pFields->AsArray()) { pFindObj = pArray->GetDirectObjectAt(iIndex); } return pFindObj; }
FX_DWORD CPDF_ActionFields::GetFieldsCount() const { if (!m_pAction) { return 0; } CPDF_Dictionary* pDict = m_pAction->GetDict(); if (!pDict) { return 0; } CFX_ByteString csType = pDict->GetString("S"); CPDF_Object* pFields = NULL; if (csType == "Hide") { pFields = pDict->GetElementValue("T"); } else { pFields = pDict->GetArray("Fields"); } if (!pFields) return 0; if (pFields->IsDictionary()) return 1; if (pFields->IsString()) return 1; if (CPDF_Array* pArray = pFields->AsArray()) return pArray->GetCount(); return 0; }
size_t CPDF_ActionFields::GetFieldsCount() const { if (!m_pAction) return 0; CPDF_Dictionary* pDict = m_pAction->GetDict(); if (!pDict) return 0; CFX_ByteString csType = pDict->GetStringFor("S"); CPDF_Object* pFields = nullptr; if (csType == "Hide") pFields = pDict->GetDirectObjectFor("T"); else pFields = pDict->GetArrayFor("Fields"); if (!pFields) return 0; if (pFields->IsDictionary()) return 1; if (pFields->IsString()) return 1; if (CPDF_Array* pArray = pFields->AsArray()) return pArray->GetCount(); return 0; }
CPDF_Pattern* CPDF_StreamContentParser::FindPattern(const CFX_ByteString& name, FX_BOOL bShading) { CPDF_Object* pPattern = FindResourceObj(bShading ? "Shading" : "Pattern", name); if (!pPattern || (!pPattern->IsDictionary() && !pPattern->IsStream())) { m_bResourceMissing = TRUE; return NULL; } return m_pDocument->LoadPattern(pPattern, bShading, &m_pCurStates->m_ParentMatrix); }
size_t CPDF_Action::GetSubActionsCount() const { if (!m_pDict || !m_pDict->KeyExist("Next")) return 0; CPDF_Object* pNext = m_pDict->GetDirectObjectFor("Next"); if (!pNext) return 0; if (pNext->IsDictionary()) return 1; if (CPDF_Array* pArray = pNext->AsArray()) return pArray->GetCount(); return 0; }
FX_DWORD CPDF_Action::GetSubActionsCount() const { if (!m_pDict || !m_pDict->KeyExist("Next")) return 0; CPDF_Object* pNext = m_pDict->GetElementValue("Next"); if (!pNext) return 0; if (pNext->IsDictionary()) return 1; if (CPDF_Array* pArray = pNext->AsArray()) return pArray->GetCount(); return 0; }
int CPDF_Dest::GetPageIndex(CPDF_Document* pDoc) { CPDF_Array* pArray = ToArray(m_pObj); if (!pArray) return 0; CPDF_Object* pPage = pArray->GetElementValue(0); if (!pPage) return 0; if (pPage->IsNumber()) return pPage->GetInteger(); if (!pPage->IsDictionary()) return 0; return pDoc->GetPageIndex(pPage->GetObjNum()); }
FX_DWORD CPDF_Dest::GetPageObjNum() { CPDF_Array* pArray = ToArray(m_pObj); if (!pArray) return 0; CPDF_Object* pPage = pArray->GetElementValue(0); if (!pPage) return 0; if (pPage->IsNumber()) return pPage->GetInteger(); if (pPage->IsDictionary()) return pPage->GetObjNum(); return 0; }
uint32_t CPDF_Dest::GetPageObjNum() { CPDF_Array* pArray = ToArray(m_pObj); if (!pArray) return 0; CPDF_Object* pPage = pArray->GetDirectObjectAt(0); if (!pPage) return 0; if (pPage->IsNumber()) return pPage->GetInteger(); if (pPage->IsDictionary()) return pPage->GetObjNum(); return 0; }
void CPDF_StructTreeImpl::LoadPageTree(const CPDF_Dictionary* pPageDict) { m_pPage = pPageDict; if (!m_pTreeRoot) return; CPDF_Object* pKids = m_pTreeRoot->GetDirectObjectBy("K"); if (!pKids) return; uint32_t dwKids = 0; if (pKids->IsDictionary()) dwKids = 1; else if (CPDF_Array* pArray = pKids->AsArray()) dwKids = pArray->GetCount(); else return; m_Kids.clear(); m_Kids.resize(dwKids); CPDF_Dictionary* pParentTree = m_pTreeRoot->GetDictBy("ParentTree"); if (!pParentTree) return; CPDF_NumberTree parent_tree(pParentTree); int parents_id = pPageDict->GetIntegerBy("StructParents", -1); if (parents_id < 0) return; CPDF_Array* pParentArray = ToArray(parent_tree.LookupValue(parents_id)); if (!pParentArray) return; std::map<CPDF_Dictionary*, CPDF_StructElementImpl*> element_map; for (size_t i = 0; i < pParentArray->GetCount(); i++) { if (CPDF_Dictionary* pParent = pParentArray->GetDictAt(i)) AddPageNode(pParent, element_map); } }
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; }
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; }
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(); }