mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-02-10 18:05:41 +08:00
@ -116,7 +116,6 @@ public:
|
||||
NSCSS::CTree m_oTree; // Дерево body html-файла
|
||||
|
||||
private:
|
||||
int m_nImageId; // ID картинки
|
||||
int m_nFootnoteId; // ID сноски
|
||||
int m_nHyperlinkId; // ID ссылки
|
||||
int m_nCrossId; // ID перекрестной ссылки
|
||||
@ -132,10 +131,11 @@ private:
|
||||
bool m_bWasPStyle; // <w:pStyle> записан?
|
||||
bool m_bWasSpace; // Был пробел?
|
||||
|
||||
std::vector<std::wstring> m_arrImages; // Картинки
|
||||
std::map<std::wstring, std::wstring> m_mFootnotes; // Сноски
|
||||
public:
|
||||
|
||||
CHtmlFile2_Private() : m_nImageId(1), m_nFootnoteId(1), m_nHyperlinkId(1), m_nCrossId(1), m_nNumberingId(1), m_bInP(false), m_bWasPStyle(false), m_bWasSpace(false)
|
||||
CHtmlFile2_Private() : m_nFootnoteId(1), m_nHyperlinkId(1), m_nCrossId(1), m_nNumberingId(1), m_bInP(false), m_bWasPStyle(false), m_bWasSpace(false)
|
||||
{
|
||||
//Установим размер исходного и нового окна для Css калькулятора (должны быть одинаковые единицы измерения (желательно пункты))
|
||||
//Это нужно для масштабирования некоторых значений
|
||||
@ -1723,30 +1723,29 @@ private:
|
||||
sNote = L"";
|
||||
}
|
||||
|
||||
bool readBase64 (const std::wstring& sSrcM, std::wstring& sImageName)
|
||||
bool readBase64 (const std::wstring& sSrcM, std::wstring& sExtention)
|
||||
{
|
||||
bool bRes = false;
|
||||
|
||||
size_t nBase = sSrcM.find(L"/", 4);
|
||||
nBase++;
|
||||
|
||||
size_t nEndBase = sSrcM.find(L";", nBase);
|
||||
if (nEndBase == std::wstring::npos)
|
||||
return bRes;
|
||||
std::wstring sType = sSrcM.substr(nBase, nEndBase - nBase);
|
||||
if (sType == L"octet-stream")
|
||||
sType = L"jpg";
|
||||
std::wstring sImageId = std::to_wstring(m_nImageId);
|
||||
sImageName = sImageId + L"." + sType;
|
||||
sExtention = sSrcM.substr(nBase, nEndBase - nBase);
|
||||
if (sExtention == L"octet-stream")
|
||||
sExtention = L"jpg";
|
||||
|
||||
nBase = sSrcM.find(L"base64", nEndBase);
|
||||
if (nBase == std::wstring::npos)
|
||||
return bRes;
|
||||
|
||||
NSFile::CFileBinary oImageWriter;
|
||||
std::wstring sImageName = std::to_wstring(m_arrImages.size()) + L'.' + sExtention;
|
||||
if (oImageWriter.CreateFileW(m_sDst + L"/word/media/i" + sImageName))
|
||||
{
|
||||
std::string sBase64 = m_oLightReader.GetTextA().substr(nBase + 7);
|
||||
std::string sSrc = U_TO_UTF8(sSrcM);
|
||||
std::string sBase64 = sSrc.substr(nBase + 7);
|
||||
int nSrcLen = (int)sBase64.length();
|
||||
int nDecodeLen = NSBase64::Base64DecodeGetRequiredLength(nSrcLen);
|
||||
if (nDecodeLen != 0)
|
||||
@ -1783,97 +1782,115 @@ private:
|
||||
return bRes;
|
||||
}
|
||||
|
||||
inline bool ValidExtension(const std::wstring& sSrc)
|
||||
inline bool NotValidExtension(const std::wstring& sExtention)
|
||||
{
|
||||
std::wstring sExtention = NSFile::GetFileExtention(sSrc);
|
||||
std::transform(sExtention.begin(), sExtention.end(), sExtention.begin(), tolower);
|
||||
return sExtention != L"bmp" && sExtention != L"emf" && sExtention != L"emz" && sExtention != L"eps" && sExtention != L"fpx" && sExtention != L"gif" &&
|
||||
sExtention != L"jpe" && sExtention != L"jpeg" && sExtention != L"jpg" && sExtention != L"jfif" && sExtention != L"pct" && sExtention != L"pict" &&
|
||||
sExtention != L"png" && sExtention != L"pntg" && sExtention != L"psd" && sExtention != L"qtif" && sExtention != L"sgi" && sExtention != L"svg" &&
|
||||
sExtention != L"tga" && sExtention != L"tpic" && sExtention != L"tiff" && sExtention != L"tif" && sExtention != L"wmf" && sExtention != L"wmz";
|
||||
}
|
||||
|
||||
void ImageAlternative(NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS, const std::wstring& wsAlt)
|
||||
{
|
||||
if (wsAlt.empty())
|
||||
return;
|
||||
|
||||
wrP(oXml, sSelectors, oTS);
|
||||
oXml->WriteString(L"<w:r>");
|
||||
wrR(oXml, sSelectors, oTS);
|
||||
oXml->WriteString(L"<w:t xml:space=\"preserve\">");
|
||||
oXml->WriteEncodeXmlString(wsAlt);
|
||||
oXml->WriteString(L"</w:t></w:r>");
|
||||
}
|
||||
|
||||
void readImage (NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS)
|
||||
{
|
||||
std::wstring wsAlt;
|
||||
std::wstring wsAlt, sSrcM;
|
||||
bool bRes = false;
|
||||
while (m_oLightReader.MoveToNextAttribute())
|
||||
{
|
||||
std::wstring wsName = m_oLightReader.GetName();
|
||||
if (wsName == L"alt")
|
||||
{
|
||||
wsAlt = m_oLightReader.GetText();
|
||||
continue;
|
||||
}
|
||||
else if (wsName != L"src")
|
||||
continue;
|
||||
|
||||
bool bIsAllowExternalLocalFiles = true;
|
||||
if (NSProcessEnv::IsPresent(NSProcessEnv::Converter::gc_allowPrivateIP))
|
||||
bIsAllowExternalLocalFiles = NSProcessEnv::GetBoolValue(NSProcessEnv::Converter::gc_allowPrivateIP);
|
||||
|
||||
std::wstring sSrcM = m_oLightReader.GetText();
|
||||
std::wstring sImageName;
|
||||
std::wstring sImageId = std::to_wstring(m_nImageId);
|
||||
|
||||
// Предполагаем картинку в Base64
|
||||
if (sSrcM.length() > 4 && sSrcM.substr(0, 4) == L"data" && sSrcM.find(L"/", 4) != std::wstring::npos)
|
||||
bRes = readBase64(sSrcM, sImageName);
|
||||
|
||||
if (!bRes)
|
||||
{
|
||||
sImageName = NSFile::GetFileName(sSrcM);
|
||||
sImageName.erase(std::remove_if(sImageName.begin(), sImageName.end(), [] (wchar_t ch) { return std::iswspace(ch) ||
|
||||
(ch == L'\\' || ch == L'/' || ch == L':' || ch == L'*' || ch == L'?' || ch == L'\"' || ch == L'<' || ch == L'>' || ch == L'|'); }), sImageName.end());
|
||||
|
||||
if (ValidExtension(sSrcM))
|
||||
break;
|
||||
|
||||
std::wstring wsDst = m_sDst + L"/word/media/i" + sImageName;
|
||||
|
||||
// Предполагаем картинку по локальному пути
|
||||
if (!((!m_sBase.empty() && m_sBase.length() > 4 && m_sBase.substr(0, 4) == L"http") || (sSrcM.length() > 4 && sSrcM.substr(0, 4) == L"http")))
|
||||
{
|
||||
if (!m_sBase.empty())
|
||||
{
|
||||
if (!bRes)
|
||||
bRes = CopyImage(NSSystemPath::Combine(m_sBase, sSrcM), wsDst, bIsAllowExternalLocalFiles);
|
||||
if (!bRes)
|
||||
bRes = CopyImage(NSSystemPath::Combine(m_sSrc, m_sBase + sSrcM), wsDst, bIsAllowExternalLocalFiles);
|
||||
}
|
||||
if (!bRes)
|
||||
bRes = CopyImage(NSSystemPath::Combine(m_sSrc, sSrcM), wsDst, bIsAllowExternalLocalFiles);
|
||||
if (!bRes)
|
||||
bRes = CopyImage(m_sSrc + L"/" + NSFile::GetFileName(sSrcM), wsDst, bIsAllowExternalLocalFiles);
|
||||
if (!bRes)
|
||||
bRes = CopyImage(sSrcM, wsDst, bIsAllowExternalLocalFiles);
|
||||
}
|
||||
// Предполагаем картинку в сети
|
||||
else
|
||||
{
|
||||
// Проверка gc_allowNetworkRequest предполагается в kernel_network
|
||||
NSNetwork::NSFileTransport::CFileDownloader oDownloadImg(m_sBase + sSrcM, false);
|
||||
oDownloadImg.SetFilePath(wsDst);
|
||||
bRes = oDownloadImg.DownloadSync();
|
||||
}
|
||||
}
|
||||
|
||||
if (bRes)
|
||||
{
|
||||
wrP(oXml, sSelectors, oTS);
|
||||
bRes = ImageRels(oXml, sImageId, L"i" + sImageName);
|
||||
}
|
||||
else if (wsName == L"src")
|
||||
sSrcM = m_oLightReader.GetText();
|
||||
}
|
||||
m_oLightReader.MoveToElement();
|
||||
|
||||
if(!bRes)
|
||||
if (sSrcM.empty())
|
||||
{
|
||||
ImageAlternative(oXml, sSelectors, oTS, wsAlt);
|
||||
return;
|
||||
}
|
||||
|
||||
bool bIsAllowExternalLocalFiles = true;
|
||||
if (NSProcessEnv::IsPresent(NSProcessEnv::Converter::gc_allowPrivateIP))
|
||||
bIsAllowExternalLocalFiles = NSProcessEnv::GetBoolValue(NSProcessEnv::Converter::gc_allowPrivateIP);
|
||||
|
||||
int nImageId = -1;
|
||||
std::wstring sImageSrc, sExtention;
|
||||
// Предполагаем картинку в Base64
|
||||
if (sSrcM.length() > 4 && sSrcM.substr(0, 4) == L"data" && sSrcM.find(L"/", 4) != std::wstring::npos)
|
||||
bRes = readBase64(sSrcM, sExtention);
|
||||
|
||||
if (!bRes)
|
||||
{
|
||||
// Проверка расширения
|
||||
sExtention = NSFile::GetFileExtention(sSrcM);
|
||||
std::transform(sExtention.begin(), sExtention.end(), sExtention.begin(), tolower);
|
||||
if (NotValidExtension(sExtention))
|
||||
{
|
||||
ImageAlternative(oXml, sSelectors, oTS, wsAlt);
|
||||
return;
|
||||
}
|
||||
|
||||
// Проверка на повтор
|
||||
std::vector<std::wstring>::iterator nFind = std::find(m_arrImages.begin(), m_arrImages.end(), sSrcM);
|
||||
if (nFind != m_arrImages.end())
|
||||
{
|
||||
bRes = true;
|
||||
nImageId = nFind - m_arrImages.begin();
|
||||
}
|
||||
}
|
||||
|
||||
if (!bRes)
|
||||
{
|
||||
sImageSrc = sSrcM;
|
||||
std::wstring wsDst = m_sDst + L"/word/media/i" + std::to_wstring(m_arrImages.size()) + L'.' + sExtention;
|
||||
|
||||
// Предполагаем картинку по локальному пути
|
||||
if (!((!m_sBase.empty() && m_sBase.length() > 4 && m_sBase.substr(0, 4) == L"http") || (sSrcM.length() > 4 && sSrcM.substr(0, 4) == L"http")))
|
||||
{
|
||||
if (!m_sBase.empty())
|
||||
{
|
||||
if (!bRes)
|
||||
bRes = CopyImage(NSSystemPath::Combine(m_sBase, sSrcM), wsDst, bIsAllowExternalLocalFiles);
|
||||
if (!bRes)
|
||||
bRes = CopyImage(NSSystemPath::Combine(m_sSrc, m_sBase + sSrcM), wsDst, bIsAllowExternalLocalFiles);
|
||||
}
|
||||
if (!bRes)
|
||||
bRes = CopyImage(NSSystemPath::Combine(m_sSrc, sSrcM), wsDst, bIsAllowExternalLocalFiles);
|
||||
if (!bRes)
|
||||
bRes = CopyImage(m_sSrc + L"/" + NSFile::GetFileName(sSrcM), wsDst, bIsAllowExternalLocalFiles);
|
||||
if (!bRes)
|
||||
bRes = CopyImage(sSrcM, wsDst, bIsAllowExternalLocalFiles);
|
||||
}
|
||||
// Предполагаем картинку в сети
|
||||
else
|
||||
{
|
||||
// Проверка gc_allowNetworkRequest предполагается в kernel_network
|
||||
NSNetwork::NSFileTransport::CFileDownloader oDownloadImg(m_sBase + sSrcM, false);
|
||||
oDownloadImg.SetFilePath(wsDst);
|
||||
bRes = oDownloadImg.DownloadSync();
|
||||
}
|
||||
}
|
||||
|
||||
if (!bRes)
|
||||
ImageAlternative(oXml, sSelectors, oTS, wsAlt);
|
||||
else
|
||||
{
|
||||
wrP(oXml, sSelectors, oTS);
|
||||
oXml->WriteString(L"<w:r>");
|
||||
wrR(oXml, sSelectors, oTS);
|
||||
oXml->WriteString(L"<w:t xml:space=\"preserve\">");
|
||||
oXml->WriteEncodeXmlString(wsAlt);
|
||||
oXml->WriteString(L"</w:t></w:r>");
|
||||
ImageRels(oXml, nImageId, sImageSrc, sExtention);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1967,24 +1984,34 @@ private:
|
||||
return sRStyle;
|
||||
}
|
||||
|
||||
bool ImageRels (NSStringUtils::CStringBuilder* oXml, const std::wstring& sImageId, const std::wstring& sImageName)
|
||||
void ImageRels (NSStringUtils::CStringBuilder* oXml, int nImageId, const std::wstring& sImageSrc, const std::wstring& sExtention)
|
||||
{
|
||||
CBgraFrame oBgraFrame;
|
||||
if(!oBgraFrame.OpenFile(m_sDst + L"/word/media/" + sImageName))
|
||||
return false;
|
||||
bool bNew = nImageId < 0;
|
||||
if (bNew)
|
||||
nImageId = m_arrImages.size();
|
||||
|
||||
std::wstring sImageId = std::to_wstring(nImageId);
|
||||
std::wstring sImageName = sImageId + L'.' + sExtention;
|
||||
CBgraFrame oBgraFrame;
|
||||
if (!oBgraFrame.OpenFile(m_sDst + L"/word/media/i" + sImageName))
|
||||
return;
|
||||
|
||||
m_nImageId++;
|
||||
// Прописать рельсы
|
||||
m_oDocXmlRels.WriteString(L"<Relationship Id=\"rPic");
|
||||
m_oDocXmlRels.WriteString(sImageId);
|
||||
m_oDocXmlRels.WriteString(L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/");
|
||||
m_oDocXmlRels.WriteString(sImageName);
|
||||
m_oDocXmlRels.WriteString(L"\"/>");
|
||||
if (bNew)
|
||||
{
|
||||
m_arrImages.push_back(sImageSrc);
|
||||
|
||||
m_oDocXmlRels.WriteString(L"<Relationship Id=\"rPic");
|
||||
m_oDocXmlRels.WriteString(sImageId);
|
||||
m_oDocXmlRels.WriteString(L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/i");
|
||||
m_oDocXmlRels.WriteEncodeXmlString(sImageName);
|
||||
m_oDocXmlRels.WriteString(L"\"/>");
|
||||
}
|
||||
|
||||
// Получаем размеры картинки
|
||||
int nHy = oBgraFrame.get_Height();
|
||||
int nWx = oBgraFrame.get_Width();
|
||||
if(nWx > nHy)
|
||||
if (nWx > nHy)
|
||||
{
|
||||
int nW = nWx * 9525;
|
||||
nW = (nW > 7000000 ? 7000000 : nW);
|
||||
@ -1996,7 +2023,7 @@ private:
|
||||
int nH = nHy * 9525;
|
||||
nH = (nH > 8000000 ? 8000000 : nH);
|
||||
int nW = (int)((double)nWx * (double)nH / (double)nHy);
|
||||
if(nW > 7000000)
|
||||
if (nW > 7000000)
|
||||
{
|
||||
nW = 7000000;
|
||||
nHy = (int)((double)nHy * (double)nW / (double)nWx);
|
||||
@ -2022,7 +2049,6 @@ private:
|
||||
oXml->WriteString(L"\" cy=\"");
|
||||
oXml->WriteString(std::to_wstring(nHy));
|
||||
oXml->WriteString(L"\"/></a:xfrm><a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom></pic:spPr></pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing></w:r>");
|
||||
return true;
|
||||
}
|
||||
|
||||
void readNote (NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const std::wstring& sNote)
|
||||
@ -2053,7 +2079,7 @@ private:
|
||||
// Сохранить как .svg картинку
|
||||
NSStringUtils::CStringBuilder oSVG;
|
||||
oSVG.WriteString(L"<svg ");
|
||||
while(m_oLightReader.MoveToNextAttribute())
|
||||
while (m_oLightReader.MoveToNextAttribute())
|
||||
{
|
||||
std::wstring sName = m_oLightReader.GetName();
|
||||
if(sName.find(L"xmlns") != std::wstring::npos)
|
||||
@ -2068,7 +2094,7 @@ private:
|
||||
|
||||
std::wstring sSVG = m_oLightReader.GetInnerXml();
|
||||
size_t nRef = sSVG.find(L"image");
|
||||
while(nRef != std::wstring::npos)
|
||||
while (nRef != std::wstring::npos)
|
||||
{
|
||||
size_t nRefBegin = sSVG.rfind(L'<', nRef);
|
||||
if (nRefBegin != std::wstring::npos)
|
||||
@ -2081,10 +2107,10 @@ private:
|
||||
|
||||
size_t nRefEnd = sSVG.find(L'>', nRef);
|
||||
size_t nHRef = sSVG.find(L"href", nRef);
|
||||
if(nHRef == std::wstring::npos || nRefEnd == std::wstring::npos)
|
||||
if (nHRef == std::wstring::npos || nRefEnd == std::wstring::npos)
|
||||
break;
|
||||
nHRef += 6;
|
||||
if(nHRef > nRefEnd || sSVG.compare(nHRef, 4, L"http") == 0)
|
||||
if (nHRef > nRefEnd || sSVG.compare(nHRef, 4, L"http") == 0)
|
||||
{
|
||||
nRef = sSVG.find(L"image", nRef + 5);
|
||||
continue;
|
||||
@ -2107,9 +2133,9 @@ private:
|
||||
oSVG.WriteString(sSVG);
|
||||
oSVG.WriteString(L"</svg>");
|
||||
|
||||
std::wstring sImageId = std::to_wstring(m_nImageId);
|
||||
std::wstring sImageId = std::to_wstring(m_arrImages.size());
|
||||
NSFile::CFileBinary oSVGWriter;
|
||||
std::wstring sImageFile = m_sDst + L"/word/media/" + sImageId + L".svg";
|
||||
std::wstring sImageFile = m_sDst + L"/word/media/i" + sImageId + L".svg";
|
||||
if (oSVGWriter.CreateFileW(sImageFile))
|
||||
{
|
||||
oSVGWriter.WriteStringUTF8(oSVG.GetData());
|
||||
@ -2120,15 +2146,15 @@ private:
|
||||
NSFonts::IApplicationFonts* pFonts = NSFonts::NSApplication::Create();
|
||||
MetaFile::IMetaFile* pMetafile = MetaFile::Create(pFonts);
|
||||
bool bLoad = pMetafile->LoadFromFile(sImageFile.data());
|
||||
if(bLoad)
|
||||
if (bLoad)
|
||||
{
|
||||
std::wstring sPngFile = m_sDst + L"/word/media/" + sImageId + L".png";
|
||||
std::wstring sPngFile = m_sDst + L"/word/media/i" + sImageId + L".png";
|
||||
pMetafile->ConvertToRaster(sPngFile.data(), 4, 1000);
|
||||
}
|
||||
pMetafile->Release();
|
||||
pFonts->Release();
|
||||
|
||||
ImageRels(oXml, sImageId, sImageId + L".png");
|
||||
ImageRels(oXml, -1, L"", L"png");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user