diff --git a/DesktopEditor/graphics/pro/js/drawingfile.json b/DesktopEditor/graphics/pro/js/drawingfile.json index 27ce31a7d2..ddb71f55e3 100644 --- a/DesktopEditor/graphics/pro/js/drawingfile.json +++ b/DesktopEditor/graphics/pro/js/drawingfile.json @@ -197,7 +197,7 @@ }, { "folder": "../../../../PdfFile/SrcReader/", - "files": ["Adaptors.cpp", "GfxClip.cpp", "RendererOutputDev.cpp", "JPXStream2.cpp", "PdfAnnot.cpp"] + "files": ["Adaptors.cpp", "GfxClip.cpp", "RendererOutputDev.cpp", "JPXStream2.cpp", "PdfAnnot.cpp", "PdfFont.cpp"] }, { "folder": "../../../../PdfFile/SrcWriter/", diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp index e2299c965b..5ac5ff212f 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -2252,8 +2252,9 @@ int main(int argc, char* argv[]) } // SCAN PAGE Fonts - if (false) + if (true) { + //ScanPage(pGrFile, nTestPage, 2); SetScanPageFonts(pGrFile, nTestPage); ReadInteractiveFormsFonts(pGrFile, 1); diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 1cdc842755..127ba565fa 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -959,9 +959,9 @@ BYTE* CPdfReader::GetGIDByUnicode(const std::wstring& wsFontName) std::map mGIDbyUnicode; bool bFind = false; - for (CPdfReaderContext* pPDFContext : m_vPDFContext) + for (int nPDF = 0; nPDF < m_vPDFContext.size(); ++nPDF) { - PdfReader::CPdfFontList* pFontList = pPDFContext->m_pFontList; + PdfReader::CPdfFontList* pFontList = m_vPDFContext[nPDF]->m_pFontList; const std::map& mapFonts = pFontList->GetFonts(); for (std::map::const_iterator it = mapFonts.begin(); it != mapFonts.end(); ++it) @@ -970,15 +970,18 @@ BYTE* CPdfReader::GetGIDByUnicode(const std::wstring& wsFontName) if (!pEntry || pEntry->wsFilePath != oIter->second) continue; bFind = true; - for (int i = 0; i < pEntry->unLenUnicode; ++i) { - if (pEntry->pCodeToUnicode[i]) + if (pEntry->pCodeToUnicode && pEntry->pCodeToUnicode[i]) { unsigned int unGID = i; if (pEntry->pCodeToGID[i]) + { unGID = pEntry->pCodeToGID[i]; - mGIDbyUnicode[unGID] = pEntry->pCodeToUnicode[i]; + mGIDbyUnicode[unGID] = pEntry->pCodeToUnicode[i]; + } + else if (pEntry->bIsIdentity) + mGIDbyUnicode.insert(std::make_pair(unGID, pEntry->pCodeToUnicode[i])); } } diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 25afae7790..67e447eb90 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -3279,8 +3279,8 @@ void CAnnotAP::Init(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFon m_gfx = new Gfx(pdfDoc, m_pRendererOut, nPageIndex, pPage->getAttrs()->getResourceDict(), 72.0, 72.0, &box, crop ? cropBox : (PDFRectangle *)NULL, 0, NULL, NULL); // Координаты внешнего вида - m_dRx1 = (m_dx1 - m_dCropX) * m_dWScale - 1; - m_dRy1 = (pdfDoc->getPageCropHeight(nPageIndex) - m_dy2 + m_dCropY) * m_dHScale - 1; + m_dRx1 = ((m_bIsStamp ? m_dx1S: m_dx1) - m_dCropX) * m_dWScale - 1; + m_dRy1 = (pdfDoc->getPageCropHeight(nPageIndex) - (m_bIsStamp ? m_dy2S : m_dy2) + m_dCropY) * m_dHScale - 1; } void CAnnotAP::Init(Object* oAnnot) { @@ -3294,6 +3294,8 @@ void CAnnotAP::Init(Object* oAnnot) if (m_bIsStamp) { + m_dx1S = m_dx1; + m_dy2S = m_dy2; double m[6] = { 1, 0, 0, 1, 0, 0 }, bbox[4] = { m_dx1, m_dy1, m_dx2, m_dy2 }; oObj.free(); diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index dbcc6cf2a0..5275e3b1d9 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -147,6 +147,7 @@ private: double m_dRWScale, m_dRHScale; double m_dWTale, m_dHTale; double m_dRx1, m_dRy1; + double m_dx1S, m_dy2S; int m_nWidth, m_nHeight; std::vector m_arrAP; bool m_bIsStamp; diff --git a/PdfFile/SrcReader/PdfFont.cpp b/PdfFile/SrcReader/PdfFont.cpp index a840943a91..8689e9e51b 100644 --- a/PdfFile/SrcReader/PdfFont.cpp +++ b/PdfFile/SrcReader/PdfFont.cpp @@ -194,6 +194,30 @@ bool scanAPfonts(Object* oAnnot, const std::vector& arrCMap, std::v oAP.free(); return bRes; } +bool CheckFontNameStyle(std::wstring& sName, const std::wstring& sStyle) +{ + size_t nPos = 0; + size_t nLenReplace = sStyle.length(); + bool bRet = false; + + std::wstring sName2 = sName; + NSStringExt::ToLower(sName2); + + while (std::wstring::npos != (nPos = sName2.find(sStyle, nPos))) + { + size_t nOffset = 0; + if ((nPos > 0) && (sName2.at(nPos - 1) == '-' || sName2.at(nPos - 1) == ',')) + { + --nPos; + ++nOffset; + } + + bRet = true; + sName.erase(nPos, nLenReplace + nOffset); + sName2.erase(nPos, nLenReplace + nOffset); + } + return bRet; +} namespace PdfReader { @@ -537,7 +561,7 @@ std::wstring GetFontData(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CP RendererOutputDev::GetFont(xref, pFontManager, pFontList, gfxFont, wsFileName, wsFontName); sFontName = U_TO_UTF8(wsFontName); - RendererOutputDev::CheckFontStylePDF(wsFontName, bBold, bItalic); + CheckFontStylePDF(wsFontName, bBold, bItalic); if (!bBold) bBold = gfxFont->isBold(); if (!bItalic) @@ -549,21 +573,7 @@ std::wstring GetFontData(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CP NSFonts::CFontInfo* pFontInfo = RendererOutputDev::GetFontByParams(xref, pFontManager, gfxFont, wsFBN); if (pFontInfo && !pFontInfo->m_wsFontPath.empty()) { - 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); - } + EraseSubsetTag(wsFontBaseName); wsFileName = pFontInfo->m_wsFontPath; sFontName = U_TO_UTF8(wsFontBaseName); @@ -841,21 +851,7 @@ std::map GetFreeTextFont(PDFDoc* pdfDoc, NSFonts::IF } } 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); - } + EraseSubsetTag(wsFontBaseName); if (bFindFreeText) { @@ -1001,4 +997,58 @@ void CollectFontWidths(GfxFont* gfxFont, Dict* pFontDict, std::map 7 && sFontName.at(6) == '+') + { + bIsRemove = true; + for (int nIndex = 0; nIndex < 6; nIndex++) + { + wchar_t nChar = sFontName.at(nIndex); + if (nChar < 'A' || nChar > 'Z') + { + bIsRemove = false; + break; + } + } + if (bIsRemove) + sFontName.erase(0, 7); + } + return bIsRemove; +} } diff --git a/PdfFile/SrcReader/PdfFont.h b/PdfFile/SrcReader/PdfFont.h index e584f1de56..ab5b6c8cd0 100644 --- a/PdfFile/SrcReader/PdfFont.h +++ b/PdfFile/SrcReader/PdfFont.h @@ -56,6 +56,8 @@ std::map GetAnnotFont(PDFDoc* pdfDoc, NSFonts::IFont std::map GetFreeTextFont(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, Object* oAnnotRef, std::vector& arrRC); bool FindFonts(Object* oStream, int nDepth, Object* oResFonts); void CollectFontWidths(GfxFont* gfxFont, Dict* pFontDict, std::map& mGIDToWidth); +void CheckFontStylePDF(std::wstring& sName, bool& bBold, bool& bItalic); +bool EraseSubsetTag(std::wstring& sFontName); } #endif // _PDF_READER_FONT_H diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 878e8bbc23..81df1bbf18 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -64,6 +64,7 @@ #else #include "../../DesktopEditor/graphics/pro/js/wasm/src/serialize.h" #include "FontsWasm.h" +#include "PdfFont.h" #define FONTS_USE_ONLY_MEMORY_STREAMS #endif @@ -75,88 +76,12 @@ namespace PdfReader { - bool CheckFontNameStyle(std::wstring& sName, const std::wstring& sStyle) - { - size_t nPos = 0; - size_t nLenReplace = sStyle.length(); - bool bRet = false; - - std::wstring sName2 = sName; - NSStringExt::ToLower(sName2); - - while (std::wstring::npos != (nPos = sName2.find(sStyle, nPos))) - { - size_t nOffset = 0; - if ((nPos > 0) && (sName2.at(nPos - 1) == '-' || sName2.at(nPos - 1) == ',')) - { - --nPos; - ++nOffset; - } - - bRet = true; - sName.erase(nPos, nLenReplace + nOffset); - sName2.erase(nPos, nLenReplace + nOffset); - } - return bRet; - } - - void RendererOutputDev::CheckFontStylePDF(std::wstring& sName, bool& bBold, bool& bItalic) - { - if (sName.length() > 7 && sName.at(6) == '+') - { - bool bIsRemove = true; - for (int nIndex = 0; nIndex < 6; nIndex++) - { - wchar_t nChar = sName.at(nIndex); - if (nChar < 'A' || nChar > 'Z') - { - bIsRemove = false; - break; - } - } - if (bIsRemove) - { - sName.erase(0, 7); - } - } - - CheckFontNameStyle(sName, L"condensedbold"); - CheckFontNameStyle(sName, L"semibold"); - CheckFontNameStyle(sName, L"regular"); - - CheckFontNameStyle(sName, L"ultraexpanded"); - CheckFontNameStyle(sName, L"extraexpanded"); - CheckFontNameStyle(sName, L"semiexpanded"); - CheckFontNameStyle(sName, L"expanded"); - - CheckFontNameStyle(sName, L"ultracondensed"); - CheckFontNameStyle(sName, L"extracondensed"); - CheckFontNameStyle(sName, L"semicondensed"); - CheckFontNameStyle(sName, L"condensedlight"); - CheckFontNameStyle(sName, L"condensed"); - //CheckFontNameStyle(sName, L"light"); - - if (CheckFontNameStyle(sName, L"bold_italic")) { bBold = true; bItalic = true; } - if (CheckFontNameStyle(sName, L"bold_oblique")) { bBold = true; bItalic = true; } - - if (CheckFontNameStyle(sName, L"boldmt")) bBold = true; - if (CheckFontNameStyle(sName, L"bold")) bBold = true; - - if (CheckFontNameStyle(sName, L"italicmt")) bItalic = true; - if (CheckFontNameStyle(sName, L"italic")) bItalic = true; - if (CheckFontNameStyle(sName, L"oblique")) bItalic = true; - - //if (CheckFontNameStyle(sName, L"bolditalicmt")) { bBold = true; bItalic = true; } - //if (CheckFontNameStyle(sName, L"bolditalic")) { bBold = true; bItalic = true; } - //if (CheckFontNameStyle(sName, L"boldoblique")) { bBold = true; bItalic = true; } - } - void CheckFontNamePDF(std::wstring& sName, NSFonts::CFontSelectFormat* format) { bool bBold = false; bool bItalic = false; - RendererOutputDev::CheckFontStylePDF(sName, bBold, bItalic); + CheckFontStylePDF(sName, bBold, bItalic); if (format) { @@ -1534,30 +1459,7 @@ namespace PdfReader // Обрежем индекс у FontName, если он есть if (wsFontName.empty()) wsFontName = wsFontBaseName; - if (wsFontName.length() > 7) - { - bool bIsIndex = true; - if ('+' != wsFontName.at(6)) - bIsIndex = false; - - if (bIsIndex) - { - for (int nIndex = 0; nIndex < 6; nIndex++) - { - int nChar = wsFontName.at(nIndex); - if (nChar < 'A' || nChar > 'Z') - { - bIsIndex = false; - break; - } - } - } - - if (bIsIndex) - { - wsFontName.erase(0, 7); - } - } + EraseSubsetTag(wsFontName); pEntry->wsFilePath = wsFileName; pEntry->wsFontName = wsFontName; @@ -1567,6 +1469,7 @@ namespace PdfReader pEntry->unLenUnicode = (unsigned int)nToUnicodeLen; pEntry->bAvailable = true; pEntry->bFontSubstitution = bFontSubstitution; + pEntry->bIsIdentity = pFont->isCIDFont() == gTrue ? ((GfxCIDFont*)pFont)->usesIdentityEncoding() || ((GfxCIDFont*)pFont)->usesIdentityCIDToGID() || ((GfxCIDFont*)pFont)->ctuUsesCharCodeToUnicode() || pFont->getType() == fontCIDType0C : false; } else if (NULL != pEntry) { @@ -2471,8 +2374,6 @@ namespace PdfReader std::wstring wsUnicodeText; bool isCIDFont = pFont->isCIDFont() == gTrue; - bool isIdentity = isCIDFont ? ((GfxCIDFont*)pFont)->usesIdentityEncoding() || ((GfxCIDFont*)pFont)->usesIdentityCIDToGID() || ((GfxCIDFont*)pFont)->ctuUsesCharCodeToUnicode() || pFont->getType() == fontCIDType0C : false; - if (NULL != oEntry.pCodeToUnicode && nCode < oEntry.unLenUnicode && oEntry.pCodeToUnicode[nCode]) { int unUnicode = oEntry.pCodeToUnicode[nCode]; @@ -2502,12 +2403,12 @@ namespace PdfReader unGid = oEntry.pCodeToGID[nCode]; unGidsCount = 1; - if (pFont->getType() == fontCIDType0COT && isCIDFont && isIdentity && oEntry.pCodeToUnicode && nCode < oEntry.unLenUnicode && !oEntry.pCodeToUnicode[nCode]) + if (pFont->getType() == fontCIDType0COT && isCIDFont && oEntry.bIsIdentity && oEntry.pCodeToUnicode && nCode < oEntry.unLenUnicode && !oEntry.pCodeToUnicode[nCode]) unGid = nCode; } else { - if ((isCIDFont && isIdentity) || (!isCIDFont && wsUnicodeText.empty())) + if ((isCIDFont && oEntry.bIsIdentity) || (!isCIDFont && wsUnicodeText.empty())) { unsigned int nCurCode = (0 == nCode ? 65534 : nCode); unGid = nCurCode; diff --git a/PdfFile/SrcReader/RendererOutputDev.h b/PdfFile/SrcReader/RendererOutputDev.h index 40854bb46d..8a2d9a7f69 100644 --- a/PdfFile/SrcReader/RendererOutputDev.h +++ b/PdfFile/SrcReader/RendererOutputDev.h @@ -56,6 +56,7 @@ namespace PdfReader unsigned int unLenUnicode; bool bAvailable; // Доступен ли шрифт. Сделано для многопотоковости bool bFontSubstitution = false; + bool bIsIdentity = false; }; @@ -245,7 +246,6 @@ namespace PdfReader } static NSFonts::CFontInfo* GetFontByParams(XRef* pXref, NSFonts::IFontManager* pFontManager, GfxFont* pFont, std::wstring& wsFontBaseName); static void GetFont(XRef* pXref, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, GfxFont* pFont, std::wstring& wsFileName, std::wstring& wsFontName); - static void CheckFontStylePDF(std::wstring& sName, bool& bBold, bool& bItalic); private: struct GfxOutputState