diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp
index 62304876c3..0fc17c61ab 100644
--- a/HtmlFile2/htmlfile2.cpp
+++ b/HtmlFile2/htmlfile2.cpp
@@ -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; // записан?
bool m_bWasSpace; // Был пробел?
+ std::vector m_arrImages; // Картинки
std::map 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& sSelectors, const CTextSettings& oTS, const std::wstring& wsAlt)
+ {
+ if (wsAlt.empty())
+ return;
+
+ wrP(oXml, sSelectors, oTS);
+ oXml->WriteString(L"");
+ wrR(oXml, sSelectors, oTS);
+ oXml->WriteString(L"");
+ oXml->WriteEncodeXmlString(wsAlt);
+ oXml->WriteString(L"");
+ }
+
void readImage (NSStringUtils::CStringBuilder* oXml, std::vector& 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::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"");
- wrR(oXml, sSelectors, oTS);
- oXml->WriteString(L"");
- oXml->WriteEncodeXmlString(wsAlt);
- oXml->WriteString(L"");
+ 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"");
+ if (bNew)
+ {
+ m_arrImages.push_back(sImageSrc);
+
+ 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"\"/>");
- return true;
}
void readNote (NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const std::wstring& sNote)
@@ -2053,7 +2079,7 @@ private:
// Сохранить как .svg картинку
NSStringUtils::CStringBuilder oSVG;
oSVG.WriteString(L"");
- 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");
}
};