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 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); }
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 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()); } } }
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; }
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; }
FX_BOOL CPDF_ICCBasedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { CPDF_Stream* pStream = pArray->GetStream(1); if (pStream == NULL) { return FALSE; } m_pProfile = pDoc->LoadIccProfile(pStream); if (!m_pProfile) { return FALSE; } m_nComponents = m_pProfile->GetComponents(); //Try using the nComponents from ICC profile CPDF_Dictionary* pDict = pStream->GetDict(); if (m_pProfile->m_pTransform == NULL) { // No valid ICC profile or using sRGB CPDF_Object* pAlterCSObj = pDict ? pDict->GetElementValue(FX_BSTRC("Alternate")) : NULL; if (pAlterCSObj) { CPDF_ColorSpace* pAlterCS = CPDF_ColorSpace::Load(pDoc, pAlterCSObj); if (pAlterCS) { if (m_nComponents == 0) { // NO valid ICC profile if (pAlterCS->CountComponents() > 0) { // Use Alternative colorspace m_nComponents = pAlterCS->CountComponents(); m_pAlterCS = pAlterCS; m_bOwn = TRUE; } else { // No valid alternative colorspace pAlterCS->ReleaseCS(); int32_t nDictComponents = pDict ? pDict->GetInteger(FX_BSTRC("N")) : 0; if (nDictComponents != 1 && nDictComponents != 3 && nDictComponents != 4) { return FALSE; } m_nComponents = nDictComponents; } } else { // Using sRGB if (pAlterCS->CountComponents() != m_nComponents) { pAlterCS->ReleaseCS(); } else { m_pAlterCS = pAlterCS; m_bOwn = TRUE; } } } } if (!m_pAlterCS) { if (m_nComponents == 1) { m_pAlterCS = GetStockCS(PDFCS_DEVICEGRAY); } else if (m_nComponents == 3) { m_pAlterCS = GetStockCS(PDFCS_DEVICERGB); } else if (m_nComponents == 4) { m_pAlterCS = GetStockCS(PDFCS_DEVICECMYK); } } } CPDF_Array* pRanges = pDict->GetArray(FX_BSTRC("Range")); m_pRanges = FX_Alloc2D(FX_FLOAT, m_nComponents, 2); for (int i = 0; i < m_nComponents * 2; i ++) { if (pRanges) { m_pRanges[i] = pRanges->GetNumber(i); } else if (i % 2) { m_pRanges[i] = 1.0f; } else { m_pRanges[i] = 0; } } 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 int STDCALL FPDFPage_Flatten(FPDF_PAGE page, int nFlag) { CPDF_Page* pPage = CPDFPageFromFPDFPage(page); if (!page) { return FLATTEN_FAIL; } CPDF_Document* pDocument = pPage->m_pDocument; CPDF_Dictionary* pPageDict = pPage->m_pFormDict; if (!pDocument || !pPageDict) { return FLATTEN_FAIL; } CPDF_ObjectArray ObjectArray; CPDF_RectArray RectArray; int iRet = FLATTEN_FAIL; iRet = ParserAnnots(pDocument, pPageDict, &RectArray, &ObjectArray, nFlag); if (iRet == FLATTEN_NOTHINGTODO || iRet == FLATTEN_FAIL) return iRet; CFX_FloatRect rcOriginalCB; CFX_FloatRect rcMerger = CalculateRect(&RectArray); CFX_FloatRect rcOriginalMB = pPageDict->GetRectFor("MediaBox"); if (pPageDict->KeyExist("CropBox")) rcOriginalMB = pPageDict->GetRectFor("CropBox"); if (rcOriginalMB.IsEmpty()) { rcOriginalMB = CFX_FloatRect(0.0f, 0.0f, 612.0f, 792.0f); } rcMerger.left = rcMerger.left < rcOriginalMB.left ? rcOriginalMB.left : rcMerger.left; rcMerger.right = rcMerger.right > rcOriginalMB.right ? rcOriginalMB.right : rcMerger.right; rcMerger.top = rcMerger.top > rcOriginalMB.top ? rcOriginalMB.top : rcMerger.top; rcMerger.bottom = rcMerger.bottom < rcOriginalMB.bottom ? rcOriginalMB.bottom : rcMerger.bottom; if (pPageDict->KeyExist("ArtBox")) rcOriginalCB = pPageDict->GetRectFor("ArtBox"); else rcOriginalCB = rcOriginalMB; if (!rcOriginalMB.IsEmpty()) { CPDF_Array* pMediaBox = new CPDF_Array(); pMediaBox->Add(new CPDF_Number(rcOriginalMB.left)); pMediaBox->Add(new CPDF_Number(rcOriginalMB.bottom)); pMediaBox->Add(new CPDF_Number(rcOriginalMB.right)); pMediaBox->Add(new CPDF_Number(rcOriginalMB.top)); pPageDict->SetFor("MediaBox", pMediaBox); } if (!rcOriginalCB.IsEmpty()) { CPDF_Array* pCropBox = new CPDF_Array(); pCropBox->Add(new CPDF_Number(rcOriginalCB.left)); pCropBox->Add(new CPDF_Number(rcOriginalCB.bottom)); pCropBox->Add(new CPDF_Number(rcOriginalCB.right)); pCropBox->Add(new CPDF_Number(rcOriginalCB.top)); pPageDict->SetFor("ArtBox", pCropBox); } CPDF_Dictionary* pRes = pPageDict->GetDictFor("Resources"); if (!pRes) { pRes = new CPDF_Dictionary(pDocument->GetByteStringPool()); pPageDict->SetFor("Resources", pRes); } CPDF_Stream* pNewXObject = new CPDF_Stream( nullptr, 0, new CPDF_Dictionary(pDocument->GetByteStringPool())); uint32_t dwObjNum = pDocument->AddIndirectObject(pNewXObject); CPDF_Dictionary* pPageXObject = pRes->GetDictFor("XObject"); if (!pPageXObject) { pPageXObject = new CPDF_Dictionary(pDocument->GetByteStringPool()); pRes->SetFor("XObject", pPageXObject); } CFX_ByteString key = ""; int nStreams = ObjectArray.GetSize(); if (nStreams > 0) { for (int iKey = 0; /*iKey < 100*/; iKey++) { char sExtend[5] = {}; FXSYS_itoa(iKey, sExtend, 10); key = CFX_ByteString("FFT") + CFX_ByteString(sExtend); if (!pPageXObject->KeyExist(key)) break; } } SetPageContents(key, pPageDict, pDocument); CPDF_Dictionary* pNewXORes = nullptr; if (!key.IsEmpty()) { pPageXObject->SetReferenceFor(key, pDocument, dwObjNum); CPDF_Dictionary* pNewOXbjectDic = pNewXObject->GetDict(); pNewXORes = new CPDF_Dictionary(pDocument->GetByteStringPool()); pNewOXbjectDic->SetFor("Resources", pNewXORes); pNewOXbjectDic->SetNameFor("Type", "XObject"); pNewOXbjectDic->SetNameFor("Subtype", "Form"); pNewOXbjectDic->SetIntegerFor("FormType", 1); pNewOXbjectDic->SetNameFor("Name", "FRM"); CFX_FloatRect rcBBox = pPageDict->GetRectFor("ArtBox"); pNewOXbjectDic->SetRectFor("BBox", rcBBox); } for (int i = 0; i < nStreams; i++) { CPDF_Dictionary* pAnnotDic = ObjectArray.GetAt(i); if (!pAnnotDic) continue; CFX_FloatRect rcAnnot = pAnnotDic->GetRectFor("Rect"); rcAnnot.Normalize(); CFX_ByteString sAnnotState = pAnnotDic->GetStringFor("AS"); CPDF_Dictionary* pAnnotAP = pAnnotDic->GetDictFor("AP"); if (!pAnnotAP) continue; CPDF_Stream* pAPStream = pAnnotAP->GetStreamFor("N"); if (!pAPStream) { CPDF_Dictionary* pAPDic = pAnnotAP->GetDictFor("N"); if (!pAPDic) continue; if (!sAnnotState.IsEmpty()) { pAPStream = pAPDic->GetStreamFor(sAnnotState); } else { auto it = pAPDic->begin(); if (it != pAPDic->end()) { CPDF_Object* pFirstObj = it->second; if (pFirstObj) { if (pFirstObj->IsReference()) pFirstObj = pFirstObj->GetDirect(); if (!pFirstObj->IsStream()) continue; pAPStream = pFirstObj->AsStream(); } } } } if (!pAPStream) continue; CPDF_Dictionary* pAPDic = pAPStream->GetDict(); CFX_Matrix matrix = pAPDic->GetMatrixFor("Matrix"); CFX_FloatRect rcStream; if (pAPDic->KeyExist("Rect")) rcStream = pAPDic->GetRectFor("Rect"); else if (pAPDic->KeyExist("BBox")) rcStream = pAPDic->GetRectFor("BBox"); if (rcStream.IsEmpty()) continue; CPDF_Object* pObj = pAPStream; if (pObj) { CPDF_Dictionary* pObjDic = pObj->GetDict(); if (pObjDic) { pObjDic->SetNameFor("Type", "XObject"); pObjDic->SetNameFor("Subtype", "Form"); } } CPDF_Dictionary* pXObject = pNewXORes->GetDictFor("XObject"); if (!pXObject) { pXObject = new CPDF_Dictionary(pDocument->GetByteStringPool()); pNewXORes->SetFor("XObject", pXObject); } CFX_ByteString sFormName; sFormName.Format("F%d", i); pXObject->SetReferenceFor(sFormName, pDocument, pDocument->AddIndirectObject(pObj)); CPDF_StreamAcc acc; acc.LoadAllData(pNewXObject); const uint8_t* pData = acc.GetData(); CFX_ByteString sStream(pData, acc.GetSize()); if (matrix.IsIdentity()) { matrix.a = 1.0f; matrix.b = 0.0f; matrix.c = 0.0f; matrix.d = 1.0f; matrix.e = 0.0f; matrix.f = 0.0f; } CFX_ByteString sTemp; CFX_Matrix m = GetMatrix(rcAnnot, rcStream, matrix); sTemp.Format("q %f 0 0 %f %f %f cm /%s Do Q\n", m.a, m.d, m.e, m.f, sFormName.c_str()); sStream += sTemp; pNewXObject->SetData(sStream.raw_str(), sStream.GetLength()); } pPageDict->RemoveFor("Annots"); ObjectArray.RemoveAll(); RectArray.RemoveAll(); return FLATTEN_SUCCESS; }
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; }
CFX_DIBitmap* CPDF_RenderStatus::LoadSMask(CPDF_Dictionary* pSMaskDict, FX_RECT* pClipRect, const CFX_AffineMatrix* pMatrix) { if (pSMaskDict == NULL) { return NULL; } CFX_DIBitmap* pMask = 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; } CPDF_Function* pFunc = NULL; CPDF_Object* pFuncObj = pSMaskDict->GetElementValue(FX_BSTRC("TR")); if (pFuncObj && (pFuncObj->GetType() == PDFOBJ_DICTIONARY || pFuncObj->GetType() == PDFOBJ_STREAM)) { pFunc = 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) { pCSObj = pGroup->GetDict()->GetDict(FX_BSTRC("Group"))->GetElementValue(FX_BSTRC("CS")); pCS = m_pContext->m_pDocument->LoadColorSpace(pCSObj); if (pCS) { FX_FLOAT R, G, B; FX_DWORD num_floats = 8; if (pCS->CountComponents() > (FX_INT32)num_floats) { num_floats = (FX_DWORD)pCS->CountComponents(); } CFX_FixedBufGrow<FX_FLOAT, 8> float_array(num_floats); FX_FLOAT* pFloats = float_array; FXSYS_memset32(pFloats, 0, num_floats * sizeof(FX_FLOAT)); 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 | ((FX_INT32)(R * 255) << 16) | ((FX_INT32)(G * 255) << 8) | (FX_INT32)(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_Level + 1, 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); pMask = FX_NEW CFX_DIBitmap; if (!pMask->Create(width, height, FXDIB_8bppMask)) { delete pMask; return NULL; } FX_LPBYTE dest_buf = pMask->GetBuffer(); int dest_pitch = pMask->GetPitch(); FX_LPBYTE src_buf = bitmap.GetBuffer(); int src_pitch = bitmap.GetPitch(); FX_LPBYTE pTransfer = FX_Alloc(FX_BYTE, 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); pTransfer[i] = FXSYS_round(results[0] * 255); } } else { for (int i = 0; i < 256; i ++) { pTransfer[i] = i; } } if (bLuminosity) { int Bpp = bitmap.GetBPP() / 8; for (int row = 0; row < height; row ++) { FX_LPBYTE dest_pos = dest_buf + row * dest_pitch; FX_LPBYTE src_pos = src_buf + row * src_pitch; for (int col = 0; col < width; col ++) { *dest_pos ++ = pTransfer[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] = pTransfer[src_buf[i]]; } } else { FXSYS_memcpy32(dest_buf, src_buf, dest_pitch * height); } if (pFunc) { delete pFunc; } FX_Free(pTransfer); return pMask; }
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; }
DLLEXPORT int STDCALL FPDFPage_Flatten( FPDF_PAGE page, int nFlag) { if (!page) { return FLATTEN_FAIL; } CPDF_Page * pPage = (CPDF_Page*)( page ); CPDF_Document * pDocument = pPage->m_pDocument; CPDF_Dictionary * pPageDict = pPage->m_pFormDict; if ( !pDocument || !pPageDict ) { return FLATTEN_FAIL; } CPDF_ObjectArray ObjectArray; CPDF_RectArray RectArray; int iRet = FLATTEN_FAIL; iRet = ParserAnnots( pDocument, pPageDict, &RectArray, &ObjectArray, nFlag); if (iRet == FLATTEN_NOTINGTODO) { return FLATTEN_NOTINGTODO; }else if (iRet == FLATTEN_FAIL) { return FLATTEN_FAIL; } CPDF_Rect rcOriginalCB; CPDF_Rect rcMerger = CalculateRect( &RectArray ); CPDF_Rect rcOriginalMB = pPageDict->GetRect("MediaBox"); if (pPageDict->KeyExist("CropBox")) rcOriginalMB = pPageDict->GetRect("CropBox"); if (rcOriginalMB.IsEmpty()) { rcOriginalMB = CPDF_Rect(0.0f, 0.0f, 612.0f, 792.0f); } rcMerger.left = rcMerger.left < rcOriginalMB.left? rcOriginalMB.left : rcMerger.left; rcMerger.right = rcMerger.right > rcOriginalMB.right? rcOriginalMB.right : rcMerger.right; rcMerger.top = rcMerger.top > rcOriginalMB.top? rcOriginalMB.top : rcMerger.top; rcMerger.bottom = rcMerger.bottom < rcOriginalMB.bottom? rcOriginalMB.bottom : rcMerger.bottom; if (pPageDict->KeyExist("ArtBox")) rcOriginalCB = pPageDict->GetRect("ArtBox"); else rcOriginalCB = rcOriginalMB; if (!rcOriginalMB.IsEmpty()) { CPDF_Array* pMediaBox = FX_NEW CPDF_Array(); pMediaBox->Add(FX_NEW CPDF_Number(rcOriginalMB.left)); pMediaBox->Add(FX_NEW CPDF_Number(rcOriginalMB.bottom)); pMediaBox->Add(FX_NEW CPDF_Number(rcOriginalMB.right)); pMediaBox->Add(FX_NEW CPDF_Number(rcOriginalMB.top)); pPageDict->SetAt("MediaBox",pMediaBox); } if (!rcOriginalCB.IsEmpty()) { CPDF_Array* pCropBox = FX_NEW CPDF_Array(); pCropBox->Add(FX_NEW CPDF_Number(rcOriginalCB.left)); pCropBox->Add(FX_NEW CPDF_Number(rcOriginalCB.bottom)); pCropBox->Add(FX_NEW CPDF_Number(rcOriginalCB.right)); pCropBox->Add(FX_NEW CPDF_Number(rcOriginalCB.top)); pPageDict->SetAt("ArtBox", pCropBox); } CPDF_Dictionary* pRes = NULL; pRes = pPageDict->GetDict("Resources"); if (!pRes) { pRes = FX_NEW CPDF_Dictionary; pPageDict->SetAt( "Resources", pRes ); } CPDF_Stream* pNewXObject = FX_NEW CPDF_Stream(NULL, 0, FX_NEW CPDF_Dictionary); FX_DWORD dwObjNum = pDocument->AddIndirectObject(pNewXObject); CPDF_Dictionary* pPageXObject = pRes->GetDict("XObject"); if (!pPageXObject) { pPageXObject = FX_NEW CPDF_Dictionary; pRes->SetAt("XObject", pPageXObject); } CFX_ByteString key = ""; int nStreams = ObjectArray.GetSize(); if (nStreams > 0) { for (int iKey = 0; /*iKey < 100*/; iKey++) { char sExtend[5] = {0}; FXSYS_itoa(iKey, sExtend, 10); key = CFX_ByteString("FFT") + CFX_ByteString(sExtend); if (!pPageXObject->KeyExist(key)) break; } } SetPageContents(key, pPageDict, pDocument); CPDF_Dictionary* pNewXORes = NULL; if (!key.IsEmpty()) { pPageXObject->SetAtReference(key, pDocument, dwObjNum); CPDF_Dictionary* pNewOXbjectDic = pNewXObject->GetDict(); pNewXORes = FX_NEW CPDF_Dictionary; pNewOXbjectDic->SetAt("Resources", pNewXORes); pNewOXbjectDic->SetAtName("Type", "XObject"); pNewOXbjectDic->SetAtName("Subtype", "Form"); pNewOXbjectDic->SetAtInteger("FormType", 1); pNewOXbjectDic->SetAtName("Name", "FRM"); CPDF_Rect rcBBox = pPageDict->GetRect("ArtBox"); pNewOXbjectDic->SetAtRect("BBox", rcBBox); } for (int i = 0; i < nStreams; i++) { CPDF_Dictionary* pAnnotDic = ObjectArray.GetAt(i); if (!pAnnotDic)continue; CPDF_Rect rcAnnot = pAnnotDic->GetRect("Rect"); rcAnnot.Normalize(); CFX_ByteString sAnnotState = pAnnotDic->GetString("AS"); CPDF_Dictionary* pAnnotAP = pAnnotDic->GetDict("AP"); if (!pAnnotAP)continue; CPDF_Stream* pAPStream = pAnnotAP->GetStream("N"); if (!pAPStream) { CPDF_Dictionary* pAPDic = pAnnotAP->GetDict("N"); if (!pAPDic)continue; if (!sAnnotState.IsEmpty()) { pAPStream = pAPDic->GetStream(sAnnotState); } else { FX_POSITION pos = pAPDic->GetStartPos(); if (pos) { CFX_ByteString sKey; CPDF_Object* pFirstObj = pAPDic->GetNextElement(pos, sKey); if (pFirstObj) { if (pFirstObj->GetType() == PDFOBJ_REFERENCE) pFirstObj = pFirstObj->GetDirect(); if (pFirstObj->GetType() != PDFOBJ_STREAM) continue; pAPStream = (CPDF_Stream*)pFirstObj; } } } } if (!pAPStream)continue; CPDF_Dictionary* pAPDic = pAPStream->GetDict(); CFX_AffineMatrix matrix = pAPDic->GetMatrix("Matrix"); CPDF_Rect rcStream; if (pAPDic->KeyExist("Rect")) rcStream = pAPDic->GetRect("Rect"); else if (pAPDic->KeyExist("BBox")) rcStream = pAPDic->GetRect("BBox"); if (rcStream.IsEmpty())continue; CPDF_Object* pObj = pAPStream; if (pObj) { CPDF_Dictionary* pObjDic = pObj->GetDict(); if (pObjDic) { pObjDic->SetAtName("Type", "XObject"); pObjDic->SetAtName("Subtype", "Form"); } } CPDF_Dictionary* pXObject = pNewXORes->GetDict("XObject"); if (!pXObject) { pXObject = FX_NEW CPDF_Dictionary; pNewXORes->SetAt("XObject", pXObject); } CFX_ByteString sFormName; sFormName.Format("F%d", i); FX_DWORD dwObjNum = pDocument->AddIndirectObject(pObj); pXObject->SetAtReference(sFormName, pDocument, dwObjNum); CPDF_StreamAcc acc; acc.LoadAllData(pNewXObject); FX_LPCBYTE pData = acc.GetData(); CFX_ByteString sStream(pData, acc.GetSize()); CFX_ByteString sTemp; if (matrix.IsIdentity()) { matrix.a = 1.0f; matrix.b = 0.0f; matrix.c = 0.0f; matrix.d = 1.0f; matrix.e = 0.0f; matrix.f = 0.0f; } CFX_AffineMatrix m = GetMatrix(rcAnnot, rcStream, matrix); sTemp.Format("q %f 0 0 %f %f %f cm /%s Do Q\n", m.a, m.d, m.e, m.f, sFormName.c_str()); sStream += sTemp; pNewXObject->SetData((FX_LPCBYTE)sStream, sStream.GetLength(), FALSE, FALSE); } pPageDict->RemoveAt( "Annots" ); ObjectArray.RemoveAll(); RectArray.RemoveAll(); return FLATTEN_SUCCESS; }
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(); }
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")); m_SampleMax = 0xffffffff >> (32 - m_nBitsPerSample); m_pSampleStream = FX_NEW CPDF_StreamAcc; m_pSampleStream->LoadAllData(pStream, FALSE); m_pEncodeInfo = FX_Alloc(SampleEncodeInfo, m_nInputs); int i; FX_DWORD nTotalSamples = 1; for (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")); } if (nTotalSamples > 0 && (FX_UINT32)(m_pEncodeInfo[i].sizes) > UINT_MAX / nTotalSamples) { return FALSE; } nTotalSamples *= 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; } } } if (nTotalSamples > 0 && m_nBitsPerSample > UINT_MAX / nTotalSamples) { return FALSE; } nTotalSamples *= m_nBitsPerSample; if (nTotalSamples > 0 && ((FX_UINT32)m_nOutputs) > UINT_MAX / nTotalSamples) { return FALSE; } nTotalSamples *= m_nOutputs; if (nTotalSamples == 0 || m_pSampleStream->GetSize() * 8 < nTotalSamples) { return FALSE; } m_pDecodeInfo = FX_Alloc(SampleDecodeInfo, m_nOutputs); for (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; }
void CPDFSDK_Annot::WriteAppearance(const CFX_ByteString& sAPType, const CPDF_Rect& rcBBox, const CPDF_Matrix& matrix, const CFX_ByteString& sContents, const CFX_ByteString& sAPState) { ASSERT(m_pAnnot != NULL); ASSERT(m_pAnnot->m_pAnnotDict != NULL); CPDF_Dictionary* pAPDict = m_pAnnot->m_pAnnotDict->GetDict("AP"); if (!pAPDict) { pAPDict = FX_NEW CPDF_Dictionary; m_pAnnot->m_pAnnotDict->SetAt("AP", pAPDict); } CPDF_Stream* pStream = NULL; CPDF_Dictionary* pParentDict = NULL; if (sAPState.IsEmpty()) { pParentDict = pAPDict; pStream = pAPDict->GetStream(sAPType); } else { CPDF_Dictionary* pAPTypeDict = pAPDict->GetDict(sAPType); if (!pAPTypeDict) { pAPTypeDict = FX_NEW CPDF_Dictionary; pAPDict->SetAt(sAPType, pAPTypeDict); } pParentDict = pAPTypeDict; pStream = pAPTypeDict->GetStream(sAPState); } if (!pStream) { ASSERT(m_pPageView != NULL); CPDF_Document* pDoc = m_pPageView->GetPDFDocument(); ASSERT(pDoc != NULL); pStream = FX_NEW CPDF_Stream(NULL, 0, NULL); FX_INT32 objnum = pDoc->AddIndirectObject(pStream); //pAPDict->SetAtReference(sAPType, pDoc, objnum); ASSERT(pParentDict != NULL); pParentDict->SetAtReference(sAPType, pDoc, objnum); } CPDF_Dictionary * pStreamDict = pStream->GetDict(); if (!pStreamDict) { pStreamDict = FX_NEW CPDF_Dictionary; pStreamDict->SetAtName("Type", "XObject"); pStreamDict->SetAtName("Subtype", "Form"); pStreamDict->SetAtInteger("FormType", 1); pStream->InitStream(NULL,0,pStreamDict); } if (pStreamDict) { pStreamDict->SetAtMatrix("Matrix",matrix); pStreamDict->SetAtRect("BBox", rcBBox); } pStream->SetData((FX_BYTE*)sContents.c_str(), sContents.GetLength(), FALSE, FALSE); }