mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-07-11 01:11:43 +08:00
All fonts to PdfFont
This commit is contained in:
@ -4515,7 +4515,7 @@ void CPdfEditor::ScanAndProcessFonts(PDFDoc* pPDFDocument, XRef* xref, Dict* pRe
|
||||
if (gfxFont->getEmbeddedFontID(&oEmbRef) || PdfReader::IsBaseFont(wsFontBaseName) || ((pFontLoc = gfxFont->locateFont(xref, false)) && NSStrings::GetStringFromUTF32(pFontLoc->path).length()))
|
||||
{
|
||||
std::wstring wsFileName, wsFontName;
|
||||
PdfReader::RendererOutputDev::GetFont(xref, pFontManager, pFontList, gfxFont, wsFileName, wsFontName, false);
|
||||
PdfReader::GetFont(xref, pFontManager, pFontList, gfxFont, wsFileName, wsFontName, false);
|
||||
|
||||
// Collect information about embedded font
|
||||
if (!PdfReader::IsBaseFont(wsFontBaseName))
|
||||
@ -4533,7 +4533,7 @@ void CPdfEditor::ScanAndProcessFonts(PDFDoc* pPDFDocument, XRef* xref, Dict* pRe
|
||||
else
|
||||
{
|
||||
std::map<unsigned int, unsigned int> mCodeToWidth, mCodeToUnicode, mCodeToGID;
|
||||
int nDW = PdfReader::CollectFontWidths(gfxFont, oFont.getDict(), mCodeToWidth);
|
||||
int nDW = PdfReader::CollectFontWidths(oFont.getDict(), mCodeToWidth);
|
||||
for (int nIndex = 0; nIndex < pFontEntry.unLenUnicode; ++nIndex)
|
||||
{
|
||||
if (pFontEntry.pCodeToUnicode[nIndex])
|
||||
|
||||
@ -40,7 +40,6 @@
|
||||
#include "../DesktopEditor/graphics/IRenderer.h"
|
||||
#include "../DesktopEditor/common/Directory.h"
|
||||
#include "../DesktopEditor/common/StringExt.h"
|
||||
#include "../DesktopEditor/graphics/pro/js/wasm/src/serialize.h"
|
||||
#include "../DesktopEditor/graphics/MetafileToRenderer.h"
|
||||
#include "../DesktopEditor/graphics/BaseThread.h"
|
||||
|
||||
@ -190,7 +189,7 @@ void CPdfReader::SetCMapMemory(BYTE* pData, DWORD nSizeData)
|
||||
if (m_vPDFContext.empty())
|
||||
return;
|
||||
CPdfReaderContext* pPDFContext = m_vPDFContext.back();
|
||||
std::map<std::wstring, std::wstring> mFonts = PdfReader::GetAllFonts(pPDFContext->m_pDocument, m_pFontManager, pPDFContext->m_pFontList, false);
|
||||
std::map<std::wstring, std::wstring> mFonts = PdfReader::GetAllFonts(pPDFContext->m_pDocument, m_pFontManager, pPDFContext->m_pFontList);
|
||||
m_mFonts.insert(mFonts.begin(), mFonts.end());
|
||||
}
|
||||
void CPdfReader::SetCMapFolder(const std::wstring& sFolder)
|
||||
@ -252,17 +251,34 @@ void CPdfReader::SetParams(COfficeDrawingPageParams* pParams)
|
||||
globalParams->setDrawAnnotations(bDraw);
|
||||
}
|
||||
|
||||
int CPdfReader::GetStartRefID(PDFDoc* _pDoc)
|
||||
// ============================================================
|
||||
// CPdfReader::FindContext
|
||||
// ============================================================
|
||||
CPdfReaderContext* CPdfReader::FindContext(PDFDoc* _pDoc) const
|
||||
{
|
||||
for (CPdfReaderContext* pPDFContext : m_vPDFContext)
|
||||
{
|
||||
if (!pPDFContext || !pPDFContext->m_pDocument)
|
||||
continue;
|
||||
PDFDoc* pDoc = pPDFContext->m_pDocument;
|
||||
if (_pDoc == pDoc)
|
||||
return pPDFContext->m_nStartID;
|
||||
if (pPDFContext->m_pDocument == _pDoc)
|
||||
return pPDFContext;
|
||||
}
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
int CPdfReader::GetStartRefID(PDFDoc* _pDoc)
|
||||
{
|
||||
CPdfReaderContext* pContext = FindContext(_pDoc);
|
||||
return pContext ? pContext->m_nStartID : -1;
|
||||
}
|
||||
PdfReader::CPdfFontList* CPdfReader::GetFontList(PDFDoc* _pDoc)
|
||||
{
|
||||
CPdfReaderContext* pContext = FindContext(_pDoc);
|
||||
return pContext ? pContext->m_pFontList : NULL;
|
||||
}
|
||||
std::string CPdfReader::GetPrefixForm(PDFDoc* _pDoc)
|
||||
{
|
||||
CPdfReaderContext* pContext = FindContext(_pDoc);
|
||||
return pContext ? pContext->m_sPrefixForm : "";
|
||||
}
|
||||
int CPdfReader::GetNumPagesBefore(PDFDoc* _pDoc)
|
||||
{
|
||||
@ -271,37 +287,12 @@ int CPdfReader::GetNumPagesBefore(PDFDoc* _pDoc)
|
||||
{
|
||||
if (!pPDFContext || !pPDFContext->m_pDocument)
|
||||
continue;
|
||||
PDFDoc* pDoc = pPDFContext->m_pDocument;
|
||||
if (_pDoc == pDoc)
|
||||
if (pPDFContext->m_pDocument == _pDoc)
|
||||
return nPagesBefore;
|
||||
nPagesBefore += pDoc->getNumPages();
|
||||
nPagesBefore += pPDFContext->m_pDocument->getNumPages();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
PdfReader::CPdfFontList* CPdfReader::GetFontList(PDFDoc* _pDoc)
|
||||
{
|
||||
for (CPdfReaderContext* pPDFContext : m_vPDFContext)
|
||||
{
|
||||
if (!pPDFContext || !pPDFContext->m_pDocument)
|
||||
continue;
|
||||
PDFDoc* pDoc = pPDFContext->m_pDocument;
|
||||
if (_pDoc == pDoc)
|
||||
return pPDFContext->m_pFontList;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
std::string CPdfReader::GetPrefixForm(PDFDoc* _pDoc)
|
||||
{
|
||||
for (CPdfReaderContext* pPDFContext : m_vPDFContext)
|
||||
{
|
||||
if (!pPDFContext || !pPDFContext->m_pDocument)
|
||||
continue;
|
||||
PDFDoc* pDoc = pPDFContext->m_pDocument;
|
||||
if (_pDoc == pDoc)
|
||||
return pPDFContext->m_sPrefixForm;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
int CPdfReader::FindRefNum(int nObjID, PDFDoc** _pDoc, int* _nStartRefID)
|
||||
{
|
||||
for (CPdfReaderContext* pPDFContext : m_vPDFContext)
|
||||
@ -311,10 +302,8 @@ int CPdfReader::FindRefNum(int nObjID, PDFDoc** _pDoc, int* _nStartRefID)
|
||||
PDFDoc* pDoc = pPDFContext->m_pDocument;
|
||||
if (nObjID < pPDFContext->m_nStartID + pDoc->getXRef()->getNumObjects())
|
||||
{
|
||||
if (_pDoc)
|
||||
*_pDoc = pDoc;
|
||||
if (_nStartRefID)
|
||||
*_nStartRefID = pPDFContext->m_nStartID;
|
||||
if (_pDoc) *_pDoc = pDoc;
|
||||
if (_nStartRefID) *_nStartRefID = pPDFContext->m_nStartID;
|
||||
return nObjID - pPDFContext->m_nStartID;
|
||||
}
|
||||
}
|
||||
@ -328,22 +317,19 @@ int CPdfReader::GetPageIndex(int nAbsPageIndex, PDFDoc** _pDoc, PdfReader::CPdfF
|
||||
if (!pPDFContext || !pPDFContext->m_pDocument)
|
||||
continue;
|
||||
PDFDoc* pDoc = pPDFContext->m_pDocument;
|
||||
|
||||
int nPages = pDoc->getNumPages();
|
||||
if (nAbsPageIndex < nTotalPages + nPages)
|
||||
{
|
||||
if (_pDoc)
|
||||
*_pDoc = pDoc;
|
||||
if (pFontList)
|
||||
*pFontList = pPDFContext->m_pFontList;
|
||||
if (nStartRefID)
|
||||
*nStartRefID = pPDFContext->m_nStartID;
|
||||
if (_pDoc) *_pDoc = pDoc;
|
||||
if (pFontList) *pFontList = pPDFContext->m_pFontList;
|
||||
if (nStartRefID) *nStartRefID = pPDFContext->m_nStartID;
|
||||
return nAbsPageIndex - nTotalPages + 1;
|
||||
}
|
||||
nTotalPages += nPages;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CPdfReader::GetError()
|
||||
{
|
||||
if (m_vPDFContext.empty())
|
||||
@ -412,6 +398,64 @@ int CPdfReader::GetNumPages()
|
||||
}
|
||||
return nNumPages;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// CPdfReader::ValidMetaData
|
||||
// ============================================================
|
||||
bool ValidateXRefTable(BaseStream* str, GFileOffset nOffset, GString* pID2)
|
||||
{
|
||||
Object oDict, oTID, oID, obj1;
|
||||
char buf[100];
|
||||
|
||||
Stream* pSubStr = str->makeSubStream(nOffset + 5, gFalse, 0, &oDict);
|
||||
int c = pSubStr->getChar();
|
||||
while (c != 't')
|
||||
c = pSubStr->getChar();
|
||||
pSubStr->getBlock(buf, 6);
|
||||
|
||||
Parser* parser = new Parser(NULL, new Lexer(NULL, pSubStr->getBaseStream()->makeSubStream(pSubStr->getPos(), gFalse, 0, &oDict)), gTrue);
|
||||
parser->getObj(&obj1);
|
||||
delete parser;
|
||||
delete pSubStr;
|
||||
|
||||
bool bRes = false;
|
||||
if (obj1.isDict() && obj1.dictLookup("ID", &oTID)->isArray() && oTID.arrayGet(1, &oID)->isString())
|
||||
bRes = pID2->cmp(oID.getString()) != 0;
|
||||
|
||||
obj1.free();
|
||||
oTID.free();
|
||||
oID.free();
|
||||
return bRes;
|
||||
}
|
||||
bool ValidateXRefStream(BaseStream* str, GFileOffset nOffset, GString* pID2)
|
||||
{
|
||||
Object oDict, oTID, oID, obj1, obj2, obj3, obj4;
|
||||
|
||||
Stream* pSubStr = str->makeSubStream(nOffset, gFalse, 0, &oDict);
|
||||
Parser* parser = new Parser(NULL, new Lexer(NULL, pSubStr), gTrue);
|
||||
parser->getObj(&obj1);
|
||||
parser->getObj(&obj2);
|
||||
parser->getObj(&obj3);
|
||||
parser->getObj(&obj4);
|
||||
|
||||
bool bRes = false;
|
||||
if (obj1.isInt() && obj2.isInt() && obj3.isCmd("obj") && obj4.isStream())
|
||||
{
|
||||
Dict* pPrevXRefDict = obj4.streamGetDict();
|
||||
if (pPrevXRefDict->lookup("ID", &oTID)->isArray() && oTID.arrayGet(1, &oID)->isString())
|
||||
bRes = pID2->cmp(oID.getString()) != 0;
|
||||
oTID.free();
|
||||
oID.free();
|
||||
}
|
||||
|
||||
obj4.free();
|
||||
obj3.free();
|
||||
obj2.free();
|
||||
obj1.free();
|
||||
delete parser;
|
||||
|
||||
return bRes;
|
||||
}
|
||||
bool CPdfReader::ValidMetaData()
|
||||
{
|
||||
if (m_vPDFContext.empty() || m_vPDFContext.size() != 1)
|
||||
@ -445,9 +489,9 @@ bool CPdfReader::ValidMetaData()
|
||||
int nNumXRefTables = xref->getNumXRefTables();
|
||||
if (bRes && nNumXRefTables > 1)
|
||||
{
|
||||
GFileOffset nOffeset = xref->getXRefTablePos(nNumXRefTables - 2);
|
||||
GFileOffset nOffset = xref->getXRefTablePos(nNumXRefTables - 2);
|
||||
BaseStream* str = pPDFContext->m_pDocument->getBaseStream();
|
||||
str->setPos(nOffeset);
|
||||
str->setPos(nOffset);
|
||||
Object oDict, obj1, obj2, obj3, obj4;
|
||||
char buf[100];
|
||||
|
||||
@ -455,52 +499,58 @@ bool CPdfReader::ValidMetaData()
|
||||
for (i = 0; i < n && Lexer::isSpace(buf[i]); ++i);
|
||||
// xref table
|
||||
if (i + 4 < n && buf[i] == 'x' && buf[i+1] == 'r' && buf[i+2] == 'e' && buf[i+3] == 'f' && Lexer::isSpace(buf[i+4]))
|
||||
{
|
||||
Stream* pSubStr = str->makeSubStream(nOffeset + i + 5, gFalse, 0, &oDict);
|
||||
int c = pSubStr->getChar();
|
||||
while (c != 't')
|
||||
c = pSubStr->getChar();
|
||||
pSubStr->getBlock(buf, 6);
|
||||
|
||||
Parser* parser = new Parser(NULL, new Lexer(NULL, pSubStr->getBaseStream()->makeSubStream(pSubStr->getPos(), gFalse, 0, &oDict)), gTrue);
|
||||
parser->getObj(&obj1);
|
||||
delete parser;
|
||||
delete pSubStr;
|
||||
if (obj1.isDict() && obj1.dictLookup("ID", &oTID)->isArray() && oTID.arrayGet(1, &oID)->isString())
|
||||
{
|
||||
bRes = oID2.getString()->cmp(oID.getString()) != 0;
|
||||
}
|
||||
obj1.free();
|
||||
oTID.free();
|
||||
}
|
||||
else // xref stream
|
||||
{
|
||||
Stream* pSubStr = str->makeSubStream(nOffeset, gFalse, 0, &oDict);
|
||||
Parser* parser = new Parser(NULL, new Lexer(NULL, pSubStr), gTrue);
|
||||
parser->getObj(&obj1);
|
||||
parser->getObj(&obj2);
|
||||
parser->getObj(&obj3);
|
||||
parser->getObj(&obj4);
|
||||
if (obj1.isInt() && obj2.isInt() && obj3.isCmd("obj") && obj4.isStream())
|
||||
{
|
||||
Dict* pPrevXRefDict = obj4.streamGetDict();
|
||||
if (pPrevXRefDict->lookup("ID", &oTID)->isArray() && oTID.arrayGet(1, &oID)->isString())
|
||||
{
|
||||
bRes = oID2.getString()->cmp(oID.getString()) != 0;
|
||||
}
|
||||
oTID.free();
|
||||
}
|
||||
obj4.free();
|
||||
obj3.free();
|
||||
obj2.free();
|
||||
obj1.free();
|
||||
delete parser;
|
||||
}
|
||||
bRes = ValidateXRefTable(str, nOffset + i + 5, oID2.getString());
|
||||
else
|
||||
bRes = ValidateXRefStream(str, nOffset, oID2.getString());
|
||||
}
|
||||
oID2.free(); oID.free();
|
||||
|
||||
return bRes;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// CPdfReader::MergePages
|
||||
// ============================================================
|
||||
void CreatePasswords(const wchar_t* wsPassword, GString*& owner_pswd, GString*& user_pswd)
|
||||
{
|
||||
owner_pswd = NULL;
|
||||
user_pswd = NULL;
|
||||
if (wsPassword)
|
||||
{
|
||||
owner_pswd = NSStrings::CreateString(wsPassword);
|
||||
user_pswd = NSStrings::CreateString(wsPassword);
|
||||
}
|
||||
}
|
||||
CPdfReaderContext* CPdfReader::CreateContext(const std::string& sPrefixForm, int nMaxID)
|
||||
{
|
||||
CPdfReaderContext* pContext = new CPdfReaderContext();
|
||||
pContext->m_pFontList = new PdfReader::CPdfFontList();
|
||||
pContext->m_sPrefixForm = sPrefixForm;
|
||||
if (nMaxID != 0)
|
||||
pContext->m_nStartID = nMaxID;
|
||||
else if (!m_vPDFContext.empty())
|
||||
pContext->m_nStartID = m_vPDFContext.back()->m_nStartID + m_vPDFContext.back()->m_pDocument->getXRef()->getNumObjects();
|
||||
return pContext;
|
||||
}
|
||||
bool CPdfReader::FinalizeMerge(CPdfReaderContext* pContext)
|
||||
{
|
||||
PDFDoc* pDoc = pContext->m_pDocument;
|
||||
m_vPDFContext.push_back(pContext);
|
||||
|
||||
m_eError = pDoc ? pDoc->getErrorCode() : errMemory;
|
||||
if (!pDoc || !pDoc->isOk())
|
||||
{
|
||||
delete pContext;
|
||||
m_vPDFContext.pop_back();
|
||||
return false;
|
||||
}
|
||||
|
||||
IsNeedCMap();
|
||||
std::map<std::wstring, std::wstring> mFonts = PdfReader::GetAllFonts(pDoc, m_pFontManager, pContext->m_pFontList);
|
||||
m_mFonts.insert(mFonts.begin(), mFonts.end());
|
||||
|
||||
return true;
|
||||
}
|
||||
bool CPdfReader::MergePages(BYTE* pData, DWORD nLength, const wchar_t* wsPassword, int nMaxID, const std::string& sPrefixForm)
|
||||
{
|
||||
if (m_eError)
|
||||
@ -530,25 +580,11 @@ bool CPdfReader::MergePages(BYTE* pData, DWORD nLength, const wchar_t* wsPasswor
|
||||
pContext->m_nStartID = nMaxID;
|
||||
else if (!m_vPDFContext.empty())
|
||||
pContext->m_nStartID = m_vPDFContext.back()->m_nStartID + m_vPDFContext.back()->m_pDocument->getXRef()->getNumObjects();
|
||||
PDFDoc* pDoc = pContext->m_pDocument;
|
||||
m_vPDFContext.push_back(pContext);
|
||||
|
||||
RELEASEOBJECT(owner_pswd);
|
||||
RELEASEOBJECT(user_pswd);
|
||||
|
||||
m_eError = pDoc ? pDoc->getErrorCode() : errMemory;
|
||||
if (!pDoc || !pDoc->isOk())
|
||||
{
|
||||
// pData is freed
|
||||
delete pContext;
|
||||
m_vPDFContext.pop_back();
|
||||
return false;
|
||||
}
|
||||
|
||||
std::map<std::wstring, std::wstring> mFonts = PdfReader::GetAllFonts(pDoc, m_pFontManager, pContext->m_pFontList, IsNeedCMap());
|
||||
m_mFonts.insert(mFonts.begin(), mFonts.end());
|
||||
|
||||
return true;
|
||||
return FinalizeMerge(pContext);
|
||||
}
|
||||
bool CPdfReader::MergePages(const std::wstring& wsFile, const wchar_t* wsPassword, int nMaxID, const std::string& sPrefixForm)
|
||||
{
|
||||
@ -574,25 +610,13 @@ bool CPdfReader::MergePages(const std::wstring& wsFile, const wchar_t* wsPasswor
|
||||
pContext->m_nStartID = nMaxID;
|
||||
else if (!m_vPDFContext.empty())
|
||||
pContext->m_nStartID = m_vPDFContext.back()->m_nStartID + m_vPDFContext.back()->m_pDocument->getXRef()->getNumObjects();
|
||||
PDFDoc* pDoc = pContext->m_pDocument;
|
||||
m_vPDFContext.push_back(pContext);
|
||||
|
||||
RELEASEOBJECT(owner_pswd);
|
||||
RELEASEOBJECT(user_pswd);
|
||||
|
||||
m_eError = pDoc ? pDoc->getErrorCode() : errMemory;
|
||||
if (!pDoc || !pDoc->isOk())
|
||||
{
|
||||
delete pContext;
|
||||
m_vPDFContext.pop_back();
|
||||
return false;
|
||||
}
|
||||
|
||||
std::map<std::wstring, std::wstring> mFonts = PdfReader::GetAllFonts(pDoc, m_pFontManager, pContext->m_pFontList, IsNeedCMap());
|
||||
m_mFonts.insert(mFonts.begin(), mFonts.end());
|
||||
|
||||
return true;
|
||||
return FinalizeMerge(pContext);
|
||||
}
|
||||
|
||||
bool CPdfReader::UnmergePages()
|
||||
{
|
||||
if (m_vPDFContext.size() <= 1)
|
||||
@ -836,6 +860,141 @@ PDFDoc* CPdfReader::GetPDFDocument(int PDFIndex)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// CPdfReader::GetInfo
|
||||
// ============================================================
|
||||
std::wstring GetMetaString(Object& oInfo, const char* sName, const wchar_t* wsName)
|
||||
{
|
||||
std::wstring sRes;
|
||||
Object obj1;
|
||||
if (oInfo.dictLookup(sName, &obj1)->isString())
|
||||
{
|
||||
TextString* s = new TextString(obj1.getString());
|
||||
std::wstring sValue = NSStringExt::CConverter::GetUnicodeFromUTF32(s->getUnicode(), s->getLength());
|
||||
delete s;
|
||||
NSStringExt::Replace(sValue, L"\\", L"\\\\");
|
||||
NSStringExt::Replace(sValue, L"\"", L"\\\"");
|
||||
sValue.erase(std::remove_if(sValue.begin(), sValue.end(), [](const wchar_t& wc) { return wc < 0x20; }), sValue.end());
|
||||
if (!sValue.empty())
|
||||
{
|
||||
sRes += L"\"";
|
||||
sRes += wsName;
|
||||
sRes += L"\":\"";
|
||||
sRes += sValue;
|
||||
sRes += L"\",";
|
||||
}
|
||||
}
|
||||
obj1.free();
|
||||
return sRes;
|
||||
}
|
||||
std::wstring GetMetaDate(Object& oInfo, const char* sName, const wchar_t* wsName)
|
||||
{
|
||||
std::wstring sRes;
|
||||
Object obj1;
|
||||
if (!oInfo.dictLookup(sName, &obj1)->isString() || !obj1.getString()->getLength())
|
||||
{
|
||||
obj1.free();
|
||||
return sRes;
|
||||
}
|
||||
|
||||
TextString* s = new TextString(obj1.getString());
|
||||
std::wstring sNoDate = NSStringExt::CConverter::GetUnicodeFromUTF32(s->getUnicode(), s->getLength());
|
||||
delete s;
|
||||
|
||||
if (sNoDate.length() > 16)
|
||||
{
|
||||
std::wstring sDate = sNoDate.substr(2, 4) + L'-' + sNoDate.substr(6, 2) + L'-' + sNoDate.substr(8, 2) + L'T' +
|
||||
sNoDate.substr(10, 2) + L':' + sNoDate.substr(12, 2) + L':' + sNoDate.substr(14, 2);
|
||||
if (sNoDate.length() > 21 && (sNoDate[16] == L'+' || sNoDate[16] == L'-'))
|
||||
sDate += (L".000" + sNoDate.substr(16, 3) + L':' + sNoDate.substr(20, 2));
|
||||
else
|
||||
sDate += L"Z";
|
||||
NSStringExt::Replace(sDate, L"\\", L"\\\\");
|
||||
NSStringExt::Replace(sDate, L"\"", L"\\\"");
|
||||
sDate.erase(std::remove_if(sDate.begin(), sDate.end(), [](const wchar_t& wc) { return wc < 0x20; }), sDate.end());
|
||||
sRes += L"\"";
|
||||
sRes += wsName;
|
||||
sRes += L"\":\"";
|
||||
sRes += sDate;
|
||||
sRes += L"\",";
|
||||
}
|
||||
|
||||
obj1.free();
|
||||
return sRes;
|
||||
}
|
||||
std::wstring GetDocMetaFields(PDFDoc* pDoc)
|
||||
{
|
||||
std::wstring sRes;
|
||||
Object oInfo;
|
||||
if (!pDoc->getDocInfo(&oInfo)->isDict())
|
||||
{
|
||||
oInfo.free();
|
||||
return sRes;
|
||||
}
|
||||
|
||||
sRes += GetMetaString(oInfo, "Title", L"Title");
|
||||
sRes += GetMetaString(oInfo, "Author", L"Author");
|
||||
sRes += GetMetaString(oInfo, "Subject", L"Subject");
|
||||
sRes += GetMetaString(oInfo, "Keywords", L"Keywords");
|
||||
sRes += GetMetaString(oInfo, "Creator", L"Creator");
|
||||
sRes += GetMetaString(oInfo, "Producer", L"Producer");
|
||||
sRes += GetMetaDate (oInfo, "CreationDate", L"CreationDate");
|
||||
sRes += GetMetaDate (oInfo, "ModDate", L"ModDate");
|
||||
|
||||
oInfo.free();
|
||||
return sRes;
|
||||
}
|
||||
bool IsLinearized(PDFDoc* pDoc, XRef* xref, BaseStream* str, DWORD nFileLength)
|
||||
{
|
||||
Object obj1, obj2, obj3, obj4, obj5, obj6;
|
||||
obj1.initNull();
|
||||
Parser* parser = new Parser(xref, new Lexer(xref, str->makeSubStream(str->getStart(), gFalse, 0, &obj1)), gTrue);
|
||||
parser->getObj(&obj1);
|
||||
parser->getObj(&obj2);
|
||||
parser->getObj(&obj3);
|
||||
parser->getObj(&obj4);
|
||||
|
||||
bool bLinearized = false;
|
||||
if (obj1.isInt() && obj2.isInt() && obj3.isCmd("obj") && obj4.isDict())
|
||||
{
|
||||
obj4.dictLookup("Linearized", &obj5);
|
||||
if (obj5.isNum() && obj5.getNum() > 0 && obj4.dictLookup("L", &obj6)->isNum())
|
||||
{
|
||||
unsigned long size = (unsigned long)obj6.getNum();
|
||||
bLinearized = size == nFileLength;
|
||||
}
|
||||
obj6.free();
|
||||
obj5.free();
|
||||
}
|
||||
obj4.free();
|
||||
obj3.free();
|
||||
obj2.free();
|
||||
obj1.free();
|
||||
delete parser;
|
||||
|
||||
return bLinearized;
|
||||
}
|
||||
bool IsTagged(XRef* xref)
|
||||
{
|
||||
bool bTagged = false;
|
||||
Object catDict, markInfoObj;
|
||||
if (xref->getCatalog(&catDict)->isDict() && catDict.dictLookup("MarkInfo", &markInfoObj)->isDict())
|
||||
{
|
||||
Object marked, suspects;
|
||||
if (markInfoObj.dictLookup("Marked", &marked)->isBool() && marked.getBool() == gTrue)
|
||||
{
|
||||
bTagged = true;
|
||||
if (markInfoObj.dictLookup("Suspects", &suspects)->isBool() && suspects.getBool() == gTrue)
|
||||
bTagged = false;
|
||||
}
|
||||
marked.free();
|
||||
suspects.free();
|
||||
}
|
||||
markInfoObj.free();
|
||||
catDict.free();
|
||||
|
||||
return bTagged;
|
||||
}
|
||||
std::wstring CPdfReader::GetInfo()
|
||||
{
|
||||
std::wstring sRes;
|
||||
@ -847,85 +1006,13 @@ std::wstring CPdfReader::GetInfo()
|
||||
return sRes;
|
||||
|
||||
PDFDoc* pDoc = pPDFContext->m_pDocument;
|
||||
XRef* xref = pDoc->getXRef();
|
||||
XRef* xref = pDoc->getXRef();
|
||||
BaseStream* str = pDoc->getBaseStream();
|
||||
if (!xref || !str)
|
||||
return NULL;
|
||||
return sRes;
|
||||
|
||||
sRes = L"{";
|
||||
|
||||
Object oInfo;
|
||||
if (pDoc->getDocInfo(&oInfo)->isDict())
|
||||
{
|
||||
auto fDictLookup = [&oInfo](const char* sName, const wchar_t* wsName)
|
||||
{
|
||||
std::wstring sRes;
|
||||
Object obj1;
|
||||
if (oInfo.dictLookup(sName, &obj1)->isString())
|
||||
{
|
||||
TextString* s = new TextString(obj1.getString());
|
||||
std::wstring sValue = NSStringExt::CConverter::GetUnicodeFromUTF32(s->getUnicode(), s->getLength());
|
||||
delete s;
|
||||
NSStringExt::Replace(sValue, L"\\", L"\\\\");
|
||||
NSStringExt::Replace(sValue, L"\"", L"\\\"");
|
||||
sValue.erase(std::remove_if(sValue.begin(), sValue.end(), [] (const wchar_t& wc) { return wc < 0x20; } ), sValue.end());
|
||||
if (!sValue.empty())
|
||||
{
|
||||
sRes += L"\"";
|
||||
sRes += wsName;
|
||||
sRes += L"\":\"";
|
||||
sRes += sValue;
|
||||
sRes += L"\",";
|
||||
}
|
||||
}
|
||||
obj1.free();
|
||||
return sRes;
|
||||
};
|
||||
sRes += fDictLookup("Title", L"Title");
|
||||
sRes += fDictLookup("Author", L"Author");
|
||||
sRes += fDictLookup("Subject", L"Subject");
|
||||
sRes += fDictLookup("Keywords", L"Keywords");
|
||||
sRes += fDictLookup("Creator", L"Creator");
|
||||
sRes += fDictLookup("Producer", L"Producer");
|
||||
|
||||
auto fDictLookupDate = [&oInfo](const char* sName, const wchar_t* wsName)
|
||||
{
|
||||
std::wstring sRes;
|
||||
Object obj1;
|
||||
if (!oInfo.dictLookup(sName, &obj1)->isString() || !obj1.getString()->getLength())
|
||||
{
|
||||
obj1.free();
|
||||
return sRes;
|
||||
}
|
||||
|
||||
TextString* s = new TextString(obj1.getString());
|
||||
std::wstring sNoDate = NSStringExt::CConverter::GetUnicodeFromUTF32(s->getUnicode(), s->getLength());
|
||||
if (sNoDate.length() > 16)
|
||||
{
|
||||
std::wstring sDate = sNoDate.substr(2, 4) + L'-' + sNoDate.substr(6, 2) + L'-' + sNoDate.substr(8, 2) + L'T' +
|
||||
sNoDate.substr(10, 2) + L':' + sNoDate.substr(12, 2) + L':' + sNoDate.substr(14, 2);
|
||||
if (sNoDate.length() > 21 && (sNoDate[16] == L'+' || sNoDate[16] == L'-'))
|
||||
sDate += (L".000" + sNoDate.substr(16, 3) + L':' + sNoDate.substr(20, 2));
|
||||
else
|
||||
sDate += L"Z";
|
||||
NSStringExt::Replace(sDate, L"\\", L"\\\\");
|
||||
NSStringExt::Replace(sDate, L"\"", L"\\\"");
|
||||
sDate.erase(std::remove_if(sDate.begin(), sDate.end(), [] (const wchar_t& wc) { return wc < 0x20; } ), sDate.end());
|
||||
sRes += L"\"";
|
||||
sRes += wsName;
|
||||
sRes += L"\":\"";
|
||||
sRes += sDate;
|
||||
sRes += L"\",";
|
||||
}
|
||||
delete s;
|
||||
|
||||
obj1.free();
|
||||
return sRes;
|
||||
};
|
||||
sRes += fDictLookupDate("CreationDate", L"CreationDate");
|
||||
sRes += fDictLookupDate("ModDate", L"ModDate");
|
||||
}
|
||||
oInfo.free();
|
||||
sRes += GetDocMetaFields(pDoc);
|
||||
|
||||
std::wstring version = std::to_wstring(pDoc->getPDFVersion());
|
||||
std::wstring::size_type posDot = version.find('.');
|
||||
@ -934,71 +1021,19 @@ std::wstring CPdfReader::GetInfo()
|
||||
if (!version.empty())
|
||||
sRes += (L"\"Version\":" + version + L",");
|
||||
|
||||
double nW = 0;
|
||||
double nH = 0;
|
||||
double nDpi = 0;
|
||||
double nW = 0, nH = 0, nDpi = 0;
|
||||
GetPageInfo(0, &nW, &nH, &nDpi, &nDpi);
|
||||
sRes += L"\"PageWidth\":";
|
||||
sRes += std::to_wstring((int)(nW * 100));
|
||||
sRes += L",\"PageHeight\":";
|
||||
sRes += std::to_wstring((int)(nH * 100));
|
||||
sRes += L",\"NumberOfPages\":";
|
||||
sRes += std::to_wstring(GetNumPages());
|
||||
sRes += L",\"FastWebView\":";
|
||||
sRes += L"\"PageWidth\":" + std::to_wstring((int)(nW * 100));
|
||||
sRes += L",\"PageHeight\":" + std::to_wstring((int)(nH * 100));
|
||||
sRes += L",\"NumberOfPages\":" + std::to_wstring(GetNumPages());
|
||||
|
||||
bool bLinearized = false;
|
||||
if (m_vPDFContext.size() == 1)
|
||||
{
|
||||
Object obj1, obj2, obj3, obj4, obj5, obj6;
|
||||
obj1.initNull();
|
||||
Parser* parser = new Parser(xref, new Lexer(xref, str->makeSubStream(str->getStart(), gFalse, 0, &obj1)), gTrue);
|
||||
parser->getObj(&obj1);
|
||||
parser->getObj(&obj2);
|
||||
parser->getObj(&obj3);
|
||||
parser->getObj(&obj4);
|
||||
if (obj1.isInt() && obj2.isInt() && obj3.isCmd("obj") && obj4.isDict())
|
||||
{
|
||||
obj4.dictLookup("Linearized", &obj5);
|
||||
if (obj5.isNum() && obj5.getNum() > 0 && obj4.dictLookup("L", &obj6)->isNum())
|
||||
{
|
||||
unsigned long size = (unsigned long)obj6.getNum();
|
||||
bLinearized = size == m_nFileLength;
|
||||
}
|
||||
obj6.free();
|
||||
obj5.free();
|
||||
}
|
||||
obj4.free();
|
||||
obj3.free();
|
||||
obj2.free();
|
||||
obj1.free();
|
||||
delete parser;
|
||||
}
|
||||
|
||||
sRes += bLinearized ? L"true" : L"false";
|
||||
sRes += L",\"Tagged\":";
|
||||
|
||||
bool bTagged = false;
|
||||
Object catDict, markInfoObj;
|
||||
if (xref->getCatalog(&catDict)->isDict() && catDict.dictLookup("MarkInfo", &markInfoObj)->isDict())
|
||||
{
|
||||
Object marked, suspects;
|
||||
if (markInfoObj.dictLookup("Marked", &marked)->isBool() && marked.getBool() == gTrue)
|
||||
{
|
||||
bTagged = true;
|
||||
// If Suspects is true, the document may not completely conform to Tagged PDF conventions.
|
||||
if (markInfoObj.dictLookup("Suspects", &suspects)->isBool() && suspects.getBool() == gTrue)
|
||||
bTagged = false;
|
||||
}
|
||||
marked.free();
|
||||
suspects.free();
|
||||
}
|
||||
markInfoObj.free();
|
||||
catDict.free();
|
||||
|
||||
sRes += bTagged ? L"true}" : L"false}";
|
||||
bool bLinearized = (m_vPDFContext.size() == 1) && IsLinearized(pDoc, xref, str, m_nFileLength);
|
||||
sRes += std::wstring(L",\"FastWebView\":") + (bLinearized ? L"true" : L"false");
|
||||
sRes += std::wstring(L",\"Tagged\":") + (IsTagged(xref) ? L"true}" : L"false}");
|
||||
|
||||
return sRes;
|
||||
}
|
||||
|
||||
BYTE* CPdfReader::GetGIDByUnicode(const std::wstring& wsFontName)
|
||||
{
|
||||
std::map<std::wstring, std::wstring>::const_iterator oIter = m_mFonts.find(wsFontName);
|
||||
@ -1049,8 +1084,8 @@ BYTE* CPdfReader::GetGIDByUnicode(const std::wstring& wsFontName)
|
||||
|
||||
NSWasm::CData oRes;
|
||||
oRes.SkipLen();
|
||||
oRes.AddInt(mGIDbyUnicode.size());
|
||||
|
||||
oRes.AddInt(mGIDbyUnicode.size());
|
||||
for (std::map<unsigned int, unsigned int>::const_iterator it = mGIDbyUnicode.begin(); it != mGIDbyUnicode.end(); ++it)
|
||||
{
|
||||
oRes.AddInt(it->first);
|
||||
@ -1058,9 +1093,9 @@ BYTE* CPdfReader::GetGIDByUnicode(const std::wstring& wsFontName)
|
||||
}
|
||||
|
||||
oRes.WriteLen();
|
||||
BYTE* bRes = oRes.GetBuffer();
|
||||
BYTE* pRes = oRes.GetBuffer();
|
||||
oRes.ClearWithoutAttack();
|
||||
return bRes;
|
||||
return pRes;
|
||||
}
|
||||
std::wstring CPdfReader::GetFontPath(const std::wstring& wsFontName, bool bSave)
|
||||
{
|
||||
@ -1170,10 +1205,9 @@ BYTE* CPdfReader::GetStructure()
|
||||
}
|
||||
|
||||
oRes.WriteLen();
|
||||
|
||||
BYTE* bRes = oRes.GetBuffer();
|
||||
BYTE* pRes = oRes.GetBuffer();
|
||||
oRes.ClearWithoutAttack();
|
||||
return bRes;
|
||||
return pRes;
|
||||
}
|
||||
BYTE* CPdfReader::GetLinks(int _nPageIndex)
|
||||
{
|
||||
@ -1348,9 +1382,9 @@ BYTE* CPdfReader::GetWidgets()
|
||||
}
|
||||
|
||||
oRes.WriteLen();
|
||||
BYTE* bRes = oRes.GetBuffer();
|
||||
BYTE* pRes = oRes.GetBuffer();
|
||||
oRes.ClearWithoutAttack();
|
||||
return bRes;
|
||||
return pRes;
|
||||
}
|
||||
void CPdfReader::SetFonts(PdfReader::CPdfFontList* pFontList)
|
||||
{
|
||||
@ -1395,9 +1429,9 @@ BYTE* CPdfReader::GetFonts(bool bStandart)
|
||||
oRes.AddInt(nFonts, nFontsPos);
|
||||
|
||||
oRes.WriteLen();
|
||||
BYTE* bRes = oRes.GetBuffer();
|
||||
BYTE* pRes = oRes.GetBuffer();
|
||||
oRes.ClearWithoutAttack();
|
||||
return bRes;
|
||||
return pRes;
|
||||
}
|
||||
BYTE* CPdfReader::VerifySign(const std::wstring& sFile, ICertificate* pCertificate, int nWidget)
|
||||
{
|
||||
@ -1480,9 +1514,9 @@ BYTE* CPdfReader::VerifySign(const std::wstring& sFile, ICertificate* pCertifica
|
||||
}
|
||||
|
||||
oRes.WriteLen();
|
||||
BYTE* bRes = oRes.GetBuffer();
|
||||
BYTE* pRes = oRes.GetBuffer();
|
||||
oRes.ClearWithoutAttack();
|
||||
return bRes;
|
||||
return pRes;
|
||||
}
|
||||
BYTE* CPdfReader::GetAPWidget(int nRasterW, int nRasterH, int nBackgroundColor, int _nPageIndex, int nWidget, const char* sView, const char* sButtonView)
|
||||
{
|
||||
@ -1518,9 +1552,9 @@ BYTE* CPdfReader::GetAPWidget(int nRasterW, int nRasterH, int nBackgroundColor,
|
||||
}
|
||||
|
||||
oRes.WriteLen();
|
||||
BYTE* bRes = oRes.GetBuffer();
|
||||
BYTE* pRes = oRes.GetBuffer();
|
||||
oRes.ClearWithoutAttack();
|
||||
return bRes;
|
||||
return pRes;
|
||||
}
|
||||
BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int _nPageIndex, bool bBase64, int nButtonWidget, const char* sIconView)
|
||||
{
|
||||
@ -1967,9 +2001,9 @@ BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int _nPageIndex, bool bBas
|
||||
}
|
||||
|
||||
oRes.WriteLen();
|
||||
BYTE* bRes = oRes.GetBuffer();
|
||||
BYTE* pRes = oRes.GetBuffer();
|
||||
oRes.ClearWithoutAttack();
|
||||
return bRes;
|
||||
return pRes;
|
||||
}
|
||||
BYTE* CPdfReader::StreamToCData(BYTE* pSteam, int nLength)
|
||||
{
|
||||
@ -1979,7 +2013,6 @@ BYTE* CPdfReader::StreamToCData(BYTE* pSteam, int nLength)
|
||||
oRes.Write(pSteam, nLength);
|
||||
|
||||
oRes.WriteLen();
|
||||
|
||||
BYTE* bRes = oRes.GetBuffer();
|
||||
oRes.ClearWithoutAttack();
|
||||
return bRes;
|
||||
@ -2140,9 +2173,9 @@ BYTE* CPdfReader::GetAnnots(int _nPageIndex)
|
||||
}
|
||||
|
||||
oRes.WriteLen();
|
||||
BYTE* bRes = oRes.GetBuffer();
|
||||
BYTE* pRes = oRes.GetBuffer();
|
||||
oRes.ClearWithoutAttack();
|
||||
return bRes;
|
||||
return pRes;
|
||||
}
|
||||
BYTE* CPdfReader::GetAPAnnots(int nRasterW, int nRasterH, int nBackgroundColor, int _nPageIndex, int nAnnot, const char* sView)
|
||||
{
|
||||
@ -2205,11 +2238,10 @@ BYTE* CPdfReader::GetAPAnnots(int nRasterW, int nRasterH, int nBackgroundColor,
|
||||
|
||||
oAnnotRef.free();
|
||||
}
|
||||
|
||||
oAnnots.free();
|
||||
|
||||
oRes.WriteLen();
|
||||
BYTE* bRes = oRes.GetBuffer();
|
||||
BYTE* pRes = oRes.GetBuffer();
|
||||
oRes.ClearWithoutAttack();
|
||||
return bRes;
|
||||
return pRes;
|
||||
}
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
|
||||
#include "../DesktopEditor/graphics/pro/Fonts.h"
|
||||
#include "../DesktopEditor/graphics/pro/officedrawingfile.h"
|
||||
#include "../DesktopEditor/graphics/pro/js/wasm/src/serialize.h"
|
||||
#include "../DesktopEditor/xmlsec/src/include/Certificate.h"
|
||||
#include "SrcReader/RendererOutputDev.h"
|
||||
|
||||
@ -92,6 +93,7 @@ public:
|
||||
int GetMaxRefID();
|
||||
int GetNumPages();
|
||||
bool ValidMetaData();
|
||||
|
||||
// Takes ownership of malloc data memory
|
||||
bool MergePages(BYTE* pData, DWORD nLength, const wchar_t* wsPassword = NULL, int nMaxID = 0, const std::string& sPrefixForm = "");
|
||||
bool MergePages(const std::wstring& wsFile, const wchar_t* wsPassword = NULL, int nMaxID = 0, const std::string& sPrefixForm = "");
|
||||
@ -135,13 +137,18 @@ public:
|
||||
private:
|
||||
void Clear();
|
||||
|
||||
CPdfReaderContext* CreateContext(const std::string& sPrefixForm, int nMaxID);
|
||||
bool FinalizeMerge(CPdfReaderContext* pContext);
|
||||
CPdfReaderContext* FindContext(PDFDoc* pDoc) const;
|
||||
|
||||
private:
|
||||
std::wstring m_wsTempFolder;
|
||||
NSFonts::IFontManager* m_pFontManager;
|
||||
DWORD m_nFileLength;
|
||||
int m_eError;
|
||||
IOfficeDrawingFilePainter* m_pPainter;
|
||||
IOfficeDrawingFilePainter* m_pPainter;
|
||||
std::vector<CPdfReaderContext*> m_vPDFContext;
|
||||
std::vector<CPdfRedact*> m_vRedact;
|
||||
std::vector<CPdfRedact*> m_vRedact;
|
||||
std::map<std::wstring, std::wstring> m_mFonts;
|
||||
};
|
||||
|
||||
|
||||
@ -49,7 +49,6 @@
|
||||
|
||||
#include "../../DesktopEditor/common/Types.h"
|
||||
#include "../../DesktopEditor/common/StringExt.h"
|
||||
#include "../../DesktopEditor/xml/include/xmlutils.h"
|
||||
#include "../../DesktopEditor/fontengine/ApplicationFonts.h"
|
||||
#include "../../DesktopEditor/graphics/pro/Fonts.h"
|
||||
|
||||
@ -1857,7 +1856,7 @@ CAnnotFreeText::CAnnotFreeText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex
|
||||
|
||||
if (oAnnot.dictLookup("RC", &oObj2)->isNull() && oAnnot.dictLookup("Contents", &oObj)->isString() && oObj.getString()->getLength())
|
||||
{
|
||||
m_arrRC = CAnnotMarkup::ReadRC(GetRCFromDS(m_sDS, &oObj, m_arrCFromDA));
|
||||
m_arrRC = ReadRC(GetRCFromDS(m_sDS, &oObj, m_arrCFromDA));
|
||||
if (m_arrRC.empty())
|
||||
m_unFlags &= ~(1 << 3);
|
||||
else
|
||||
@ -2749,7 +2748,7 @@ CAnnotMarkup::CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, in
|
||||
// std::cout << sRC << std::endl;
|
||||
// if (oAnnot.dictLookup("RC", &oObj)->isStream())
|
||||
// TODO streamGetBlock
|
||||
m_arrRC = CAnnotMarkup::ReadRC(sRC);
|
||||
m_arrRC = ReadRC(sRC);
|
||||
if (m_arrRC.empty())
|
||||
m_unFlags &= ~(1 << 3);
|
||||
else
|
||||
@ -2786,166 +2785,6 @@ CAnnotMarkup::~CAnnotMarkup()
|
||||
for (int i = 0; i < m_arrRC.size(); ++i)
|
||||
RELEASEOBJECT(m_arrRC[i]);
|
||||
}
|
||||
void ReadFontData(const std::string& sData, CAnnotMarkup::CFontData* pFont)
|
||||
{
|
||||
size_t nSemicolon = 0;
|
||||
size_t nColon = sData.find(':');
|
||||
while (nColon != std::string::npos && nColon > nSemicolon)
|
||||
{
|
||||
std::string sProperty = sData.substr(nSemicolon, nColon - nSemicolon);
|
||||
nSemicolon = sData.find(';', nSemicolon);
|
||||
nColon++;
|
||||
std::string sValue = sData.substr(nColon, nSemicolon - nColon);
|
||||
nColon = sData.find(':', nSemicolon);
|
||||
nSemicolon++;
|
||||
|
||||
if (sProperty == "font-size")
|
||||
pFont->dFontSise = std::stod(sValue);
|
||||
else if (sProperty == "text-align")
|
||||
{
|
||||
// 0 start / left
|
||||
if (sValue == "center" || sValue == "middle")
|
||||
pFont->nAlign = 1;
|
||||
else if (sValue == "right" || sValue == "end")
|
||||
pFont->nAlign = 2;
|
||||
else if (sValue == "justify")
|
||||
pFont->nAlign = 3;
|
||||
}
|
||||
else if (sProperty == "color")
|
||||
{
|
||||
if (sValue[0] == '#')
|
||||
{
|
||||
sValue = sValue.substr(1);
|
||||
BYTE nColor1 = 0, nColor2 = 0, nColor3 = 0;
|
||||
if (sValue.length() == 6)
|
||||
sscanf(sValue.c_str(), "%2hhx%2hhx%2hhx", &nColor1, &nColor2, &nColor3);
|
||||
else if (sValue.length() == 3)
|
||||
{
|
||||
sscanf(sValue.c_str(), "%1hhx%1hhx%1hhx", &nColor1, &nColor2, &nColor3);
|
||||
nColor1 *= 17;
|
||||
nColor2 *= 17;
|
||||
nColor3 *= 17;
|
||||
}
|
||||
|
||||
pFont->dColor[0] = (double)nColor1 / 255.0;
|
||||
pFont->dColor[1] = (double)nColor2 / 255.0;
|
||||
pFont->dColor[2] = (double)nColor3 / 255.0;
|
||||
}
|
||||
}
|
||||
else if (sProperty == "font-weight")
|
||||
{
|
||||
// 0 normal / 300 / 400 / 500
|
||||
if (sValue == "normal" || sValue == "300" || sValue == "400" || sValue == "500")
|
||||
pFont->unFontFlags &= ~(1 << 0);
|
||||
else if (sValue == "bold" || sValue == "bolder" || sValue == "600" || sValue == "700" || sValue == "800" || sValue == "900")
|
||||
pFont->unFontFlags |= (1 << 0);
|
||||
}
|
||||
else if (sProperty == "font-style")
|
||||
{
|
||||
// 0 normal
|
||||
if (sValue == "normal")
|
||||
pFont->unFontFlags &= ~(1 << 1);
|
||||
else if (sValue == "italic" || sValue.find("oblique") != std::string::npos)
|
||||
pFont->unFontFlags |= (1 << 1);
|
||||
}
|
||||
else if (sProperty == "font-family")
|
||||
pFont->sFontFamily = sValue[0] == '\'' ? sValue.substr(1, sValue.length() - 2) : sValue;
|
||||
else if (sProperty == "text-decoration")
|
||||
{
|
||||
if (sValue.find("line-through") != std::string::npos)
|
||||
pFont->unFontFlags |= (1 << 3);
|
||||
if (sValue.find("word") != std::string::npos || sValue.find("underline") != std::string::npos)
|
||||
pFont->unFontFlags |= (1 << 4);
|
||||
if (sValue.find("none") != std::string::npos)
|
||||
{
|
||||
pFont->unFontFlags &= ~(1 << 3);
|
||||
pFont->unFontFlags &= ~(1 << 4);
|
||||
}
|
||||
}
|
||||
else if (sProperty == "vertical-align")
|
||||
{
|
||||
pFont->unFontFlags |= (1 << 5);
|
||||
pFont->dVAlign = std::stod(sValue);
|
||||
if (pFont->dVAlign == 0 && sValue[0] == '-')
|
||||
pFont->dVAlign = -0.01;
|
||||
}
|
||||
// font-stretch
|
||||
}
|
||||
}
|
||||
std::vector<CAnnotMarkup::CFontData*> CAnnotMarkup::ReadRC(const std::string& sRC)
|
||||
{
|
||||
std::vector<CAnnotMarkup::CFontData*> arrRC;
|
||||
|
||||
XmlUtils::CXmlLiteReader oLightReader;
|
||||
if (sRC.empty() || !oLightReader.FromStringA(sRC) || !oLightReader.ReadNextNode() || oLightReader.GetNameA() != "body")
|
||||
return arrRC;
|
||||
|
||||
CAnnotMarkup::CFontData oFontBase;
|
||||
while (oLightReader.MoveToNextAttribute())
|
||||
{
|
||||
if (oLightReader.GetNameA() == "style")
|
||||
{
|
||||
ReadFontData(oLightReader.GetTextA(), &oFontBase);
|
||||
break;
|
||||
}
|
||||
}
|
||||
oLightReader.MoveToElement();
|
||||
|
||||
int nDepthP = oLightReader.GetDepth();
|
||||
while (oLightReader.ReadNextSiblingNode2(nDepthP))
|
||||
{
|
||||
if (oLightReader.GetNameA() != "p")
|
||||
continue;
|
||||
|
||||
bool bRTL = false;
|
||||
while (oLightReader.MoveToNextAttribute())
|
||||
{
|
||||
if (oLightReader.GetNameA() == "dir" && oLightReader.GetTextA() == "rtl")
|
||||
{
|
||||
bRTL = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
oLightReader.MoveToElement();
|
||||
|
||||
int nDepthSpan = oLightReader.GetDepth();
|
||||
if (oLightReader.IsEmptyNode() || !oLightReader.ReadNextSiblingNode2(nDepthSpan))
|
||||
continue;
|
||||
|
||||
do
|
||||
{
|
||||
std::string sName = oLightReader.GetNameA();
|
||||
if (sName == "span")
|
||||
{
|
||||
CAnnotMarkup::CFontData* pFont = new CAnnotMarkup::CFontData(oFontBase);
|
||||
while (oLightReader.MoveToNextAttribute())
|
||||
{
|
||||
if (oLightReader.GetNameA() == "style")
|
||||
{
|
||||
ReadFontData(oLightReader.GetTextA(), pFont);
|
||||
break;
|
||||
}
|
||||
}
|
||||
oLightReader.MoveToElement();
|
||||
|
||||
if (bRTL)
|
||||
pFont->unFontFlags |= (1 << 7);
|
||||
pFont->sText = oLightReader.GetText2A();
|
||||
arrRC.push_back(pFont);
|
||||
}
|
||||
else if (sName == "#text")
|
||||
{
|
||||
CAnnotMarkup::CFontData* pFont = new CAnnotMarkup::CFontData(oFontBase);
|
||||
if (bRTL)
|
||||
pFont->unFontFlags |= (1 << 7);
|
||||
pFont->sText = oLightReader.GetTextA();
|
||||
arrRC.push_back(pFont);
|
||||
}
|
||||
} while (oLightReader.ReadNextSiblingNode2(nDepthSpan));
|
||||
}
|
||||
|
||||
return arrRC;
|
||||
}
|
||||
void CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList)
|
||||
{
|
||||
GetFreeTextFont(pdfDoc, pFontManager, pFontList, oAnnotRef, m_arrRC);
|
||||
|
||||
@ -46,6 +46,7 @@
|
||||
#include "../../DesktopEditor/graphics/pro/js/wasm/src/serialize.h"
|
||||
|
||||
#include "RendererOutputDev.h"
|
||||
#include "PdfFont.h"
|
||||
|
||||
namespace PdfReader
|
||||
{
|
||||
@ -387,25 +388,7 @@ private:
|
||||
class CAnnotMarkup : public CAnnot
|
||||
{
|
||||
public:
|
||||
struct CFontData final
|
||||
{
|
||||
bool bFind;
|
||||
BYTE nAlign;
|
||||
unsigned int unFontFlags; // 0 Bold, 1 Italic, 3 strikethrough, 4 underline, 5 vertical-align, 6 actual font, 7 RTL
|
||||
double dFontSise;
|
||||
double dVAlign;
|
||||
double dColor[3];
|
||||
std::string sFontFamily;
|
||||
std::string sActualFont;
|
||||
std::string sText;
|
||||
|
||||
CFontData() : bFind(false), nAlign(0), unFontFlags(4), dFontSise(10), dVAlign(0), dColor{0, 0, 0} {}
|
||||
CFontData(const CFontData& oFont) : bFind(oFont.bFind), nAlign(oFont.nAlign), unFontFlags(oFont.unFontFlags), dFontSise(oFont.dFontSise), dVAlign(oFont.dVAlign),
|
||||
dColor{oFont.dColor[0], oFont.dColor[1], oFont.dColor[2]}, sFontFamily(oFont.sFontFamily), sActualFont(oFont.sActualFont), sText(oFont.sText) {}
|
||||
};
|
||||
|
||||
void SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList);
|
||||
static std::vector<CAnnotMarkup::CFontData*> ReadRC(const std::string& sRC);
|
||||
|
||||
protected:
|
||||
CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -45,7 +45,6 @@
|
||||
#include "../../DesktopEditor/graphics/pro/Fonts.h"
|
||||
|
||||
#include "RendererOutputDev.h"
|
||||
#include "PdfAnnot.h"
|
||||
|
||||
namespace PdfReader
|
||||
{
|
||||
@ -84,20 +83,40 @@ struct CType3FontMetrics
|
||||
return dUnitsPerEm * 0.5;
|
||||
}
|
||||
};
|
||||
struct CFontData
|
||||
{
|
||||
bool bFind;
|
||||
BYTE nAlign;
|
||||
unsigned int unFontFlags; // 0 Bold, 1 Italic, 3 strikethrough, 4 underline, 5 vertical-align, 6 actual font, 7 RTL
|
||||
double dFontSise;
|
||||
double dVAlign;
|
||||
double dColor[3];
|
||||
std::string sFontFamily;
|
||||
std::string sActualFont;
|
||||
std::string sText;
|
||||
|
||||
CFontData() : bFind(false), nAlign(0), unFontFlags(4), dFontSise(10), dVAlign(0), dColor{0, 0, 0} {}
|
||||
CFontData(const CFontData& oFont) : bFind(oFont.bFind), nAlign(oFont.nAlign), unFontFlags(oFont.unFontFlags), dFontSise(oFont.dFontSise), dVAlign(oFont.dVAlign),
|
||||
dColor{oFont.dColor[0], oFont.dColor[1], oFont.dColor[2]}, sFontFamily(oFont.sFontFamily), sActualFont(oFont.sActualFont), sText(oFont.sText) {}
|
||||
};
|
||||
|
||||
std::vector<CFontData*> ReadRC(const std::string& sRC);
|
||||
std::string GetRCFromDS(const std::string& sDS, Object* pContents, const std::vector<double>& arrCFromDA);
|
||||
bool IsNeedCMap(PDFDoc* pDoc);
|
||||
bool IsBaseFont(const std::wstring& wsName);
|
||||
std::map<std::wstring, std::wstring> GetAllFonts(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, bool bIsNeedCMap);
|
||||
std::wstring GetFontData(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, Object* oFontRef, std::string& sFontName, std::string& sActualFontName, bool& bBold, bool& bItalic, bool bIsNeedCMap = false);
|
||||
std::map<std::wstring, std::wstring> GetAllFonts(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList);
|
||||
std::wstring GetFontData(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, Object* oFontRef, std::string& sFontName, std::string& sActualFontName, bool& bBold, bool& bItalic);
|
||||
bool GetFontFromAP(PDFDoc* pdfDoc, AcroFormField* pField, Object* oFontRef, std::string& sFontKey);
|
||||
std::vector<CAnnotFontInfo> GetAnnotFontInfos(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, Object* oAnnotRef);
|
||||
std::map<std::wstring, std::wstring> GetFreeTextFont(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, Object* oAnnotRef, std::vector<CAnnotMarkup::CFontData*>& arrRC);
|
||||
std::map<std::wstring, std::wstring> GetFreeTextFont(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, Object* oAnnotRef, std::vector<CFontData*>& arrRC);
|
||||
bool FindFonts(Object* oStream, int nDepth, Object* oResFonts);
|
||||
int CollectFontWidths(GfxFont* gfxFont, Dict* pFontDict, std::map<unsigned int, unsigned int>& mGIDToWidth);
|
||||
int CollectFontWidths(Dict* pFontDict, std::map<unsigned int, unsigned int>& mGIDToWidth);
|
||||
double CheckFontStylePDF(std::wstring& sName, bool& bBold, bool& bItalic);
|
||||
bool EraseSubsetTag(std::wstring& sFontName);
|
||||
|
||||
NSFonts::CFontInfo* GetFontByParams(XRef* pXref, NSFonts::IFontManager* pFontManager, GfxFont* pFont, std::wstring& wsFontBaseName, double& dStretch);
|
||||
void GetFont(XRef* pXref, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, GfxFont* pFont, std::wstring& wsFileName, std::wstring& wsFontName, bool bNotFullName = true);
|
||||
|
||||
CType3FontMetrics* BuildType3FontMetrics(XRef* pXref, GfxFont* pFont);
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -249,8 +249,6 @@ namespace PdfReader
|
||||
{
|
||||
m_pbBreak = pbBreak;
|
||||
}
|
||||
static NSFonts::CFontInfo* GetFontByParams(XRef* pXref, NSFonts::IFontManager* pFontManager, GfxFont* pFont, std::wstring& wsFontBaseName, double& dStretch);
|
||||
static void GetFont(XRef* pXref, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, GfxFont* pFont, std::wstring& wsFileName, std::wstring& wsFontName, bool bNotFullName = true);
|
||||
|
||||
private:
|
||||
struct GfxOutputState
|
||||
|
||||
@ -146,7 +146,7 @@ public:
|
||||
GBool isName(const char *nameA)
|
||||
{ return type == objName && !strcmp(name, nameA); }
|
||||
GBool isDict(const char *dictType);
|
||||
GBool isStream(char *dictType);
|
||||
GBool isStream(const char *dictType);
|
||||
GBool isCmd(const char *cmdA)
|
||||
{ return type == objCmd && !strcmp(cmd, cmdA); }
|
||||
|
||||
@ -182,7 +182,7 @@ public:
|
||||
Object *dictGetValNF(int i, Object *obj);
|
||||
|
||||
// Stream accessors.
|
||||
GBool streamIs(char *dictType);
|
||||
GBool streamIs(const char *dictType);
|
||||
void streamReset();
|
||||
void streamClose();
|
||||
int streamGetChar();
|
||||
@ -284,10 +284,10 @@ inline Object *Object::dictGetValNF(int i, Object *obj)
|
||||
|
||||
#include "Stream.h"
|
||||
|
||||
inline GBool Object::streamIs(char *dictType)
|
||||
inline GBool Object::streamIs(const char *dictType)
|
||||
{ return stream->getDict()->is(dictType); }
|
||||
|
||||
inline GBool Object::isStream(char *dictType)
|
||||
inline GBool Object::isStream(const char *dictType)
|
||||
{ return type == objStream && streamIs(dictType); }
|
||||
|
||||
inline void Object::streamReset()
|
||||
|
||||
Reference in New Issue
Block a user