From 306a61ba140cee3cc7029e8868759e0d27d7143c Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 27 Feb 2024 12:12:56 +0300 Subject: [PATCH] Fix NSFonts::IFontList::Add --- DesktopEditor/fontengine/ApplicationFonts.cpp | 4 +- DesktopEditor/fontengine/ApplicationFonts.h | 2 +- DesktopEditor/graphics/pro/Fonts.h | 1 + .../pro/js/wasm/js/drawingfile_base.js | 6 +- PdfFile/PdfReader.cpp | 142 +++++++++--------- PdfFile/SrcReader/PdfAnnot.cpp | 45 +++++- 6 files changed, 118 insertions(+), 82 deletions(-) diff --git a/DesktopEditor/fontengine/ApplicationFonts.cpp b/DesktopEditor/fontengine/ApplicationFonts.cpp index 934ee5e2e1..3b54c8365d 100644 --- a/DesktopEditor/fontengine/ApplicationFonts.cpp +++ b/DesktopEditor/fontengine/ApplicationFonts.cpp @@ -1412,7 +1412,7 @@ void CFontList::Add(FT_Library pLibrary, FT_Parameter* pParams, const std::wstri } } -void CFontList::Add(const std::wstring& sFontPath, CFontStream* pStream, int nFlag) +void CFontList::Add(const std::wstring& sFontPath, NSFonts::IFontStream* pStream, int nFlag) { if (!pStream) return; @@ -1431,7 +1431,7 @@ void CFontList::Add(const std::wstring& sFontPath, CFontStream* pStream, int nFl pParams[3].tag = FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY; pParams[3].data = NULL; - Add(pLibrary, pParams, sFontPath, pStream, nFlag); + Add(pLibrary, pParams, sFontPath, (CFontStream*)pStream, nFlag); ::free( pParams ); FT_Done_FreeType(pLibrary); diff --git a/DesktopEditor/fontengine/ApplicationFonts.h b/DesktopEditor/fontengine/ApplicationFonts.h index 206967dfe6..2b2658451f 100644 --- a/DesktopEditor/fontengine/ApplicationFonts.h +++ b/DesktopEditor/fontengine/ApplicationFonts.h @@ -317,7 +317,7 @@ public: void LoadFromFolder (const std::wstring& strDirectory); bool CheckLoadFromFolderBin(const std::wstring& strDirectory); void CheckLoadFromSelectionBin(const std::wstring& strDirectory, BYTE* pData, DWORD len); - void Add (const std::wstring& sFontPath, CFontStream* pStream, int nFlag = 0); + void Add (const std::wstring& sFontPath, NSFonts::IFontStream* pStream, int nFlag = 0); void Add (NSFonts::CFontInfo* pInfo); NSFonts::CFontInfo* GetByParams (NSFonts::CFontSelectFormat& oSelect, bool bIsDictionaryUse = true); std::vector GetAllByName (const std::wstring& strFontName); diff --git a/DesktopEditor/graphics/pro/Fonts.h b/DesktopEditor/graphics/pro/Fonts.h index 1a06368fac..d41a82ee79 100644 --- a/DesktopEditor/graphics/pro/Fonts.h +++ b/DesktopEditor/graphics/pro/Fonts.h @@ -766,6 +766,7 @@ namespace NSFonts virtual std::vector* GetFonts() = 0; virtual CFontInfo* GetByParams(CFontSelectFormat& oSelect, bool bIsDictionaryUse = true) = 0; virtual void ToBuffer(BYTE** pDstData, LONG* pLen, CFontListToBufferSerializer& oSerializer) = 0; + virtual void Add(const std::wstring& sFontPath, IFontStream* pStream, int nFlag = 0) = 0; }; class GRAPHICS_DECL IApplicationFonts : public NSBase::CBaseRefCounter diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js index fcfc1f32e0..5f25396371 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js @@ -1126,13 +1126,13 @@ // RC if (flags & (1 << 3)) { - // 0 - left, 1 - centered, 2 - right, 3 - justify - rec["alignment"] = reader.readByte(); let n = reader.readInt(); rec["RC"] = []; for (let i = 0; i < n; ++i) { let oFont = {}; + // 0 - left, 1 - centered, 2 - right, 3 - justify + oFont["alignment"] = reader.readByte(); let nFontFlag = reader.readInt(); oFont["bold"] = (nFontFlag >> 0) & 1; oFont["italic"] = (nFontFlag >> 1) & 1; @@ -1140,6 +1140,8 @@ oFont["underlined"] = (nFontFlag >> 4) & 1; if (nFontFlag & (1 << 5)) oFont["vertical"] = reader.readDouble(); + if (nFontFlag & (1 << 6)) + oFont["actual"] = reader.readDouble(); oFont["size"] = reader.readDouble(); oFont["color"] = []; oFont["color"].push(reader.readDouble2()); diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 730fa9703b..46dafed8bf 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -926,10 +926,6 @@ BYTE* CPdfReader::GetWidgetFonts(int nTypeFonts) if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) return NULL; - AcroForm* pAcroForms = m_pPDFDocument->getCatalog()->getForm(); - if (!pAcroForms || !m_pPDFDocument->getXRef()) - return NULL; - NSWasm::CData oRes; oRes.SkipLen(); @@ -937,69 +933,55 @@ BYTE* CPdfReader::GetWidgetFonts(int nTypeFonts) int nFontsPos = oRes.GetSize(); oRes.AddInt(nFontsID); - std::vector arrFontsRef; - for (int nField = 0, nNum = pAcroForms->getNumFields(); nField < nNum; ++nField) + AcroForm* pAcroForms = m_pPDFDocument->getCatalog()->getForm(); + if (pAcroForms) { - AcroFormField* pField = pAcroForms->getField(nField); - if (!pField) - continue; - - // Шрифт и размер шрифта - из DA - Ref fontID; - double dFontSize = 0; - pField->getFont(&fontID, &dFontSize); - - if (pField->getAcroFormFieldType() == acroFormFieldPushbutton) + std::vector arrFontsRef; + for (int nField = 0, nNum = pAcroForms->getNumFields(); nField < nNum; ++nField) { - std::string sFontKey; - Object oR, oFonts, oFontRef; - if (PdfReader::GetFontFromAP(m_pPDFDocument, pField, &oR, &oFonts, &oFontRef, sFontKey) && - std::find(arrFontsRef.begin(), arrFontsRef.end(), oFontRef.getRefNum()) == arrFontsRef.end()) + AcroFormField* pField = pAcroForms->getField(nField); + if (!pField) + continue; + + // Шрифт и размер шрифта - из DA + Ref fontID; + double dFontSize = 0; + pField->getFont(&fontID, &dFontSize); + + if (pField->getAcroFormFieldType() == acroFormFieldPushbutton) { - std::string sFontName; - bool bBold = false, bItalic = false; - std::wstring wsFileName = PdfReader::GetFontData(m_pPDFDocument, m_pFontManager, m_pFontList, &oFonts, &oFontRef, nTypeFonts, sFontName, sFontName, bBold, bItalic); - - if (!sFontName.empty()) + std::string sFontKey; + Object oR, oFonts, oFontRef; + if (PdfReader::GetFontFromAP(m_pPDFDocument, pField, &oR, &oFonts, &oFontRef, sFontKey) && + std::find(arrFontsRef.begin(), arrFontsRef.end(), oFontRef.getRefNum()) == arrFontsRef.end()) { - oRes.WriteString(sFontName); - nFontsID++; - arrFontsRef.push_back(oFontRef.getRefNum()); - m_mFonts[UTF8_TO_U(sFontName)] = wsFileName; + std::string sFontName; + bool bBold = false, bItalic = false; + std::wstring wsFileName = PdfReader::GetFontData(m_pPDFDocument, m_pFontManager, m_pFontList, &oFonts, &oFontRef, nTypeFonts, sFontName, sFontName, bBold, bItalic); - if (fontID.num == oFontRef.getRefNum()) + if (!sFontName.empty()) { - oR.free(); oFonts.free(); oFontRef.free(); - continue; + oRes.WriteString(sFontName); + nFontsID++; + arrFontsRef.push_back(oFontRef.getRefNum()); + m_mFonts[UTF8_TO_U(sFontName)] = wsFileName; + + if (fontID.num == oFontRef.getRefNum()) + { + oR.free(); oFonts.free(); oFontRef.free(); + continue; + } } } + oR.free(); oFonts.free(); oFontRef.free(); } - oR.free(); oFonts.free(); oFontRef.free(); - } - if (fontID.num < 0 || std::find(arrFontsRef.begin(), arrFontsRef.end(), fontID.num) != arrFontsRef.end()) - continue; + if (fontID.num < 0 || std::find(arrFontsRef.begin(), arrFontsRef.end(), fontID.num) != arrFontsRef.end()) + continue; - Object oR, oFonts, oFontRef; - bool bFindResources = false; - if (pField->fieldLookup("DR", &oR)->isDict() && oR.dictLookup("Font", &oFonts)->isDict()) - { - for (int i = 0; i < oFonts.dictGetLength(); ++i) - { - if (oFonts.dictGetValNF(i, &oFontRef)->isRef() && oFontRef.getRef() == fontID) - { - bFindResources = true; - break; - } - oFontRef.free(); - } - } - - if (!bFindResources) - { - oR.free(); oFonts.free(); - Object* oAcroForm = pAcroForms->getAcroFormObj(); - if (oAcroForm->isDict() && oAcroForm->dictLookup("DR", &oR)->isDict() && oR.dictLookup("Font", &oFonts)->isDict()) + Object oR, oFonts, oFontRef; + bool bFindResources = false; + if (pField->fieldLookup("DR", &oR)->isDict() && oR.dictLookup("Font", &oFonts)->isDict()) { for (int i = 0; i < oFonts.dictGetLength(); ++i) { @@ -1011,24 +993,42 @@ BYTE* CPdfReader::GetWidgetFonts(int nTypeFonts) oFontRef.free(); } } - } - std::string sFontName; - std::wstring wsFileName; - if (bFindResources) - { - bool bBold = false, bItalic = false; - wsFileName = PdfReader::GetFontData(m_pPDFDocument, m_pFontManager, m_pFontList, &oFonts, &oFontRef, nTypeFonts, sFontName, sFontName, bBold, bItalic); - } + if (!bFindResources) + { + oR.free(); oFonts.free(); + Object* oAcroForm = pAcroForms->getAcroFormObj(); + if (oAcroForm->isDict() && oAcroForm->dictLookup("DR", &oR)->isDict() && oR.dictLookup("Font", &oFonts)->isDict()) + { + for (int i = 0; i < oFonts.dictGetLength(); ++i) + { + if (oFonts.dictGetValNF(i, &oFontRef)->isRef() && oFontRef.getRef() == fontID) + { + bFindResources = true; + break; + } + oFontRef.free(); + } + } + } - if (!sFontName.empty()) - { - oRes.WriteString(sFontName); - nFontsID++; - arrFontsRef.push_back(oFontRef.getRefNum()); - m_mFonts[UTF8_TO_U(sFontName)] = wsFileName; + std::string sFontName; + std::wstring wsFileName; + if (bFindResources) + { + bool bBold = false, bItalic = false; + wsFileName = PdfReader::GetFontData(m_pPDFDocument, m_pFontManager, m_pFontList, &oFonts, &oFontRef, nTypeFonts, sFontName, sFontName, bBold, bItalic); + } + + if (!sFontName.empty()) + { + oRes.WriteString(sFontName); + nFontsID++; + arrFontsRef.push_back(oFontRef.getRefNum()); + m_mFonts[UTF8_TO_U(sFontName)] = wsFileName; + } + oR.free(); oFonts.free(); oFontRef.free(); } - oR.free(); oFonts.free(); oFontRef.free(); } for (int nPage = 0, nLastPage = m_pPDFDocument->getNumPages(); nPage < nLastPage; ++nPage) diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 8deee839af..53e794b1f5 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -2255,7 +2255,21 @@ std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Objec CFontStream* pFontStream = (CFontStream*)NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Get(sFontPath); if (pFontStream && !GetBaseFont(sFontPath, pData14, nSize14)) { - pAppFontList->Add(sFontPath, pFontStream); + bool bNew = true; + std::vector* arrFontList = pAppFontList->GetFonts(); + for (int nIndex = 0; nIndex < arrFontList->size(); ++nIndex) + { + if (((*arrFontList)[nIndex]->m_wsFontPath == sFontPath || + (*arrFontList)[nIndex]->m_wsFontName == UTF8_TO_U(sFontName)) && + (*arrFontList)[nIndex]->m_bBold == bBold && + (*arrFontList)[nIndex]->m_bItalic == bItalic) + { + bNew = false; + break; + } + } + if (bNew) + pAppFontList->Add(sFontPath, pFontStream); arrFontFreeText.push_back(sFontPath); } } @@ -2270,7 +2284,8 @@ std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Objec std::string sFontName = arrRC[i]->sFontFamily; bool bBold = (bool)((arrRC[i]->unFontFlags >> 0) & 1); bool bItalic = (bool)((arrRC[i]->unFontFlags >> 1) & 1); - if (sFontName == "Courier" || sFontName == "Helvetica" || sFontName == "Symbol" || sFontName == "Times New Roman" || sFontName == "ZapfDingbats") + bool bBase = sFontName == "Courier" || sFontName == "Helvetica" || sFontName == "Symbol" || sFontName == "Times New Roman" || sFontName == "ZapfDingbats"; + if ((nTypeFonts & 2) && bBase) { if (sFontName == "Times New Roman") { @@ -2301,6 +2316,7 @@ std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Objec std::string sFontNameBefore = arrRC[i]->sFontFamily; arrRC[i]->sFontFamily = sFontName; arrRC[i]->bFind = true; + mRes[wsFontName] = wsFontName; for (int j = i; j < arrRC.size(); ++j) { @@ -2311,7 +2327,7 @@ std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Objec } } } - else + if ((nTypeFonts & 1) && !bBase) { NSFonts::CFontSelectFormat oFontSelect; if (bBold) @@ -2324,15 +2340,32 @@ std::map CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Objec if (pFontInfo && !pFontInfo->m_wsFontPath.empty()) { bool bFreeText = std::find(arrFontFreeText.begin(), arrFontFreeText.end(), pFontInfo->m_wsFontPath) != arrFontFreeText.end(); + std::wstring wsFontBaseName = pFontInfo->m_wsFontName; + if (wsFontBaseName.length() > 7 && wsFontBaseName.at(6) == '+') + { + bool bIsRemove = true; + for (int nIndex = 0; nIndex < 6; nIndex++) + { + wchar_t nChar = wsFontBaseName.at(nIndex); + if (nChar < 'A' || nChar > 'Z') + { + bIsRemove = false; + break; + } + } + if (bIsRemove) + wsFontBaseName.erase(0, 7); + } + if (bFreeText) { - arrRC[i]->sFontFamily = U_TO_UTF8(pFontInfo->m_wsFontName); - mRes[pFontInfo->m_wsFontName] = pFontInfo->m_wsFontPath; + arrRC[i]->sFontFamily = U_TO_UTF8(wsFontBaseName); + mRes[wsFontBaseName] = pFontInfo->m_wsFontPath; } else { arrRC[i]->unFontFlags |= (1 << 6); - arrRC[i]->sActualFont = U_TO_UTF8(pFontInfo->m_wsFontName); + arrRC[i]->sActualFont = U_TO_UTF8(wsFontBaseName); } arrRC[i]->bFind = true;