Compare commits

..

8 Commits

9 changed files with 908 additions and 26 deletions

View File

@ -82,6 +82,7 @@ namespace PPTX
}
void UniEffect::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader)
{
LONG pos = pReader->GetPos();
ULONG rec_len = pReader->GetULong();
if (0 == rec_len)
return;
@ -92,11 +93,43 @@ namespace PPTX
{
case EFFECT_TYPE_ALPHAMODFIX: Effect = new PPTX::Logic::AlphaModFix(); break;
case EFFECT_TYPE_DUOTONE: Effect = new PPTX::Logic::Duotone(); break;
case EFFECT_TYPE_OUTERSHDW: Effect = new PPTX::Logic::OuterShdw(); break;
case EFFECT_TYPE_GLOW: Effect = new PPTX::Logic::Glow(); break;
case EFFECT_TYPE_XFRM: Effect = new PPTX::Logic::XfrmEffect(); break;
case EFFECT_TYPE_BLUR: Effect = new PPTX::Logic::Blur(); break;
case EFFECT_TYPE_PRSTSHDW: Effect = new PPTX::Logic::PrstShdw(); break;
case EFFECT_TYPE_INNERSHDW: Effect = new PPTX::Logic::InnerShdw(); break;
case EFFECT_TYPE_REFLECTION: Effect = new PPTX::Logic::Reflection(); break;
case EFFECT_TYPE_SOFTEDGE: Effect = new PPTX::Logic::SoftEdge(); break;
case EFFECT_TYPE_FILLOVERLAY: Effect = new PPTX::Logic::FillOverlay(); break;
case EFFECT_TYPE_ALPHACEILING: Effect = new PPTX::Logic::AlphaCeiling(); break;
case EFFECT_TYPE_ALPHAFLOOR: Effect = new PPTX::Logic::AlphaFloor(); break;
case EFFECT_TYPE_TINTEFFECT: Effect = new PPTX::Logic::TintEffect(); break;
case EFFECT_TYPE_RELOFF: Effect = new PPTX::Logic::RelOff(); break;
case EFFECT_TYPE_LUM: Effect = new PPTX::Logic::LumEffect(); break;
case EFFECT_TYPE_HSL: Effect = new PPTX::Logic::HslEffect(); break;
case EFFECT_TYPE_GRAYSCL: Effect = new PPTX::Logic::Grayscl(); break;
case EFFECT_TYPE_ALPHAREPL: Effect = new PPTX::Logic::AlphaRepl(); break;
case EFFECT_TYPE_ALPHAOUTSET: Effect = new PPTX::Logic::AlphaOutset(); break;
case EFFECT_TYPE_ALPHABILEVEL: Effect = new PPTX::Logic::AlphaBiLevel(); break;
case EFFECT_TYPE_BILEVEL: Effect = new PPTX::Logic::BiLevel(); break;
case EFFECT_TYPE_FILL: Effect = new PPTX::Logic::FillEffect(); break;
case EFFECT_TYPE_CLRREPL: Effect = new PPTX::Logic::ClrRepl(); break;
case EFFECT_TYPE_CLRCHANGE: Effect = new PPTX::Logic::ClrChange(); break;
case EFFECT_TYPE_ALPHAINV: Effect = new PPTX::Logic::AlphaInv(); break;
case EFFECT_TYPE_ALPHAMOD: Effect = new PPTX::Logic::AlphaMod(); break;
case EFFECT_TYPE_BLEND: Effect = new PPTX::Logic::Blend(); break;
}
pReader->Seek(pos);
if (Effect.is_init())
{
Effect->fromPPTY(pReader);
}
else
{
pReader->SkipRecord();
}
}
UniEffect::UniEffect(XmlUtils::CXmlNode& node)
{

View File

@ -1094,11 +1094,10 @@ bool RtfParagraphPropsCommand::ExecuteCommand(RtfDocument& oDocument, RtfReader&
else
{
paragraphProps->m_bInTable = 1;
if ( PROP_DEF == paragraphProps->m_nItap )
if ( PROP_DEF == paragraphProps->m_nItap)
paragraphProps->m_nItap = 1;
}
}
COMMAND_RTF_BOOL( "intbl", paragraphProps->m_bInTable, sCommand, hasParameter, parameter )
else if ( "itap" == sCommand && hasParameter)
{
//if (parameter == 0 && paragraphProps->m_bInTable && paragraphProps->m_nItap > 0)
@ -2340,6 +2339,32 @@ bool RtfOldListReader::ExecuteCommand( RtfDocument& oDocument, RtfReader& oReade
return false;
return true;
}
void RtfParagraphPropDestination::EndRows(RtfReader& oReader)
{
RtfTableRowPtr oNewTableRow ( new RtfTableRow() );
oNewTableRow->m_oProperty = oReader.m_oState->m_oRowProperty;
for( int k = (int)aCells.size() - 1; k >= 0 ; k-- )
{
if ( aCellItaps[k] == nCurItap )
{
oNewTableRow->InsertItem( aCells[k], 0 );
aCells.erase(aCells.begin() + k);
aCellItaps.erase(aCellItaps.begin() + k);
}
else
break;
}
//для каждого cell в row добавляем их свойства
for( int i = 0; i < oNewTableRow->GetCount() && i < oNewTableRow->m_oProperty.GetCount() ; i++ )
{
oNewTableRow->operator [](i)->m_oProperty = oNewTableRow->m_oProperty[i];
}
//Добавляем временный row
aRows.push_back( oNewTableRow );
aRowItaps.push_back( nCurItap );
}
//-------------------------------------------------------------------------------------------------------------------------------------------
void RtfParagraphPropDestination::AddItem( RtfParagraphPtr oItem, RtfReader& oReader, bool bEndCell, bool bEndRow )
@ -2351,6 +2376,8 @@ void RtfParagraphPropDestination::AddItem( RtfParagraphPtr oItem, RtfReader& oRe
{
if ( nCurItap > 0 ) //Если до этого были только параграфы в таблицах - завершаем таблицу
{
if (bEndRow) EndRows(oReader); //ê¡ñ¿ó¿ñπá½∞¡á∩ »α«úαá¼¼á.rtf
RtfTablePtr oNewTable ( new RtfTable() );
oNewTable->m_oProperty = oCurRowProperty;
@ -2416,30 +2443,10 @@ void RtfParagraphPropDestination::AddItem( RtfParagraphPtr oItem, RtfReader& oRe
aItaps.push_back( oItem->m_oProperty.m_nItap );
}
nCurItap = oItem->m_oProperty.m_nItap;
//закончилась строка
if ( bEndRow )
{
RtfTableRowPtr oNewTableRow ( new RtfTableRow() );
oNewTableRow->m_oProperty = oReader.m_oState->m_oRowProperty;
for( int k = (int)aCells.size() - 1; k >= 0 ; k-- )
{
if ( aCellItaps[k] == nCurItap )
{
oNewTableRow->InsertItem( aCells[k], 0 );
aCells.erase(aCells.begin() + k);
aCellItaps.erase(aCellItaps.begin() + k);
}
else
break;
}
//для каждого cell в row добавляем их свойства
for( int i = 0; i < (int)oNewTableRow->GetCount() && i < oNewTableRow->m_oProperty.GetCount() ; i++ )
oNewTableRow->operator [](i)->m_oProperty = oNewTableRow->m_oProperty[i];
//Добавляем временный row
aRows.push_back( oNewTableRow );
aRowItaps.push_back( nCurItap );
EndRows(oReader);
}
else
{

View File

@ -1656,6 +1656,7 @@ public:
void Finalize( RtfReader& oReader);
void EndRows(RtfReader& oReader);
void ExecuteNumberChar( RtfDocument& oDocument, RtfReader& oReader, RtfAbstractReader& oAbstrReader, int nWinChar, int nMacChar )
{
RtfFont oFont;

View File

@ -704,7 +704,7 @@ namespace ComplexTypes
std::wstring sResult;
if ( m_sVal.IsInit() )
sResult += XmlUtils::EncodeXmlString(m_sVal.get(), false);
sResult += m_sVal.get();
return sResult;
}

View File

@ -51,6 +51,9 @@ namespace NSOnlineOfficeBinToPdf
int m_nRasterW;
int m_nRasterH;
double m_dDpiX;
double m_dDpiY;
std::vector<std::wstring> m_arTempFiles;
public:
@ -70,6 +73,9 @@ namespace NSOnlineOfficeBinToPdf
m_nRasterW = 100;
m_nRasterH = 100;
m_dDpiX = 96.0;
m_dDpiY = 96.0;
}
~CMetafileToRenderterRaster_private()
@ -228,6 +234,14 @@ namespace NSOnlineOfficeBinToPdf
nRasterW = (int)(w * dKoef1 + 0.5);
nRasterH = (int)(h * dKoef1 + 0.5);
}
else if (2 == m_internal->m_nSaveType)
{
double w = oInfo.arSizes[nPageIndex].width;
double h = oInfo.arSizes[nPageIndex].height;
nRasterW = (int)((w * m_internal->m_dDpiX / 25.4) + 0.5);
nRasterH = (int)((h * m_internal->m_dDpiY / 25.4) + 0.5);
}
oFrame.put_Width(nRasterW);
oFrame.put_Height(nRasterH);
@ -347,4 +361,9 @@ namespace NSOnlineOfficeBinToPdf
{
m_internal->m_bIsOnlyFirst = value;
}
void CMetafileToRenderterRaster::SetOutputDpi(const double& dDpiX, const double& dDpiY)
{
m_internal->m_dDpiX = dDpiX;
m_internal->m_dDpiY = dDpiY;
}
}

View File

@ -81,6 +81,8 @@ namespace NSOnlineOfficeBinToPdf
bool GetIsOnlyFirst();
void SetIsOnlyFirst(const bool& value);
void SetOutputDpi(const double& dDpiX, const double& dDpiY);
};
}

View File

@ -450,7 +450,7 @@ namespace NSHtmlRenderer
m_oCurrentInfo.m_lAscent = (USHORT)(lA);
m_oCurrentInfo.m_lDescent = (USHORT)(lD);
m_oCurrentInfo.m_lLineHeight = (USHORT)(lL);
m_oCurrentInfo.m_lUnitsPerEm = (USHORT)(lD);
m_oCurrentInfo.m_lUnitsPerEm = (USHORT)(lU);
}
};

