From 49d3e46a0f5cebfd50286f43fa170c681326b339 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 21 Nov 2023 18:25:32 +0300 Subject: [PATCH] Create GetWidgetFonts --- PdfFile/PdfFile.cpp | 6 +++ PdfFile/PdfFile.h | 1 + PdfFile/PdfReader.cpp | 115 ++++++++++++++++++++++++++++++++++++++++++ PdfFile/PdfReader.h | 1 + 4 files changed, 123 insertions(+) diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 11a1570230..5d84fe953d 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -1292,6 +1292,12 @@ BYTE* CPdfFile::GetWidgets() return NULL; return m_pInternal->pReader->GetWidgets(); } +BYTE* CPdfFile::GetWidgetFonts() +{ + if (!m_pInternal->pReader) + return NULL; + return m_pInternal->pReader->GetWidgetFonts(); +} BYTE* CPdfFile::GetAnnots(int nPageIndex) { if (!m_pInternal->pReader) diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index b11e596a2c..feddd7c826 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -129,6 +129,7 @@ public: int GetRotate(int nPageIndex); int GetMaxRefID(); BYTE* GetWidgets(); + BYTE* GetWidgetFonts(); BYTE* GetAnnots (int nPageIndex = -1); BYTE* VerifySign (const std::wstring& sFile, ICertificate* pCertificate, int nWidget = -1); BYTE* GetAPWidget (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget = -1, const char* sView = NULL, const char* sBView = NULL); diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index a7171d0cff..6cd2f80ae9 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -883,6 +883,121 @@ BYTE* CPdfReader::GetWidgets() oRes.ClearWithoutAttack(); return bRes; } +BYTE* CPdfReader::GetWidgetFonts() +{ + if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) + return NULL; + + AcroForm* pAcroForms = m_pPDFDocument->getCatalog()->getForm(); + XRef* xref = m_pPDFDocument->getXRef(); + if (!pAcroForms || !xref) + return NULL; + + NSWasm::CData oRes; + oRes.SkipLen(); + + Object oObj1, oObj2; + + for (int i = 0, nNum = pAcroForms->getNumFields(); i < nNum; ++i) + { + AcroFormField* pField = pAcroForms->getField(i); + Object oFieldRef, oField; + if (!pField || !pField->getFieldRef(&oFieldRef)->isRef() || !oFieldRef.fetch(xref, &oField)->isDict()) + { + oField.free(); oFieldRef.free(); + continue; + } + + GfxFont* gfxFont = NULL; + GfxFontDict *gfxFontDict = NULL; + + // Шрифт и размер шрифта - из DA + Ref fontID; + double dFontSize = 0; + pField->getFont(&fontID, &dFontSize); + if (fontID.num > 0) + { + Object oObj, oField, oFont; + pField->getFieldRef(&oObj); + oObj.fetch(xref, &oField); + oObj.free(); + + bool bFindResources = false; + + if (oField.dictLookup("DR", &oObj)->isDict() && oObj.dictLookup("Font", &oFont)->isDict()) + { + for (int i = 0; i < oFont.dictGetLength(); ++i) + { + Object oFontRef; + if (oFont.dictGetValNF(i, &oFontRef)->isRef() && oFontRef.getRef() == fontID) + { + bFindResources = true; + oFontRef.free(); + break; + } + oFontRef.free(); + } + } + oFont.free(); oField.free(); + + if (!bFindResources) + { + oObj.free(); + Object* oAcroForm = pAcroForms->getAcroFormObj(); + if (oAcroForm->isDict() && oAcroForm->dictLookup("DR", &oObj)->isDict() && oObj.dictLookup("Font", &oFont)->isDict()) + { + for (int i = 0; i < oFont.dictGetLength(); ++i) + { + Object oFontRef; + if (oFont.dictGetValNF(i, &oFontRef)->isRef() && oFontRef.getRef() == fontID) + { + bFindResources = true; + oFontRef.free(); + break; + } + oFontRef.free(); + } + } + oFont.free(); + } + + if (bFindResources) + { + Object oFontRef; + if (oObj.dictLookupNF("Font", &oFontRef)->isRef()) + { + if (oFontRef.fetch(xref, &oFont)->isDict()) + { + Ref r = oFontRef.getRef(); + gfxFontDict = new GfxFontDict(xref, &r, oFont.getDict()); + gfxFont = gfxFontDict->lookupByRef(fontID); + } + oFont.free(); + } + else if (oFontRef.isDict()) + { + gfxFontDict = new GfxFontDict(xref, NULL, oFontRef.getDict()); + gfxFont = gfxFontDict->lookupByRef(fontID); + } + oFontRef.free(); + } + oObj.free(); + } + + std::wstring wsFileName, wsFontName; + if (gfxFont) + GetFont(xref, m_pFontManager, m_pFontList, gfxFont, wsFileName, wsFontName); + + std::string m_sFontName = U_TO_UTF8(wsFileName); + + RELEASEOBJECT(gfxFontDict); + } + + oRes.WriteLen(); + BYTE* bRes = oRes.GetBuffer(); + oRes.ClearWithoutAttack(); + return bRes; +} BYTE* CPdfReader::VerifySign(const std::wstring& sFile, ICertificate* pCertificate, int nWidget) { if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) diff --git a/PdfFile/PdfReader.h b/PdfFile/PdfReader.h index 9618d7eebb..76c155273b 100644 --- a/PdfFile/PdfReader.h +++ b/PdfFile/PdfReader.h @@ -73,6 +73,7 @@ public: BYTE* GetStructure(); BYTE* GetLinks(int nPageIndex); BYTE* GetWidgets(); + BYTE* GetWidgetFonts(); BYTE* GetAnnots(int nPageIndex = -1); BYTE* VerifySign(const std::wstring& sFile, ICertificate* pCertificate, int nWidget = -1); BYTE* GetAPWidget (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget = -1, const char* sView = NULL, const char* sBView = NULL);