Deferred Link resolution

This commit is contained in:
Svetlana Kulikova
2025-12-02 15:10:49 +03:00
parent df82306306
commit fa532edad6
9 changed files with 54 additions and 13 deletions

View File

@ -1246,6 +1246,7 @@ void CPdfEditor::Close()
}
if (m_nMode == Mode::Split)
{
m_pWriter->EditClose();
m_pWriter->SaveToFile(m_wsDstFile);
return;
}
@ -1512,6 +1513,7 @@ void CPdfEditor::Close()
pEncryptDict->UpdateKey(nCryptAlgorithm);
}
m_pWriter->EditClose();
m_pWriter->SaveToFile(m_wsDstFile);
return;
}

View File

@ -1736,7 +1736,7 @@ void GetRCSpanStyle(CAnnotFieldInfo::CMarkupAnnotPr::CFontData* pFontData, NSStr
oRC.AddDouble(pFontData->dVAlign, 2);
}
}
PdfWriter::CAction* GetAction(PdfWriter::CDocument* m_pDocument, CAnnotFieldInfo::CActionFieldPr* pAction)
PdfWriter::CAction* CPdfWriter::GetAction(CAnnotFieldInfo::CActionFieldPr* pAction, bool bDeferred)
{
PdfWriter::CAction* pA = m_pDocument->CreateAction(pAction->nActionType);
if (!pA)
@ -1748,7 +1748,7 @@ PdfWriter::CAction* GetAction(PdfWriter::CDocument* m_pDocument, CAnnotFieldInfo
case 1:
{
PdfWriter::CActionGoTo* ppA = (PdfWriter::CActionGoTo*)pA;
PdfWriter::CPage* pPageD = m_pDocument->GetPage(pAction->nInt1);
PdfWriter::CPage* pPageD = bDeferred ? m_pDocument->GetCurPage() : m_pDocument->GetPage(pAction->nInt1);
PdfWriter::CDestination* pDest = m_pDocument->CreateDestination(pPageD);
if (!pDest)
break;
@ -1807,6 +1807,12 @@ PdfWriter::CAction* GetAction(PdfWriter::CDocument* m_pDocument, CAnnotFieldInfo
break;
}
}
if (bDeferred)
{
pPageD = m_pDocument->GetCurPage();
m_vDestinations.push_back(TDestinationInfo(pDest, pAction->nInt1));
}
break;
}
case 6:
@ -1845,7 +1851,7 @@ PdfWriter::CAction* GetAction(PdfWriter::CDocument* m_pDocument, CAnnotFieldInfo
if (pAction->pNext)
{
PdfWriter::CAction* pANext = GetAction(m_pDocument, pAction->pNext);
PdfWriter::CAction* pANext = GetAction(pAction->pNext, bDeferred);
pA->SetNext(pANext);
}
@ -2371,7 +2377,7 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF
const std::vector<CAnnotFieldInfo::CActionFieldPr*> arrActions = pPr->GetActions();
for (CAnnotFieldInfo::CActionFieldPr* pAction : arrActions)
{
PdfWriter::CAction* pA = GetAction(m_pDocument, pAction);
PdfWriter::CAction* pA = GetAction(pAction);
pWidgetAnnot->AddAction(pA);
}
@ -2656,18 +2662,26 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF
nFlags = pPr->GetFlags();
if (nFlags & (1 << 0))
{
PdfWriter::CAction* pA = GetAction(m_pDocument, pPr->GetA());
PdfWriter::CAction* pA = GetAction(pPr->GetA(), true);
pLinkAnnot->SetA(pA);
}
if (nFlags & (1 << 1))
{
PdfWriter::CAction* pA = GetAction(m_pDocument, pPr->GetPA());
PdfWriter::CAction* pA = GetAction(pPr->GetPA(), true);
pLinkAnnot->SetPA(pA);
}
if (nFlags & (1 << 2))
pLinkAnnot->SetH(pPr->GetH());
if (nFlags & (1 << 3))
pLinkAnnot->SetQuadPoints(pPr->GetQuadPoints());
if (bRender)
{
pLinkAnnot->RemoveAP();
LONG nLen = 0;
BYTE* pRender = oInfo.GetRender(nLen);
DrawAP(pAnnot, pRender, nLen);
}
}
return S_OK;
@ -3006,7 +3020,7 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi
const std::vector<CAnnotFieldInfo::CActionFieldPr*> arrActions = pParent->arrAction;
for (CAnnotFieldInfo::CActionFieldPr* pAction : arrActions)
{
PdfWriter::CAction* pA = GetAction(m_pDocument, pAction);
PdfWriter::CAction* pA = GetAction(pAction);
if (!pA)
continue;
@ -3189,7 +3203,13 @@ bool CPdfWriter::EditClose()
TDestinationInfo& oInfo = m_vDestinations.at(nIndex);
if (nPagesCount > oInfo.unDestPage)
{
AddLink(oInfo.pPage, oInfo.dX, oInfo.dY, oInfo.dW, oInfo.dH, oInfo.dDestX, oInfo.dDestY, oInfo.unDestPage);
if (oInfo.pDest)
{
PdfWriter::CPage* pDestPage = m_pDocument->GetPage(oInfo.unDestPage);
oInfo.pDest->ChangePage(pDestPage);
}
else
AddLink(oInfo.pPage, oInfo.dX, oInfo.dY, oInfo.dW, oInfo.dH, oInfo.dDestX, oInfo.dDestY, oInfo.unDestPage);
m_vDestinations.erase(m_vDestinations.begin() + nIndex);
nIndex--;
nCount--;

View File

@ -229,6 +229,7 @@ public:
void SetSplit(bool bSplit) { m_bSplit = bSplit; }
private:
PdfWriter::CAction* GetAction(CAnnotFieldInfo::CActionFieldPr* pAction, bool bDeferred = false);
bool SkipRedact(const double& dX, const double& dY, const double& dW, const double& dH);
bool SkipRedact(const double& dX, const double& dY);
PdfWriter::CImageDict* LoadImage(Aggplus::CImage* pImage, BYTE nAlpha);

View File

@ -358,6 +358,10 @@ namespace PdfWriter
pNormal->AddBBox(GetRect().fLeft, GetRect().fBottom, GetRect().fRight, GetRect().fTop);
pNormal->AddMatrix(1, 0, 0, 1, -GetRect().fLeft, -GetRect().fBottom);
}
void CAnnotation::RemoveAP()
{
Remove("AP");
}
//----------------------------------------------------------------------------------------
// CMarkupAnnotation
//----------------------------------------------------------------------------------------
@ -415,10 +419,6 @@ namespace PdfWriter
{
Add("IRT", pAnnot);
}
void CMarkupAnnotation::RemoveAP()
{
Remove("AP");
}
//----------------------------------------------------------------------------------------
// CDestLinkAnnotation
//----------------------------------------------------------------------------------------

View File

@ -194,6 +194,7 @@ namespace PdfWriter
void SetOMetadata(const std::wstring& wsOMetadata);
void SetC(const std::vector<double>& arrC);
void RemoveAP();
void APFromFakePage();
virtual CAnnotAppearanceObject* StartAP(int nRotate);
TRect& GetRect() { return m_oRect; }
@ -256,7 +257,7 @@ namespace PdfWriter
void SetCD(const std::wstring& wsCD);
void SetSubj(const std::wstring& wsSubj);
void RemoveAP();
void SetIRTID(CAnnotation* pAnnot);
CPopupAnnotation* CreatePopup();
};

View File

@ -58,6 +58,12 @@ namespace PdfWriter
return true;
}
void CDestination::ChangePage(CObjectBase* pPage)
{
if (!pPage)
return;
Insert(Get(0, false), pPage, true);
}
void CDestination::PrepareArray()
{
if (m_arrList.size() > 1)

View File

@ -41,6 +41,7 @@ namespace PdfWriter
public:
CDestination(CObjectBase* pPage, CXref* pXref, bool bInline = false);
bool IsValid() const;
void ChangePage(CObjectBase* pPage);
void SetXYZ (float fLeft, float fTop, float fZoom);
void SetFit ();
void SetFitH (float fTop);

View File

@ -47,6 +47,7 @@ namespace PdfWriter
class CFontDict;
class CShading;
class CExtGrState;
class CDestination;
}
class CPdfWriter;
@ -1636,6 +1637,7 @@ struct TDestinationInfo
{
TDestinationInfo(PdfWriter::CPage* page, const double& x, const double& y, const double& w, const double& h, const double& dx, const double& dy, const unsigned int& undpage)
{
pDest = NULL;
pPage = page;
dX = x;
dY = y;
@ -1645,7 +1647,14 @@ struct TDestinationInfo
dDestY = dy;
unDestPage = undpage;
}
TDestinationInfo(PdfWriter::CDestination* dest, const unsigned int& undpage)
{
pDest = dest;
pPage = NULL;
unDestPage = undpage;
}
PdfWriter::CDestination* pDest;
PdfWriter::CPage* pPage;
double dX;
double dY;

View File

@ -1691,6 +1691,7 @@ void Annot::draw(Gfx *gfx, GBool printing) {
// draw the appearance stream
isLink = type && !type->cmp("Link");
#ifdef BUILDING_WASM_MODULE
isLink = gFalse;
if (type && !type->cmp("Stamp"))
{
gfx->drawStamp(&appearance);