View File

@ -0,0 +1,19 @@
TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += \
$$PWD/../../../../core/Common/OfficeFileFormatChecker2.cpp \
$$PWD/../../../../core/Common/3dParty/pole/pole.cpp \
$$PWD/../../../../core/Common/DocxFormat/Source/Base/unicode_util.cpp
SOURCES += main.cpp
CORE_ROOT_DIR = $$PWD/../../../../core
PWD_ROOT_DIR = $$PWD
include($$PWD/../../../Common/base.pri)
LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lkernel -lgraphics
DESTDIR = $$PWD/build

View File

@ -0,0 +1,801 @@
#include <iostream>
#include "../../../Common/OfficeFileFormats.h"
#include "../../../Common/OfficeFileFormatChecker.h"
#include "../../../DesktopEditor/graphics/Timer.h"
#include "../../../DesktopEditor/graphics/TemporaryCS.h"
#include "../../../DesktopEditor/common/File.h"
#include "../../../DesktopEditor/common/Directory.h"
#include "../../../DesktopEditor/common/StringBuilder.h"
#include "../../../OfficeUtils/src/OfficeUtils.h"
#include "../../../DesktopEditor/fontengine/application_generate_fonts.h"
class CConverter;
class CInternalWorker
{
public:
std::map<int, bool> m_formats;
std::vector<std::wstring> m_files;
int m_nCount;
int m_nCurrent;
int m_nCurrentComplete;
std::wstring m_sInputFolder;
std::wstring m_sOutputFolder;
bool m_bIsStandard;
NSCriticalSection::CRITICAL_SECTION m_oCS;
NSCriticalSection::CRITICAL_SECTION m_oCS_OfficeUtils;
public:
CInternalWorker()
{
m_formats.insert(std::make_pair<int, bool>(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX, true));
m_formats.insert(std::make_pair<int, bool>(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC, true));
m_formats.insert(std::make_pair<int, bool>(AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT, true));
m_formats.insert(std::make_pair<int, bool>(AVS_OFFICESTUDIO_FILE_DOCUMENT_RTF, true));
m_formats.insert(std::make_pair<int, bool>(AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT, true));
m_formats.insert(std::make_pair<int, bool>(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX, true));
m_formats.insert(std::make_pair<int, bool>(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX, true));
m_formats.insert(std::make_pair<int, bool>(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPT, true));
m_formats.insert(std::make_pair<int, bool>(AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP, true));
m_formats.insert(std::make_pair<int, bool>(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX, true));
m_formats.insert(std::make_pair<int, bool>(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLS, true));
m_formats.insert(std::make_pair<int, bool>(AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS, true));
m_formats.insert(std::make_pair<int, bool>(AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV, true));
m_nCount = 0;
m_nCurrent = 0;
m_nCurrentComplete = 0;
m_oCS.InitializeCriticalSection();
m_oCS_OfficeUtils.InitializeCriticalSection();
}
~CInternalWorker()
{
m_oCS.DeleteCriticalSection();
m_oCS_OfficeUtils.DeleteCriticalSection();
}
CConverter* GetNextConverter();
void OnConvertFile(CConverter* pConverter, int nCode);
void Start(int nCores);
void Cancel();
void OpenDir(std::wstring sDir)
{
m_sInputFolder = sDir;
std::vector<std::wstring> arFiles = NSDirectory::GetFiles(sDir, true);
for (std::vector<std::wstring>::iterator iter = arFiles.begin(); iter != arFiles.end(); iter++)
{
std::wstring sExt = NSFile::GetFileExtention(*iter);
if (sExt == L"docx" || sExt == L"pptx" || sExt == L"xlsx")
m_files.push_back(*iter);
}
m_nCount = (int)m_files.size();
}
bool IsWork()
{
CTemporaryCS oCS(&m_oCS);
return (m_nCurrentComplete < m_nCount);
}
};
namespace NSX2T
{
int Convert(const std::wstring& sConverterPath, const std::wstring sXmlPath)
{
int nReturnCode = 0;
std::wstring sConverterExe = sConverterPath;
#ifdef WIN32
NSCommon::string_replace(sConverterExe, L"/", L"\\");
sConverterExe += L".exe";
std::wstring sApp = L"x2t ";
STARTUPINFO sturtupinfo;
ZeroMemory(&sturtupinfo,sizeof(STARTUPINFO));
sturtupinfo.cb = sizeof(STARTUPINFO);
sApp += (L"\"" + sXmlPath + L"\"");
wchar_t* pCommandLine = NULL;
if (true)
{
pCommandLine = new wchar_t[sApp.length() + 1];
memcpy(pCommandLine, sApp.c_str(), sApp.length() * sizeof(wchar_t));
pCommandLine[sApp.length()] = (wchar_t)'\0';
}
HANDLE ghJob = CreateJobObject(NULL, NULL);
if (ghJob)
{
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 };
// Configure all child processes associated with the job to terminate when the
jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
if ( 0 == SetInformationJobObject( ghJob, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)))
{
CloseHandle(ghJob);
ghJob = NULL;
}
}
PROCESS_INFORMATION processinfo;
ZeroMemory(&processinfo,sizeof(PROCESS_INFORMATION));
BOOL bResult = CreateProcessW(sConverterExe.c_str(), pCommandLine,
NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &sturtupinfo, &processinfo);
if (bResult && ghJob)
{
AssignProcessToJobObject(ghJob, processinfo.hProcess);
}
::WaitForSingleObject(processinfo.hProcess, INFINITE);
RELEASEARRAYOBJECTS(pCommandLine);
//get exit code
DWORD dwExitCode = 0;
if (GetExitCodeProcess(processinfo.hProcess, &dwExitCode))
{
nReturnCode = (int)dwExitCode;
}
CloseHandle(processinfo.hProcess);
CloseHandle(processinfo.hThread);
if (ghJob)
{
CloseHandle(ghJob);
ghJob = NULL;
}
#endif
#ifdef LINUX
pid_t pid = fork(); // create child process
int status;
std::string sProgramm = U_TO_UTF8(sConverterExe);
std::string sXmlA = U_TO_UTF8(sXmlPath);
switch (pid)
{
case -1: // error
break;
case 0: // child process
{
std::string sLibraryDir = sProgramm;
std::string sPATH = sProgramm;
if (std::string::npos != sProgramm.find_last_of('/'))
{
sLibraryDir = "LD_LIBRARY_PATH=" + sProgramm.substr(0, sProgramm.find_last_of('/'));
sPATH = "PATH=" + sProgramm.substr(0, sProgramm.find_last_of('/'));
}
#ifdef _MAC
sLibraryDir = "DY" + sLibraryDir;
#endif
const char* nargs[3];
nargs[0] = sProgramm.c_str();
nargs[1] = sXmlA.c_str();
nargs[2] = NULL;
#ifndef _MAC
const char* nenv[2];
nenv[0] = sLibraryDir.c_str();
nenv[1] = NULL;
#else
const char* nenv[3];
nenv[0] = sLibraryDir.c_str();
nenv[1] = sPATH.c_str();
nenv[2] = NULL;
#endif
execve(sProgramm.c_str(),
(char * const *)nargs,
(char * const *)nenv);
exit(EXIT_SUCCESS);
break;
}
default: // parent process, pid now contains the child pid
while (-1 == waitpid(pid, &status, 0)); // wait for child to complete
if (WIFEXITED(status))
{
nReturnCode = WEXITSTATUS(status);
}
break;
}
#endif
return nReturnCode;
}
}
class CConverter : public NSThreads::CBaseThread
{
public:
CInternalWorker* m_pInternal;
std::wstring m_file;
std::wstring m_folder_dst;
int m_format;
public:
CConverter(CInternalWorker* pWorker) : NSThreads::CBaseThread()
{
m_pInternal = pWorker;
}
virtual ~CConverter()
{
Stop();
}
virtual DWORD ThreadProc()
{
COfficeFileFormatChecker oChecker;
if (!oChecker.isOfficeFile(m_file))
{
m_bRunThread = FALSE;
m_pInternal->OnConvertFile(this, -1);
return 0;
}
m_format = oChecker.nFileType;
#if 0
std::map<int, bool>::iterator find = m_pInternal->m_formats.find(m_format);
if ((find == m_pInternal->m_formats.end()) || (find->second == false))
{
m_bRunThread = FALSE;
m_pInternal->OnConvertFile(this, -1);
return 0;
}
#endif
std::wstring sProcess = NSFile::GetProcessDirectory();
NSCommon::string_replace(sProcess, L"\\", L"/");
NSCommon::string_replace(m_file, L"\\", L"/");
std::wstring sDirectoryDst = m_folder_dst;
NSCommon::string_replace(sDirectoryDst, L"\\", L"/");
#ifdef WIN32
NSCommon::string_replace(m_file, L"//", L"\\\\");
#endif
NSDirectory::CreateDirectory(sDirectoryDst);
NSStringUtils::CStringBuilder oBuilder;
oBuilder.WriteString(L"<?xml version=\"1.0\" encoding=\"utf-8\"?><TaskQueueDataConvert><m_sFileFrom>");
std::wstring sFileDst = sDirectoryDst + L"/page.zip";
oBuilder.WriteEncodeXmlString(m_file);
oBuilder.WriteString(L"</m_sFileFrom><m_sFileTo>");
oBuilder.WriteEncodeXmlString(sFileDst);
oBuilder.WriteString(L"</m_sFileTo><m_nFormatTo>");
oBuilder.WriteString(std::to_wstring(AVS_OFFICESTUDIO_FILE_IMAGE));
oBuilder.WriteString(L"</m_nFormatTo><m_sThemeDir>./</m_sThemeDir><m_bDontSaveAdditional>true</m_bDontSaveAdditional><m_sAllFontsPath>");
oBuilder.WriteString(sProcess + L"/fonts");
oBuilder.WriteString(L"/AllFonts.js</m_sAllFontsPath><m_nCsvTxtEncoding>46</m_nCsvTxtEncoding><m_nCsvDelimiter>4</m_nCsvDelimiter>");
oBuilder.WriteString(L"<m_sFontDir>");
oBuilder.WriteEncodeXmlString(sProcess + L"/fonts");
oBuilder.WriteString(L"</m_sFontDir>");
oBuilder.WriteString(L"<m_oThumbnail><format>4</format><aspect>2</aspect><first>false</first><width>1000</width><height>1000</height></m_oThumbnail>");
oBuilder.WriteString(L"</TaskQueueDataConvert>");
std::wstring sXmlConvert = oBuilder.GetData();
std::wstring sTempFileForParams = sDirectoryDst + L"/params.xml";
NSFile::CFileBinary::SaveToFile(sTempFileForParams, sXmlConvert, true);
if (NSDirectory::Exists(sProcess + L"/converter"))
sProcess += L"/converter";
std::wstring sExe = sProcess + L"/x2t";
int nReturnCode = NSX2T::Convert(sExe, sTempFileForParams);
NSFile::CFileBinary::Remove(sTempFileForParams);
if (0 == nReturnCode)
{
CTemporaryCS oCS(&m_pInternal->m_oCS_OfficeUtils);
COfficeUtils oUtils;
if (S_OK == oUtils.ExtractToDirectory(sFileDst, sDirectoryDst, NULL, 0))
NSFile::CFileBinary::Remove(sFileDst);
}
if (!m_pInternal->m_bIsStandard)
{
// смотрим разницу
std::wstring strDirIn = NSFile::GetDirectoryName(m_file);
std::wstring strDirOut = sDirectoryDst;
std::wstring strDiffsMain = NSFile::GetDirectoryName(strDirOut) + L"/DIFF";
std::wstring strDiffs = strDiffsMain + L"/" + NSFile::GetFileName(m_file);
int nCountInPages = GetPagesCount(strDirIn);
int nCountOutPages = GetPagesCount(strDirOut);
if (nCountInPages != nCountOutPages)
{
if (!NSDirectory::Exists(strDiffsMain))
NSDirectory::CreateDirectory(strDiffsMain);
if (!NSDirectory::Exists(strDiffs))
NSDirectory::CreateDirectory(strDiffs);
if (nCountInPages > nCountOutPages)
nCountInPages = nCountOutPages;
std::wstring sFilePagesDiff = strDiffs + L"/pages_count";
NSFile::CFileBinary oFile;
oFile.CreateFileW(sFilePagesDiff);
oFile.CloseFile();
std::cout << "file (page count) : " << U_TO_UTF8(strDiffs) << std::endl;
}
for (int nPage = 0; nPage < nCountInPages; ++nPage)
{
std::wstring sPageI = strDirIn + L"/image" + std::to_wstring(nPage + 1) + L".png";
std::wstring sPageO = strDirOut + L"/image" + std::to_wstring(nPage + 1) + L".png";
std::wstring sPageDiff = strDiffs + L"/image" + std::to_wstring(nPage + 1) + L".png";
CBgraFrame frameI;
frameI.OpenFile(sPageI);
CBgraFrame frameO;
frameO.OpenFile(sPageO);
int nW_I = frameI.get_Width();
int nH_I = frameI.get_Height();
int nW_O = frameO.get_Width();
int nH_O = frameO.get_Height();
if (nW_I != nW_O || nH_I != nH_O)
{
if (!NSDirectory::Exists(strDiffsMain))
NSDirectory::CreateDirectory(strDiffsMain);
if (!NSDirectory::Exists(strDiffs))
NSDirectory::CreateDirectory(strDiffs);
std::wstring sFilePagesDiff = sPageDiff;
NSFile::CFileBinary oFile;
oFile.CreateFileW(sPageDiff);
oFile.WriteStringUTF8(L"sizes!");
oFile.CloseFile();
std::cout << "file (sizes) : " << U_TO_UTF8(sPageDiff) << ", (" << nW_I << ", " << nH_I << "), (" << nW_O << ", " << nH_O << ")" << std::endl;
continue;
}
BYTE* pDataI = frameI.get_Data();
BYTE* pDataO = frameO.get_Data();
size_t sizeMemory = 4 * nW_I * nH_I;
if (0 == memcmp(pDataI, pDataO, sizeMemory))
continue;
sizeMemory = nW_I * nH_I;
for (size_t pix = 0; pix < sizeMemory; ++pix)
{
if (pDataI[0] != pDataO[0] || pDataI[1] != pDataO[1] || pDataI[2] != pDataO[2])
{
if (pDataO[0] == 0x00 && pDataO[1] == 0x00 && pDataO[2] == 0xFF)
{
pDataO[0] = 0xFF;
pDataO[1] = 0x00;
pDataO[2] = 0x00;
}
else
{
pDataO[0] = 0x00;
pDataO[1] = 0x00;
pDataO[2] = 0xFF;
}
}
pDataI += 4;
pDataO += 4;
}
if (!NSDirectory::Exists(strDiffsMain))
NSDirectory::CreateDirectory(strDiffsMain);
if (!NSDirectory::Exists(strDiffs))
NSDirectory::CreateDirectory(strDiffs);
frameO.SaveFile(sPageDiff, 4);
std::cout << "file (diffs) : " << U_TO_UTF8(sPageDiff) << std::endl;
}
}
m_bRunThread = FALSE;
m_pInternal->OnConvertFile(this, nReturnCode);
return 0;
}
int GetPagesCount(const std::wstring& dir)
{
int nCount = 0;
std::vector<std::wstring> files = NSDirectory::GetFiles(dir, false);
for (std::vector<std::wstring>::iterator i = files.begin(); i != files.end(); i++)
{
std::wstring sExt = NSFile::GetFileExtention(*i);
if (sExt == L"png")
++nCount;
}
return nCount;
}
};
CConverter* CInternalWorker::GetNextConverter()
{
if (m_nCurrent >= m_nCount)
return NULL;
CConverter* pConverter = new CConverter(this);
pConverter->m_file = m_files[m_nCurrent];
++m_nCurrent;
std::wstring sName = NSFile::GetFileName(pConverter->m_file);
pConverter->m_folder_dst = m_sOutputFolder + L"/" + sName;
NSDirectory::CreateDirectory(pConverter->m_folder_dst);
if (m_bIsStandard)
NSFile::CFileBinary::Copy(pConverter->m_file, pConverter->m_folder_dst + L"/" + sName);
pConverter->Start(0);
return pConverter;
}
void CInternalWorker::OnConvertFile(CConverter* pConverter, int nCode)
{
CTemporaryCS oCS(&m_oCS);
std::cout << "file (complete) : " << U_TO_UTF8(m_files[m_nCurrentComplete]) << ", code : " << nCode << std::endl;
++m_nCurrentComplete;
RELEASEOBJECT(pConverter);
GetNextConverter();
}
void CInternalWorker::Start(int nCores)
{
CTemporaryCS oCS(&m_oCS);
int nSizeInit = nCores;
if (nSizeInit > m_nCount)
nSizeInit = m_nCount;
for (int i = 0; i < nSizeInit; ++i)
GetNextConverter();
}
void CInternalWorker::Cancel()
{
CTemporaryCS oCS(&m_oCS);
m_nCount = m_nCurrent;
}
#define ONLYOFFICE_FONTS_VERSION_ 1
void CheckFonts(const bool& bIsUseSystemFonts, std::vector<std::wstring>& arDirs)
{
std::vector<std::string> strFonts;
std::wstring strDirectory = NSFile::GetProcessDirectory() + L"/fonts";
if (!NSDirectory::Exists(strDirectory))
NSDirectory::CreateDirectory(strDirectory);
std::wstring strAllFontsJSPath = strDirectory + L"/AllFonts.js";
std::wstring strThumbnailsFolder = strDirectory;
std::wstring strFontsSelectionBin = strDirectory + L"/font_selection.bin";
if (true)
{
NSFile::CFileBinary oFile;
if (oFile.OpenFile(strDirectory + L"/fonts.log"))
{
int nSize = oFile.GetFileSize();
char* pBuffer = new char[nSize];
DWORD dwReaden = 0;
oFile.ReadFile((BYTE*)pBuffer, nSize, dwReaden);
oFile.CloseFile();
int nStart = 0;
int nCur = nStart;
for (; nCur < nSize; ++nCur)
{
if (pBuffer[nCur] == '\n')
{
int nEnd = nCur - 1;
if (nEnd > nStart)
{
std::string s(pBuffer + nStart, nEnd - nStart + 1);
strFonts.push_back(s);
}
nStart = nCur + 1;
}
}
delete[] pBuffer;
}
if (0 != strFonts.size())
{
// check version!!!
std::string sOO_Version = strFonts[0];
if (0 != sOO_Version.find("ONLYOFFICE_FONTS_VERSION_"))
{
strFonts.clear();
}
else
{
std::string sVersion = sOO_Version.substr(25);
int nVersion = std::stoi(sVersion);
if (nVersion != ONLYOFFICE_FONTS_VERSION_)
strFonts.clear();
else
strFonts.erase(strFonts.begin());
}
}
}
NSFonts::IApplicationFonts* oApplicationF = NSFonts::NSApplication::Create();
std::vector<std::wstring> strFontsW_Cur;
if (bIsUseSystemFonts)
strFontsW_Cur = oApplicationF->GetSetupFontFiles();
for (std::vector<std::wstring>::iterator i = arDirs.begin(); i != arDirs.end(); i++)
{
NSDirectory::GetFiles2(*i, strFontsW_Cur, true);
}
#if defined(_LINUX)
std::wstring sHome = GetHomeDirectory();
if (!sHome.empty())
{
#ifdef _MAC
NSDirectory::GetFiles2(sHome + L"/Library/Fonts", strFontsW_Cur, true);
#else
NSDirectory::GetFiles2(sHome + L"/.fonts", strFontsW_Cur, true);
NSDirectory::GetFiles2(sHome + L"/.local/share/fonts", strFontsW_Cur, true);
#endif
}
#endif
bool bIsEqual = true;
if (strFonts.size() != strFontsW_Cur.size())
bIsEqual = false;
if (bIsEqual)
{
int nCount = (int)strFonts.size();
for (int i = 0; i < nCount; ++i)
{
if (strFonts[i] != NSFile::CUtf8Converter::GetUtf8StringFromUnicode2(strFontsW_Cur[i].c_str(), strFontsW_Cur[i].length()))
{
bIsEqual = false;
break;
}
}
}
if (bIsEqual)
{
if (!NSFile::CFileBinary::Exists(strFontsSelectionBin))
bIsEqual = false;
}
if (!bIsEqual)
{
if (NSFile::CFileBinary::Exists(strAllFontsJSPath))
NSFile::CFileBinary::Remove(strAllFontsJSPath);
if (NSFile::CFileBinary::Exists(strFontsSelectionBin))
NSFile::CFileBinary::Remove(strFontsSelectionBin);
if (strFonts.size() != 0)
NSFile::CFileBinary::Remove(strDirectory + L"/fonts.log");
NSFile::CFileBinary oFile;
oFile.CreateFileW(strDirectory + L"/fonts.log");
oFile.WriteStringUTF8(L"ONLYOFFICE_FONTS_VERSION_");
oFile.WriteStringUTF8(std::to_wstring(ONLYOFFICE_FONTS_VERSION_));
oFile.WriteFile((BYTE*)"\n", 1);
int nCount = (int)strFontsW_Cur.size();
for (int i = 0; i < nCount; ++i)
{
oFile.WriteStringUTF8(strFontsW_Cur[i]);
oFile.WriteFile((BYTE*)"\n", 1);
}
oFile.CloseFile();
int nFlag = 3;
oApplicationF->InitializeFromArrayFiles(strFontsW_Cur, nFlag);
NSCommon::SaveAllFontsJS(oApplicationF, strAllFontsJSPath, strThumbnailsFolder, strFontsSelectionBin);
}
oApplicationF->Release();
}
std::wstring CorrectDir(const std::wstring& sDir)
{
if (sDir.empty())
return L"";
const wchar_t* data = sDir.c_str();
std::wstring::size_type pos1 = (data[0] == '\"') ? 1 : 0;
std::wstring::size_type pos2 = sDir.length();
if (data[pos2 - 1] == '\"')
--pos2;
if (pos2 > 0 && ((data[pos2 - 1] == '\\') || (data[pos2 - 1] == '/')))
--pos2;
return sDir.substr(pos1, pos2 - pos1);
}
/*
*
* --input="input-standard-files-dir"
* --output="output-dir"
* --standard // generate standarts
* --use-system-fonts="0/1/false/true"
* --font-dirs="C:\\Windows\\Fonts;/usr/share/fonts;"
* --cores=4
*
*/
#ifdef WIN32
int wmain(int argc, wchar_t** argv)
#else
int main(int argc, char** argv)
#endif
{
std::vector<std::wstring> arFontsDirs;
bool bIsStandard = false;
std::wstring strInputFolder = L"";
std::wstring strOutputFolder = L"";
bool bIsUseSystemFonts = true;
int nCores = 1;
for (int i = 0; i < argc; ++i)
{
#ifdef WIN32
std::wstring sParam(argv[i]);
#else
std::string sParamA(argv[i]);
std::wstring sParam = UTF8_TO_U(sParamA);
#endif
if (sParam.find(L"--") == 0)
{
std::wstring sKey = L"";
std::wstring sValue = L"";
std::wstring::size_type _pos = sParam.find('=');
if (std::wstring::npos == _pos)
{
sKey = sParam;
}
else
{
sKey = sParam.substr(0, _pos);
sValue = sParam.substr(_pos + 1);
}
if (sKey == L"--input")
{
strInputFolder = CorrectDir(sValue);
}
else if (sKey == L"--output")
{
strOutputFolder = CorrectDir(sValue);
}
else if (sKey == L"--standard")
{
bIsStandard = true;
}
else if (sKey == L"--use-system-fonts")
{
if (sValue == L"0" || sValue == L"false")
bIsUseSystemFonts = false;
}
else if (sKey == L"--font-dirs")
{
const wchar_t* src = sValue.c_str();
const wchar_t* limit = src + sValue.length();
const wchar_t* srcPrev = src;
while (src < limit)
{
if (*src == ';')
{
if (srcPrev != src)
{
arFontsDirs.push_back(std::wstring(srcPrev, src - srcPrev));
}
src++;
srcPrev = src;
}
else
src++;
}
if (src > srcPrev)
{
arFontsDirs.push_back(std::wstring(srcPrev, src - srcPrev));
}
}
else if (sKey == L"--cores")
{
nCores = std::stoi(sValue);
if (nCores < 1)
nCores = 1;
}
}
}
DWORD dwTime1 = NSTimers::GetTickCount();
CheckFonts(bIsUseSystemFonts, arFontsDirs);
#if 0
if (true)
{
strInputFolder = L"D:\\standard";
strOutputFolder = L"D:\\standard\\out";
bIsStandard = true;
}
else
{
strInputFolder = L"D:\\standard\\out";
strOutputFolder = L"D:\\standard\\check";
bIsStandard = false;
}
#endif
CInternalWorker oWorker;
oWorker.OpenDir(strInputFolder);
oWorker.m_sOutputFolder = strOutputFolder;
oWorker.m_bIsStandard = bIsStandard;
if (!NSDirectory::Exists(strOutputFolder))
NSDirectory::CreateDirectories(strOutputFolder);
oWorker.Start(nCores);
while (oWorker.IsWork())
NSThreads::Sleep(500);
DWORD dwTime2 = NSTimers::GetTickCount();
DWORD dwTimeDelta = (dwTime2 - dwTime1) / 1000;
std::cout << "time: " << dwTimeDelta << std::endl;
return 0;
}