From 500f95cfb55eccce51758a66e22a163cf25da6a7 Mon Sep 17 00:00:00 2001 From: "Oleg.Korshul" Date: Tue, 1 Mar 2016 16:10:09 +0000 Subject: [PATCH] DocBuilder git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@68603 954022d7-b5bf-4e40-9824-e11837661b57 --- DesktopEditor/doctrenderer/docbuilder.cpp | 968 ++++++++++++++++++ DesktopEditor/doctrenderer/docbuilder.h | 30 + DesktopEditor/doctrenderer/doctrenderer.cpp | 13 + DesktopEditor/doctrenderer/doctrenderer.h | 2 - DesktopEditor/doctrenderer/doctrenderer.pro | 14 +- DesktopEditor/doctrenderer/memorystream.cpp | 116 +++ DesktopEditor/doctrenderer/memorystream.h | 117 +-- DesktopEditor/doctrenderer/nativecontrol.cpp | 380 +++++++ DesktopEditor/doctrenderer/nativecontrol.h | 501 ++------- DesktopEditor/doctrenderer/test/main.cpp | 16 +- .../doctrenderer/test_builder/docbuilder.pro | 58 ++ .../doctrenderer/test_builder/main.cpp | 51 + 12 files changed, 1737 insertions(+), 529 deletions(-) create mode 100644 DesktopEditor/doctrenderer/docbuilder.cpp create mode 100644 DesktopEditor/doctrenderer/docbuilder.h create mode 100644 DesktopEditor/doctrenderer/memorystream.cpp create mode 100644 DesktopEditor/doctrenderer/nativecontrol.cpp create mode 100644 DesktopEditor/doctrenderer/test_builder/docbuilder.pro create mode 100644 DesktopEditor/doctrenderer/test_builder/main.cpp diff --git a/DesktopEditor/doctrenderer/docbuilder.cpp b/DesktopEditor/doctrenderer/docbuilder.cpp new file mode 100644 index 0000000000..2aea67dc56 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.cpp @@ -0,0 +1,968 @@ +#include "docbuilder.h" +//#include "nativecontrol.h" + +#include "../xml/include/xmlutils.h" +#include + +#define ASC_APPLICATION_FONTS_NO_THUMBNAILS +#include "../ChromiumBasedEditors2/lib/src/application_generate_fonts.h" + +#include "../common/File.h" +#include "../common/Directory.h" + +#include "../../Common/OfficeFileFormats.h" +#include "../../Common/OfficeFileFormatChecker.h" + +#include "nativecontrol.h" + +template +class CScopeWrapper +{ +private: + T m_handler; + +private: + CScopeWrapper(const CScopeWrapper&) {} + void operator=(const CScopeWrapper&) {} + +public: + + CScopeWrapper(v8::Isolate* isolate) : m_handler(isolate) {} +}; + +class CV8RealTimeWorker +{ +public: + v8::Platform* m_platform; + v8::Isolate* m_isolate; + + v8::Isolate::Scope* m_isolate_scope; + v8::Locker* m_isolate_locker; + + CScopeWrapper* m_handle_scope; + v8::Local m_context; + + int m_nFileType; + +private: + static bool m_bIsInitTypedArrays; + +public: + + CV8RealTimeWorker() + { + m_nFileType = -1; + m_platform = v8::platform::CreateDefaultPlatform(); + v8::V8::InitializePlatform(m_platform); + + v8::V8::Initialize(); + v8::V8::InitializeICU(); + + if (!m_bIsInitTypedArrays) + { + m_bIsInitTypedArrays = true; + enableTypedArrays(); + } + + m_isolate = v8::Isolate::New(); + + m_isolate_scope = new v8::Isolate::Scope(m_isolate); + m_isolate_locker = new v8::Locker(m_isolate); + m_handle_scope = new CScopeWrapper(m_isolate); + + v8::Handle global = v8::ObjectTemplate::New(); + global->Set(v8::String::NewFromUtf8(m_isolate, "CreateNativeEngine"), v8::FunctionTemplate::New(m_isolate, CreateNativeObjectBuilder)); + global->Set(v8::String::NewFromUtf8(m_isolate, "CreateNativeMemoryStream"), v8::FunctionTemplate::New(m_isolate, CreateNativeMemoryStream)); + + m_context = v8::Context::New(m_isolate, NULL, global); + } + ~CV8RealTimeWorker() + { + RELEASEOBJECT(m_handle_scope); + m_context.Clear(); + + RELEASEOBJECT(m_isolate_locker); + RELEASEOBJECT(m_isolate_scope); + + m_isolate->Dispose(); + v8::V8::Dispose(); + + v8::V8::ShutdownPlatform(); + delete m_platform; + m_platform = NULL; + m_isolate = NULL; + } + +public: + + void _LOGGING_ERROR_(const std::wstring& strType, const std::wstring& strError) + { + std::string sT = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strType); + std::string sE = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strError); + + std::cerr << sT << ": " << sE << std::endl; + } + + bool ExecuteCommand(const std::wstring& command, bool bIsSave = true) + { + std::string commandA = U_TO_UTF8(command); + commandA = "_api." + commandA; + + if (bIsSave) + commandA += "_api.asc_Save();"; + + v8::Context::Scope context_scope(m_context); + + v8::TryCatch try_catch; + + v8::Local source = v8::String::NewFromUtf8(m_isolate, commandA.c_str()); + v8::Local script = v8::Script::Compile(source); + + if (try_catch.HasCaught()) + { + std::wstring strCode = to_cstring(try_catch.Message()->GetSourceLine()); + std::wstring strException = to_cstring(try_catch.Message()->Get()); + + _LOGGING_ERROR_(L"execute_compile_code", strCode); + _LOGGING_ERROR_(L"execute_compile", strException); + + return false; + } + else + { + script->Run(); + + if (try_catch.HasCaught()) + { + std::wstring strCode = to_cstring(try_catch.Message()->GetSourceLine()); + std::wstring strException = to_cstring(try_catch.Message()->Get()); + + _LOGGING_ERROR_(L"execute_run_code", strCode); + _LOGGING_ERROR_(L"execute_run", strException); + + return false; + } + } + + return true; + } + + bool OpenFile(const std::wstring& path, const std::string& sString) + { + v8::Context::Scope context_scope(m_context); + + v8::TryCatch try_catch; + + v8::Local source = v8::String::NewFromUtf8(m_isolate, sString.c_str()); + v8::Local script = v8::Script::Compile(source); + + if (try_catch.HasCaught()) + { + std::wstring strCode = to_cstring(try_catch.Message()->GetSourceLine()); + std::wstring strException = to_cstring(try_catch.Message()->Get()); + + _LOGGING_ERROR_(L"sdk_compile_code", strCode); + _LOGGING_ERROR_(L"sdk_compile", strException); + + return false; + } + else + { + script->Run(); + + if (try_catch.HasCaught()) + { + std::wstring strCode = to_cstring(try_catch.Message()->GetSourceLine()); + std::wstring strException = to_cstring(try_catch.Message()->Get()); + + _LOGGING_ERROR_(L"sdk_run_code", strCode); + _LOGGING_ERROR_(L"sdk_run", strException); + + return false; + } + } + + CNativeControl* pNative = NULL; + bool bIsBreak = false; + + v8::Local global_js = m_context->Global(); + v8::Handle args[1]; + args[0] = v8::Int32::New(m_isolate, 0); + + // GET_NATIVE_ENGINE + if (!bIsBreak) + { + v8::Handle js_func_get_native = global_js->Get(v8::String::NewFromUtf8(m_isolate, "GetNativeEngine")); + v8::Local objNative; + if (js_func_get_native->IsFunction()) + { + v8::Handle func_get_native = v8::Handle::Cast(js_func_get_native); + v8::Local js_result2 = func_get_native->Call(global_js, 1, args); + + if (try_catch.HasCaught()) + { + std::wstring strCode = to_cstring(try_catch.Message()->GetSourceLine()); + std::wstring strException = to_cstring(try_catch.Message()->Get()); + + _LOGGING_ERROR_(L"run_code", strCode); + _LOGGING_ERROR_(L"run", strException); + + bIsBreak = true; + } + else + { + objNative = js_result2->ToObject(); + v8::Handle field = v8::Handle::Cast(objNative->GetInternalField(0)); + + pNative = static_cast(field->Value()); + } + } + } + + if (pNative != NULL) + { + pNative->m_strFontsDirectory = NSFile::GetProcessDirectory() + L"/sdk/Common"; + pNative->m_strImagesDirectory = path + L"/media"; + + pNative->CheckFonts(); + + if (0 == m_nFileType) + pNative->m_strEditorType = L"document"; + else if (1 == m_nFileType) + pNative->m_strEditorType = L"presentation"; + else + pNative->m_strEditorType = L"spreadsheet"; + + pNative->SetFilePath(path + L"/Editor.bin"); + + pNative->m_sChangesBuilderPath = path + L"/changes/changes0.json"; + + pNative->m_nMaxChangesNumber = -1; + } + + // OPEN + if (!bIsBreak) + { + v8::Handle js_func_open = global_js->Get(v8::String::NewFromUtf8(m_isolate, "NativeOpenFileData")); + if (js_func_open->IsFunction()) + { + v8::Handle func_open = v8::Handle::Cast(js_func_open); + + CChangesWorker oWorkerLoader; + int nVersion = oWorkerLoader.OpenNative(pNative->GetFilePath()); + + v8::Handle args_open[2]; + args_open[0] = oWorkerLoader.GetDataFull(); + args_open[1] = v8::Integer::New(m_isolate, nVersion); + + func_open->Call(global_js, 2, args_open); + + if (try_catch.HasCaught()) + { + std::wstring strCode = to_cstring(try_catch.Message()->GetSourceLine()); + std::wstring strException = to_cstring(try_catch.Message()->Get()); + + _LOGGING_ERROR_(L"open_code", strCode); + _LOGGING_ERROR_(L"open", strException); + + bIsBreak = true; + } + } + } + + if (!bIsBreak) + bIsBreak = !this->ExecuteCommand(L"asc_nativeInitBuilder();", false); + + return !bIsBreak; + } +}; + +bool CV8RealTimeWorker::m_bIsInitTypedArrays = false; + +#ifdef CreateFile +#undef CreateFile +#endif + +namespace NSDoctRenderer +{ + class CDocBuilder_Private + { + public: + CArray m_arrFiles; + + std::wstring m_strDoctSDK; + std::wstring m_strPpttSDK; + std::wstring m_strXlstSDK; + + std::wstring m_strEditorType; + std::wstring m_strFilePath; + + std::wstring m_strAllFonts; + + std::wstring m_sTmpFolder; + std::wstring m_sFileDir; + int m_nFileType; + + std::wstring m_sX2tPath; + + CV8RealTimeWorker* m_pWorker; + public: + CDocBuilder_Private() + { + m_sX2tPath = NSFile::GetProcessDirectory(); + m_pWorker = NULL; + +#if 1 + m_sX2tPath += L"/converter"; +#endif + + std::wstring sConfigDir = NSFile::GetProcessDirectory() + L"/"; + std::wstring sConfigPath = sConfigDir + L"DoctRenderer.config"; + + XmlUtils::CXmlNode oNode; + if (oNode.FromXmlFile(sConfigPath)) + { + XmlUtils::CXmlNodes oNodes; + if (oNode.GetNodes(L"file", oNodes)) + { + int nCount = oNodes.GetCount(); + XmlUtils::CXmlNode _node; + for (int i = 0; i < nCount; ++i) + { + oNodes.GetAt(i, _node); + std::wstring strFilePath = _node.GetText(); + + if (std::wstring::npos != strFilePath.find(L"AllFonts.js")) + m_strAllFonts = strFilePath; + + if (!NSFile::CFileBinary::Exists(m_strAllFonts) || NSFile::CFileBinary::Exists(sConfigDir + m_strAllFonts)) + m_strAllFonts = sConfigDir + m_strAllFonts; + + if (NSFile::CFileBinary::Exists(strFilePath) && !NSFile::CFileBinary::Exists(sConfigDir + strFilePath)) + m_arrFiles.Add(strFilePath); + else + m_arrFiles.Add(sConfigDir + strFilePath); + } + } + } + + m_strDoctSDK = L""; + m_strPpttSDK = L""; + m_strXlstSDK = L""; + + XmlUtils::CXmlNode oNodeSdk = oNode.ReadNode(L"DoctSdk"); + if (oNodeSdk.IsValid()) + m_strDoctSDK = oNodeSdk.GetText(); + + oNodeSdk = oNode.ReadNode(L"PpttSdk"); + if (oNodeSdk.IsValid()) + m_strPpttSDK = oNodeSdk.GetText(); + + oNodeSdk = oNode.ReadNode(L"XlstSdk"); + if (oNodeSdk.IsValid()) + m_strXlstSDK = oNodeSdk.GetText(); + + if (!NSFile::CFileBinary::Exists(m_strDoctSDK)) + m_strDoctSDK = sConfigDir + m_strDoctSDK; + + if (!NSFile::CFileBinary::Exists(m_strPpttSDK)) + m_strPpttSDK = sConfigDir + m_strPpttSDK; + + if (!NSFile::CFileBinary::Exists(m_strXlstSDK)) + m_strXlstSDK = sConfigDir + m_strXlstSDK; + + CheckFonts(); + + m_sTmpFolder = NSFile::CFileBinary::CreateTempFileWithUniqueName(NSFile::CFileBinary::GetTempPath(), L"DTB"); + + // под линуксом предыдущая функция создает файл!!! + if (NSFile::CFileBinary::Exists(m_sTmpFolder)) + NSFile::CFileBinary::Remove(m_sTmpFolder); + } + + ~CDocBuilder_Private() + { + CloseFile(); + } + + void CheckFonts() + { + CArray strFonts; + std::wstring strDirectory = NSCommon::GetDirectoryName(m_strAllFonts); + + std::wstring strAllFontsJSPath = strDirectory + L"/AllFonts.js"; + 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.Add(s); + } + nStart = nCur + 1; + } + } + + delete[] pBuffer; + } + } + + CApplicationFonts oApplicationF; + CArray strFontsW_Cur = oApplicationF.GetSetupFontFiles(); + + bool bIsEqual = true; + if (strFonts.GetCount() != strFontsW_Cur.GetCount()) + bIsEqual = false; + + if (bIsEqual) + { + int nCount = strFonts.GetCount(); + 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.GetCount() != 0) + NSFile::CFileBinary::Remove(strDirectory + L"/fonts.log"); + + NSFile::CFileBinary oFile; + oFile.CreateFileW(strDirectory + L"/fonts.log"); + int nCount = strFontsW_Cur.GetCount(); + for (int i = 0; i < nCount; ++i) + { + oFile.WriteStringUTF8(strFontsW_Cur[i]); + oFile.WriteFile((BYTE*)"\n", 1); + } + oFile.CloseFile(); + + oApplicationF.InitializeFromArrayFiles(strFontsW_Cur, 2); + NSCommon::SaveAllFontsJS(oApplicationF, strAllFontsJSPath, L"", strFontsSelectionBin); + } + } + + void CheckFileDir() + { + m_sFileDir = NSFile::CFileBinary::CreateTempFileWithUniqueName(m_sTmpFolder, L"DE_"); + if (NSFile::CFileBinary::Exists(m_sFileDir)) + NSFile::CFileBinary::Remove(m_sFileDir); + + NSCommon::string_replace(m_sFileDir, L"\\", L"/"); + + std::wstring::size_type nPosPoint = m_sFileDir.rfind('.'); + if (nPosPoint != std::wstring::npos && nPosPoint > m_sTmpFolder.length()) + { + m_sFileDir = m_sFileDir.substr(0, nPosPoint); + } + + m_nFileType = -1; + + NSDirectory::CreateDirectory(m_sFileDir); + } + + bool CreateFile(int type) + { + CheckFileDir(); + + std::wstring sEmptyPath = NSFile::GetProcessDirectory() + L"/empty/"; + if (type & AVS_OFFICESTUDIO_FILE_DOCUMENT) + { + sEmptyPath = sEmptyPath + L"docx.bin"; + m_nFileType = 0; + } + else if (type & AVS_OFFICESTUDIO_FILE_PRESENTATION) + { + sEmptyPath = sEmptyPath + L"pptx.bin"; + m_nFileType = 1; + } + else if (type & AVS_OFFICESTUDIO_FILE_SPREADSHEET) + { + sEmptyPath = sEmptyPath + L"xlsx.bin"; + m_nFileType = 2; + } + else + return false; + + bool bRet = NSFile::CFileBinary::Copy(sEmptyPath, m_sFileDir + L"/Editor.bin"); + if (bRet) + { + NSDirectory::CreateDirectory(m_sFileDir + L"/media"); + NSDirectory::CreateDirectory(m_sFileDir + L"/changes"); + } + + return bRet; + } + + bool OpenFile(const std::wstring& path, const std::wstring& params) + { + CheckFileDir(); + + COfficeFileFormatChecker oChecker; + if (!oChecker.isOfficeFile(path)) + return false; + + if (oChecker.nFileType & AVS_OFFICESTUDIO_FILE_DOCUMENT) + m_nFileType = 0; + if (oChecker.nFileType & AVS_OFFICESTUDIO_FILE_PRESENTATION) + m_nFileType = 1; + if (oChecker.nFileType & AVS_OFFICESTUDIO_FILE_SPREADSHEET) + m_nFileType = 2; + + NSStringUtils::CStringBuilder oBuilder; + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(path); + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(m_sFileDir); + oBuilder.WriteString(L"/Editor.bin8192"); + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(NSFile::GetProcessDirectory() + L"/sdk/Common"); + oBuilder.WriteString(L""); + oBuilder.WriteString(L"./sdk/presentationeditor/themestrue"); + oBuilder.WriteString(params); + oBuilder.WriteString(L""); + + std::wstring sXmlConvert = oBuilder.GetData(); + + std::wstring sConverterExe = m_sX2tPath + L"/x2t"; + + int nReturnCode = 0; + + std::wstring sTempFileForParams = m_sFileDir + L"/params_from.xml"; + NSFile::CFileBinary::SaveToFile(sTempFileForParams, sXmlConvert, true); + + #ifdef WIN32 + std::wstring sApp = L"x2t32 "; + + if (NSFile::CFileBinary::Exists(sConverterExe + L".exe")) + { + sApp = L"x2t "; + sConverterExe += L".exe"; + } + else + sConverterExe += L"32.exe"; + + STARTUPINFO sturtupinfo; + ZeroMemory(&sturtupinfo,sizeof(STARTUPINFO)); + sturtupinfo.cb = sizeof(STARTUPINFO); + + sApp += (L"\"" + sTempFileForParams + 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'; + } + + 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); + + ::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); + + #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(sTempFileForParams); + + 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 + + NSFile::CFileBinary::Remove(sTempFileForParams); + + if (0 == nReturnCode) + return true; + + NSDirectory::DeleteDirectory(m_sFileDir); + m_sFileDir = L""; + m_nFileType = -1; + return false; + } + + void CloseFile() + { + NSDirectory::DeleteDirectory(m_sFileDir); + m_sFileDir = L""; + m_nFileType = -1; + + RELEASEOBJECT(m_pWorker); + } + + bool SaveFile(const int& type, const std::wstring& path) + { + NSStringUtils::CStringBuilder oBuilder; + + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(m_sFileDir); + oBuilder.WriteString(L"/Editor.bin"); + oBuilder.WriteEncodeXmlString(path); + oBuilder.WriteString(L""); + oBuilder.WriteString(std::to_wstring(type)); + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(L"./sdk/presentationeditor/themes"); + oBuilder.WriteString(L"truetrue"); + oBuilder.WriteString(L"464"); + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(NSFile::GetProcessDirectory() + L"/sdk/Common"); + oBuilder.WriteString(L""); + + int nDoctRendererParam = 0; + //if (true) // печать пдф (лист = страница) + // nDoctRendererParam |= 0x02; + + oBuilder.WriteString(L""); + oBuilder.WriteString(std::to_wstring(nDoctRendererParam)); + oBuilder.WriteString(L""); + + oBuilder.WriteString(L""); + + std::wstring sXmlConvert = oBuilder.GetData(); + + std::wstring sConverterExe = m_sX2tPath + L"/x2t"; + + int nReturnCode = 0; + + std::wstring sTempFileForParams = m_sFileDir + L"/params_to.xml"; + NSFile::CFileBinary::SaveToFile(sTempFileForParams, sXmlConvert, true); + + #ifdef WIN32 + std::wstring sApp = L"x2t32 "; + + if (NSFile::CFileBinary::Exists(sConverterExe + L".exe")) + { + sApp = L"x2t "; + sConverterExe += L".exe"; + } + else + sConverterExe += L"32.exe"; + + STARTUPINFO sturtupinfo; + ZeroMemory(&sturtupinfo,sizeof(STARTUPINFO)); + sturtupinfo.cb = sizeof(STARTUPINFO); + + sApp += (L"\"" + sTempFileForParams + 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'; + } + + 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); + + ::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); + + #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(sTempFileForParams); + + 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 + + NSFile::CFileBinary::Remove(sTempFileForParams); + + if (0 == nReturnCode) + return true; + + return false; + } + + bool ExecuteCommand(const std::wstring& command) + { + if (-1 == m_nFileType) + return false; + + if (NULL == m_pWorker) + { + m_pWorker = new CV8RealTimeWorker(); + m_pWorker->m_nFileType = m_nFileType; + + bool bOpen = m_pWorker->OpenFile(m_sFileDir, GetScript()); + if (!bOpen) + return false; + } + + return m_pWorker->ExecuteCommand(command); + } + + std::string GetScript() + { + std::wstring sResourceFile; + switch (m_nFileType) + { + case 0: + { + sResourceFile = m_strDoctSDK; + break; + } + case 1: + { + sResourceFile = m_strPpttSDK; + break; + } + case 2: + { + sResourceFile = m_strXlstSDK; + break; + } + default: + return false; + } + + std::string strScript = ""; + for (size_t i = 0; i < m_arrFiles.GetCount(); ++i) + { + strScript += ReadScriptFile(m_arrFiles[i]); + strScript += "\n\n"; + } + + strScript += ReadScriptFile(sResourceFile); + + if (m_nFileType == 2) + strScript += "\n$.ready();"; + + return strScript; + } + + std::string ReadScriptFile(const std::wstring& strFile) + { + NSFile::CFileBinary oFile; + + if (!oFile.OpenFile(strFile)) + return ""; + + int nSize = (int)oFile.GetFileSize(); + if (nSize < 3) + return ""; + + BYTE* pData = new BYTE[nSize]; + DWORD dwReadSize = 0; + oFile.ReadFile(pData, (DWORD)nSize, dwReadSize); + + int nOffset = 0; + if (pData[0] == 0xEF && pData[1] == 0xBB && pData[2] == 0xBF) + { + nOffset = 3; + } + + std::string sReturn((char*)(pData + nOffset), nSize - nOffset); + + RELEASEARRAYOBJECTS(pData); + return sReturn; + } + }; +} + +namespace NSDoctRenderer +{ + CDocBuilder::CDocBuilder() + { + m_pInternal = new CDocBuilder_Private(); + } + CDocBuilder::~CDocBuilder() + { + RELEASEOBJECT(m_pInternal); + } + + bool CDocBuilder::OpenFile(const std::wstring& path, const std::wstring& params) + { + m_pInternal->m_nFileType = -1; + if (!NSDirectory::Exists(m_pInternal->m_sTmpFolder)) + NSDirectory::CreateDirectory(m_pInternal->m_sTmpFolder); + + return m_pInternal->OpenFile(path, params); + } + bool CDocBuilder::CreateFile(const int& type) + { + m_pInternal->m_nFileType = -1; + if (!NSDirectory::Exists(m_pInternal->m_sTmpFolder)) + NSDirectory::CreateDirectory(m_pInternal->m_sTmpFolder); + + return m_pInternal->CreateFile(type); + } + void CDocBuilder::SetTmpFolder(const std::wstring& folder) + { + m_pInternal->m_sTmpFolder = folder; + } + bool CDocBuilder::SaveFile(const int& type, const std::wstring& path) + { + return m_pInternal->SaveFile(type, path); + } + void CDocBuilder::CloseFile() + { + m_pInternal->CloseFile(); + } + + bool CDocBuilder::ExecuteCommand(const std::wstring& command) + { + return m_pInternal->ExecuteCommand(command); + } +} diff --git a/DesktopEditor/doctrenderer/docbuilder.h b/DesktopEditor/doctrenderer/docbuilder.h new file mode 100644 index 0000000000..783474a461 --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.h @@ -0,0 +1,30 @@ +#ifndef DOCBUILDER_H +#define DOCBUILDER_H + +#include +#include +#include "../common/base_export.h" + +namespace NSDoctRenderer +{ + class CDocBuilder_Private; + class Q_DECL_EXPORT CDocBuilder + { + public: + CDocBuilder(); + ~CDocBuilder(); + + public: + bool OpenFile(const std::wstring& path, const std::wstring& params); + bool CreateFile(const int& type); + void SetTmpFolder(const std::wstring& folder); + bool SaveFile(const int& type, const std::wstring& path); + void CloseFile(); + bool ExecuteCommand(const std::wstring& command); + + private: + CDocBuilder_Private* m_pInternal; + }; +} + +#endif // DOCBUILDER_H diff --git a/DesktopEditor/doctrenderer/doctrenderer.cpp b/DesktopEditor/doctrenderer/doctrenderer.cpp index a7dad9e811..761a370c49 100644 --- a/DesktopEditor/doctrenderer/doctrenderer.cpp +++ b/DesktopEditor/doctrenderer/doctrenderer.cpp @@ -133,6 +133,19 @@ void CreateNativeObject(const v8::FunctionCallbackInfo& args) args.GetReturnValue().Set(obj); } +void CreateNativeObjectBuilder(const v8::FunctionCallbackInfo& args) +{ + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + + v8::Handle NativeObjectTemplate = CreateNativeControlTemplateBuilder(isolate); + CNativeControl* pNativeObject = new CNativeControl(); + + v8::Local obj = NativeObjectTemplate->NewInstance(); + obj->SetInternalField(0, v8::External::New(v8::Isolate::GetCurrent(), pNativeObject)); + + args.GetReturnValue().Set(obj); +} + void CreateNativeMemoryStream(const v8::FunctionCallbackInfo& args) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); diff --git a/DesktopEditor/doctrenderer/doctrenderer.h b/DesktopEditor/doctrenderer/doctrenderer.h index 8520c976f0..8f12fd7b7d 100644 --- a/DesktopEditor/doctrenderer/doctrenderer.h +++ b/DesktopEditor/doctrenderer/doctrenderer.h @@ -3,8 +3,6 @@ #include #include -#include "../common/Types.h" -#include "../common/Array.h" #include "../common/base_export.h" namespace NSDoctRenderer diff --git a/DesktopEditor/doctrenderer/doctrenderer.pro b/DesktopEditor/doctrenderer/doctrenderer.pro index 91837699a3..35bc63b552 100644 --- a/DesktopEditor/doctrenderer/doctrenderer.pro +++ b/DesktopEditor/doctrenderer/doctrenderer.pro @@ -104,6 +104,9 @@ include(../Qt_build/graphics/project/graphics_fonts.pri) LIB_XML_PRI_PATH = ../xml include(../xml/build/qt/libxml2.pri) +CONFIG += build_all_zlib build_zlib_as_sources +include(../../OfficeUtils/OfficeUtils.pri) + win32:contains(QMAKE_TARGET.arch, x86_64):{ CONFIG(debug, debug|release) { @@ -168,9 +171,18 @@ mac { } ################################################## -SOURCES += doctrenderer.cpp +SOURCES += \ + memorystream.cpp \ + nativecontrol.cpp \ + doctrenderer.cpp \ + docbuilder.cpp + +SOURCES += \ + ../../Common/OfficeFileFormatChecker2.cpp \ + ../../Common/3dParty/pole/pole.cpp HEADERS += doctrenderer.h \ + docbuilder.h \ memorystream.h \ nativecontrol.h diff --git a/DesktopEditor/doctrenderer/memorystream.cpp b/DesktopEditor/doctrenderer/memorystream.cpp new file mode 100644 index 0000000000..bb41444675 --- /dev/null +++ b/DesktopEditor/doctrenderer/memorystream.cpp @@ -0,0 +1,116 @@ +#include "memorystream.h" + +// wrap_methods ------------- +CMemoryStream* unwrap_memorystream(v8::Handle obj) +{ + v8::Handle field = v8::Handle::Cast(obj->GetInternalField(0)); + return static_cast(field->Value()); +} + +void _ms_write_byte(const v8::FunctionCallbackInfo& args) +{ + CMemoryStream* pNative = unwrap_memorystream(args.This()); + + BYTE arg = (BYTE)args[0]->Int32Value(); + pNative->WriteBYTE(arg); + + args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); +} +void _ms_write_bool(const v8::FunctionCallbackInfo& args) +{ + CMemoryStream* pNative = unwrap_memorystream(args.This()); + + BYTE arg = (BYTE)args[0]->BooleanValue(); + pNative->WriteBYTE(arg ? 1 : 0); + + args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); +} +void _ms_write_long(const v8::FunctionCallbackInfo& args) +{ + CMemoryStream* pNative = unwrap_memorystream(args.This()); + + LONG arg = (LONG)args[0]->Int32Value(); + pNative->WriteLONG(arg); + + args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); +} +void _ms_write_double(const v8::FunctionCallbackInfo& args) +{ + CMemoryStream* pNative = unwrap_memorystream(args.This()); + + double arg = (double)args[0]->NumberValue(); + pNative->WriteLONG((LONG)(arg * 100000)); + + args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); +} + +void _ms_writestring1(const v8::FunctionCallbackInfo& args) +{ + CMemoryStream* pNative = unwrap_memorystream(args.This()); + v8::String::Value data(args[0]); + pNative->WriteString((wchar_t*)*data, data.length()); + args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); +} +void _ms_writestring2(const v8::FunctionCallbackInfo& args) +{ + CMemoryStream* pNative = unwrap_memorystream(args.This()); + v8::String::Value data(args[0]); + pNative->WriteString2((wchar_t*)*data, data.length()); + args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); +} + +void _ms_copy(const v8::FunctionCallbackInfo& args) +{ + CMemoryStream* pNative = unwrap_memorystream(args.This()); + + CMemoryStream* pNative2 = unwrap_memorystream(args[0]->ToObject()); + size_t pos = (size_t)args[1]->Uint32Value(); + size_t len = (size_t)args[2]->Uint32Value(); + + pNative->Copy(pNative2, pos, len); + + args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); +} + +void _ms_clearnoattack(const v8::FunctionCallbackInfo& args) +{ + CMemoryStream* pNative = unwrap_memorystream(args.This()); + pNative->ClearNoAttack(); + args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); +} + +void _ms_pos(v8::Local name, const v8::PropertyCallbackInfo& info) +{ + CMemoryStream* pNative = unwrap_memorystream(info.Holder()); + info.GetReturnValue().Set(v8::Integer::New(v8::Isolate::GetCurrent(), pNative->GetSize())); +} + +v8::Handle CreateMemoryStreamTemplate(v8::Isolate* isolate) +{ + //v8::HandleScope handle_scope(isolate); + + v8::Local result = v8::ObjectTemplate::New(); + result->SetInternalFieldCount(1); // отводим в нем место для хранения CNativeControl + + v8::Isolate* current = v8::Isolate::GetCurrent(); + + // property + result->SetAccessor(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), "pos"), _ms_pos); // получить код ошибки + + // прописываем функции - методы объекта + result->Set(v8::String::NewFromUtf8(current, "Copy"), v8::FunctionTemplate::New(current, _ms_copy)); + result->Set(v8::String::NewFromUtf8(current, "ClearNoAttack"), v8::FunctionTemplate::New(current, _ms_clearnoattack)); + result->Set(v8::String::NewFromUtf8(current, "WriteByte"), v8::FunctionTemplate::New(current, _ms_write_byte)); + result->Set(v8::String::NewFromUtf8(current, "WriteBool"), v8::FunctionTemplate::New(current, _ms_write_bool)); + result->Set(v8::String::NewFromUtf8(current, "WriteLong"), v8::FunctionTemplate::New(current, _ms_write_long)); + result->Set(v8::String::NewFromUtf8(current, "WriteDouble"), v8::FunctionTemplate::New(current, _ms_write_double)); + result->Set(v8::String::NewFromUtf8(current, "WriteString"), v8::FunctionTemplate::New(current, _ms_writestring1)); + result->Set(v8::String::NewFromUtf8(current, "WriteString2"), v8::FunctionTemplate::New(current, _ms_writestring2)); + + // возвращаем временный хэндл хитрым образом, который переносит наш хэндл в предыдущий HandleScope и не дает ему + // уничтожиться при уничтожении "нашего" HandleScope - handle_scope + + //return handle_scope.Close(result); + return result; +} + diff --git a/DesktopEditor/doctrenderer/memorystream.h b/DesktopEditor/doctrenderer/memorystream.h index b237154301..fb97fd366f 100644 --- a/DesktopEditor/doctrenderer/memorystream.h +++ b/DesktopEditor/doctrenderer/memorystream.h @@ -151,118 +151,23 @@ public: }; // wrap_methods ------------- -CMemoryStream* unwrap_memorystream(v8::Handle obj) -{ - v8::Handle field = v8::Handle::Cast(obj->GetInternalField(0)); - return static_cast(field->Value()); -} +CMemoryStream* unwrap_memorystream(v8::Handle obj); -void _ms_write_byte(const v8::FunctionCallbackInfo& args) -{ - CMemoryStream* pNative = unwrap_memorystream(args.This()); +void _ms_write_byte(const v8::FunctionCallbackInfo& args); +void _ms_write_bool(const v8::FunctionCallbackInfo& args); +void _ms_write_long(const v8::FunctionCallbackInfo& args); +void _ms_write_double(const v8::FunctionCallbackInfo& args); - BYTE arg = (BYTE)args[0]->Int32Value(); - pNative->WriteBYTE(arg); +void _ms_writestring1(const v8::FunctionCallbackInfo& args); +void _ms_writestring2(const v8::FunctionCallbackInfo& args); - args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); -} -void _ms_write_bool(const v8::FunctionCallbackInfo& args) -{ - CMemoryStream* pNative = unwrap_memorystream(args.This()); +void _ms_copy(const v8::FunctionCallbackInfo& args); - BYTE arg = (BYTE)args[0]->BooleanValue(); - pNative->WriteBYTE(arg ? 1 : 0); +void _ms_clearnoattack(const v8::FunctionCallbackInfo& args); - args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); -} -void _ms_write_long(const v8::FunctionCallbackInfo& args) -{ - CMemoryStream* pNative = unwrap_memorystream(args.This()); +void _ms_pos(v8::Local name, const v8::PropertyCallbackInfo& info); - LONG arg = (LONG)args[0]->Int32Value(); - pNative->WriteLONG(arg); - - args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); -} -void _ms_write_double(const v8::FunctionCallbackInfo& args) -{ - CMemoryStream* pNative = unwrap_memorystream(args.This()); - - double arg = (double)args[0]->NumberValue(); - pNative->WriteLONG((LONG)(arg * 100000)); - - args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); -} - -void _ms_writestring1(const v8::FunctionCallbackInfo& args) -{ - CMemoryStream* pNative = unwrap_memorystream(args.This()); - v8::String::Value data(args[0]); - pNative->WriteString((wchar_t*)*data, data.length()); - args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); -} -void _ms_writestring2(const v8::FunctionCallbackInfo& args) -{ - CMemoryStream* pNative = unwrap_memorystream(args.This()); - v8::String::Value data(args[0]); - pNative->WriteString2((wchar_t*)*data, data.length()); - args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); -} - -void _ms_copy(const v8::FunctionCallbackInfo& args) -{ - CMemoryStream* pNative = unwrap_memorystream(args.This()); - - CMemoryStream* pNative2 = unwrap_memorystream(args[0]->ToObject()); - size_t pos = (size_t)args[1]->Uint32Value(); - size_t len = (size_t)args[2]->Uint32Value(); - - pNative->Copy(pNative2, pos, len); - - args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); -} - -void _ms_clearnoattack(const v8::FunctionCallbackInfo& args) -{ - CMemoryStream* pNative = unwrap_memorystream(args.This()); - pNative->ClearNoAttack(); - args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); -} - -void _ms_pos(v8::Local name, const v8::PropertyCallbackInfo& info) -{ - CMemoryStream* pNative = unwrap_memorystream(info.Holder()); - info.GetReturnValue().Set(v8::Integer::New(v8::Isolate::GetCurrent(), pNative->GetSize())); -} - -v8::Handle CreateMemoryStreamTemplate(v8::Isolate* isolate) -{ - //v8::HandleScope handle_scope(isolate); - - v8::Local result = v8::ObjectTemplate::New(); - result->SetInternalFieldCount(1); // отводим в нем место для хранения CNativeControl - - v8::Isolate* current = v8::Isolate::GetCurrent(); - - // property - result->SetAccessor(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), "pos"), _ms_pos); // получить код ошибки - - // прописываем функции - методы объекта - result->Set(v8::String::NewFromUtf8(current, "Copy"), v8::FunctionTemplate::New(current, _ms_copy)); - result->Set(v8::String::NewFromUtf8(current, "ClearNoAttack"), v8::FunctionTemplate::New(current, _ms_clearnoattack)); - result->Set(v8::String::NewFromUtf8(current, "WriteByte"), v8::FunctionTemplate::New(current, _ms_write_byte)); - result->Set(v8::String::NewFromUtf8(current, "WriteBool"), v8::FunctionTemplate::New(current, _ms_write_bool)); - result->Set(v8::String::NewFromUtf8(current, "WriteLong"), v8::FunctionTemplate::New(current, _ms_write_long)); - result->Set(v8::String::NewFromUtf8(current, "WriteDouble"), v8::FunctionTemplate::New(current, _ms_write_double)); - result->Set(v8::String::NewFromUtf8(current, "WriteString"), v8::FunctionTemplate::New(current, _ms_writestring1)); - result->Set(v8::String::NewFromUtf8(current, "WriteString2"), v8::FunctionTemplate::New(current, _ms_writestring2)); - - // возвращаем временный хэндл хитрым образом, который переносит наш хэндл в предыдущий HandleScope и не дает ему - // уничтожиться при уничтожении "нашего" HandleScope - handle_scope - - //return handle_scope.Close(result); - return result; -} +v8::Handle CreateMemoryStreamTemplate(v8::Isolate* isolate); #endif // MEMORYSTREAM diff --git a/DesktopEditor/doctrenderer/nativecontrol.cpp b/DesktopEditor/doctrenderer/nativecontrol.cpp new file mode 100644 index 0000000000..39e770e88a --- /dev/null +++ b/DesktopEditor/doctrenderer/nativecontrol.cpp @@ -0,0 +1,380 @@ +#include "nativecontrol.h" + +std::wstring to_cstring(v8::Local v) +{ + v8::String::Utf8Value data(v); + if (NULL == *data) + return L""; + + return NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)(*data), data.length()); +} + +std::string to_cstringA(v8::Local v) +{ + v8::String::Utf8Value data(v); + const char* p = (char*)*data; + if (NULL == p) + return ""; + return std::string(p); +} + +// wrap_methods ------------- +CNativeControl* unwrap_nativeobject(v8::Handle obj) +{ + v8::Handle field = v8::Handle::Cast(obj->GetInternalField(0)); + return static_cast(field->Value()); +} + +void _GetFilePath(const v8::FunctionCallbackInfo& args) +{ + CNativeControl* pNative = unwrap_nativeobject(args.This()); + std::string sReturn = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(pNative->GetFilePath()); + args.GetReturnValue().Set(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), sReturn.c_str())); +} +void _SetFilePath(const v8::FunctionCallbackInfo& args) +{ + args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); + + if (args.Length() < 1) + return; + + CNativeControl* pNative = unwrap_nativeobject(args.This()); + pNative->SetFilePath(to_cstring(args[0])); +} + +void _GetFontsDirectory(const v8::FunctionCallbackInfo& args) +{ + CNativeControl* pNative = unwrap_nativeobject(args.This()); + std::string sReturn = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(pNative->m_strFontsDirectory); + args.GetReturnValue().Set(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), sReturn.c_str())); +} + +void _GetEditorType(const v8::FunctionCallbackInfo& args) +{ + CNativeControl* pNative = unwrap_nativeobject(args.This()); + std::string sReturn = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(pNative->m_strEditorType); + args.GetReturnValue().Set(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), sReturn.c_str())); +} + +void _GetChangesCount(const v8::FunctionCallbackInfo& args) +{ + CNativeControl* pNative = unwrap_nativeobject(args.This()); + + int nCount = 0; + if (pNative->m_pChanges != NULL) + nCount = (int)pNative->m_pChanges->GetCount(); + args.GetReturnValue().Set(v8::Integer::New(v8::Isolate::GetCurrent(), nCount)); +} +void _GetChangesFile(const v8::FunctionCallbackInfo& args) +{ + CNativeControl* pNative = unwrap_nativeobject(args.This()); + + if (args.Length() < 1) + args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); + + v8::Local intValue = args[0]->ToInt32(); + int nIndex = (int)intValue->Value(); + + std::string strFile = ""; + if (pNative->m_pChanges != NULL) + strFile = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(pNative->m_pChanges->operator []((int)nIndex)); + + args.GetReturnValue().Set(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), strFile.c_str())); +} + +void _GetFileId(const v8::FunctionCallbackInfo& args) +{ + CNativeControl* pNative = unwrap_nativeobject(args.This()); + std::string sReturn = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(pNative->GetFileId()); + args.GetReturnValue().Set(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), sReturn.c_str())); +} +void _SetFileId(const v8::FunctionCallbackInfo& args) +{ + args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); + + if (args.Length() < 1) + return; + + CNativeControl* pNative = unwrap_nativeobject(args.This()); + pNative->SetFileId(to_cstring(args[0])); +} + +void _CheckNextChange(const v8::FunctionCallbackInfo& args) +{ + CNativeControl* pNative = unwrap_nativeobject(args.This()); + + pNative->m_nCurrentChangesNumber++; + if (-1 != pNative->m_nMaxChangesNumber) + { + if (pNative->m_nCurrentChangesNumber >= pNative->m_nMaxChangesNumber) + { + args.GetReturnValue().Set(v8::Boolean::New(v8::Isolate::GetCurrent(), false)); + return; + } + } + args.GetReturnValue().Set(v8::Boolean::New(v8::Isolate::GetCurrent(), true)); +} + +void _GetFileArrayBuffer(const v8::FunctionCallbackInfo& args) +{ + if (args.Length() < 1) + { + args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); + return; + } + + CNativeControl* pNative = unwrap_nativeobject(args.This()); + + BYTE* pData = NULL; + DWORD len = 0; + pNative->getFileData(to_cstring(args[0]), pData, len); + + v8::Local _buffer = v8::ArrayBuffer::New(v8::Isolate::GetCurrent(), (void*)pData, (size_t)len); + v8::Local _array = v8::Uint8Array::New(_buffer, 0, (size_t)len); + + args.GetReturnValue().Set(_array); +} + +void _GetFontArrayBuffer(const v8::FunctionCallbackInfo& args) +{ + if (args.Length() < 1) + { + args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); + return; + } + + CNativeControl* pNative = unwrap_nativeobject(args.This()); + + BYTE* pData = NULL; + DWORD len = 0; + std::wstring strDir = pNative->m_strFontsDirectory; + +#if 0 + if (strDir.length() != 0) + { + strDir += L"/"; + strDir += to_cstring(args[0]); + } + else +#endif + + // TODO: + // по идее файлы могут совпадать по имени, но лежать в разных директориях. + // и поэтому в AllFonts.js надо бы писать пути полные. + // пока оставим по-старому + std::wstring sFind = to_cstring(args[0]); + bool bIsFullFilePath = (std::wstring::npos != sFind.find('\\') || std::wstring::npos != sFind.find('/')); + if (bIsFullFilePath) + { + bIsFullFilePath = NSFile::CFileBinary::Exists(sFind); + } + + if (!bIsFullFilePath) + { + std::map::iterator pair = pNative->m_map_fonts.find(sFind); + if (pair != pNative->m_map_fonts.end()) + strDir = pair->second; + else + strDir = pNative->m_sDefaultFont; + } + else + { + strDir = sFind; + } + + pNative->getFileData(strDir, pData, len); + + v8::Local _buffer = v8::ArrayBuffer::New(v8::Isolate::GetCurrent(), (void*)pData, (size_t)len); + v8::Local _array = v8::Uint8Array::New(_buffer, 0, (size_t)len); + + args.GetReturnValue().Set(_array); +} + +void _GetFileString(const v8::FunctionCallbackInfo& args) +{ + if (args.Length() < 1) + { + args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); + return; + } + + CNativeControl* pNative = unwrap_nativeobject(args.This()); + + BYTE* pData = NULL; + DWORD len = 0; + pNative->getFileData(to_cstring(args[0]), pData, len); + + args.GetReturnValue().Set(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), (char*)pData, v8::String::kNormalString, len)); +} + +void _Save_AllocNative(const v8::FunctionCallbackInfo& args) +{ + args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); + if (args.Length() < 1) + return; + + CNativeControl* pNative = unwrap_nativeobject(args.This()); + v8::Local intValue = args[0]->ToInt32(); + int nLen = (int)intValue->Value(); + + pNative->Save_Alloc(nLen); + + v8::Local _buffer = v8::ArrayBuffer::New(v8::Isolate::GetCurrent(), (void*)pNative->m_pSaveBinary, (size_t)pNative->m_nSaveLen); + v8::Local _array = v8::Uint8Array::New(_buffer, 0, (size_t)pNative->m_nSaveLen); + args.GetReturnValue().Set(_array); +} + +void _Save_ReAllocNative(const v8::FunctionCallbackInfo& args) +{ + args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); + if (args.Length() < 2) + return; + + CNativeControl* pNative = unwrap_nativeobject(args.This()); + int _pos = args[0]->Int32Value(); + int _len = args[1]->Int32Value(); + + pNative->Save_ReAlloc(_pos, _len); + + v8::Local _buffer = v8::ArrayBuffer::New(v8::Isolate::GetCurrent(), (void*)pNative->m_pSaveBinary, (size_t)pNative->m_nSaveLen); + v8::Local _array = v8::Uint8Array::New(_buffer, 0, (size_t)pNative->m_nSaveLen); + args.GetReturnValue().Set(_array); +} + +void _Save_End(const v8::FunctionCallbackInfo& args) +{ + args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); + if (args.Length() < 2) + return; + + CNativeControl* pNative = unwrap_nativeobject(args.This()); + std::string sHeader = to_cstringA(args[0]); + int _len = args[1]->Int32Value(); + + pNative->Save_End(sHeader, _len); +} + +void _ConsoleLog(const v8::FunctionCallbackInfo& args) +{ + args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); + if (args.Length() < 1) + return; + + CNativeControl* pNative = unwrap_nativeobject(args.This()); + pNative->ConsoleLog(to_cstringA(args[0])); +} + +void _SaveChanges(const v8::FunctionCallbackInfo& args) +{ + args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); + if (args.Length() < 3) + return; + + CNativeControl* pNative = unwrap_nativeobject(args.This()); + pNative->DumpChanges(to_cstringA(args[0]), args[1]->Int32Value(), args[2]->Int32Value()); +} + +void _AddImageInChanges(const v8::FunctionCallbackInfo& args) +{ + args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); + if (args.Length() < 1) + return; + + CNativeControl* pNative = unwrap_nativeobject(args.This()); + + std::wstring sImage = to_cstring(args[0]); + if (sImage.empty()) + return; + + std::map::const_iterator iter = pNative->m_mapImagesInChanges.find(sImage); + if (iter == pNative->m_mapImagesInChanges.end()) + pNative->m_mapImagesInChanges.insert(std::pair(sImage, true)); +} + +v8::Handle CreateNativeControlTemplate(v8::Isolate* isolate) +{ + //v8::HandleScope handle_scope(isolate); + + v8::Local result = v8::ObjectTemplate::New(); + result->SetInternalFieldCount(1); // отводим в нем место для хранения CNativeControl + + v8::Isolate* current = v8::Isolate::GetCurrent(); + + // прописываем функции - методы объекта + result->Set(v8::String::NewFromUtf8(current, "SetFilePath"), v8::FunctionTemplate::New(current, _SetFilePath)); + result->Set(v8::String::NewFromUtf8(current, "GetFilePath"), v8::FunctionTemplate::New(current, _GetFilePath)); + result->Set(v8::String::NewFromUtf8(current, "SetFileId"), v8::FunctionTemplate::New(current, _SetFileId)); + result->Set(v8::String::NewFromUtf8(current, "GetFileId"), v8::FunctionTemplate::New(current, _GetFileId)); + result->Set(v8::String::NewFromUtf8(current, "GetFileBinary"), v8::FunctionTemplate::New(current, _GetFileArrayBuffer)); + result->Set(v8::String::NewFromUtf8(current, "GetFontBinary"), v8::FunctionTemplate::New(current, _GetFontArrayBuffer)); + result->Set(v8::String::NewFromUtf8(current, "GetFontsDirectory"), v8::FunctionTemplate::New(current, _GetFontsDirectory)); + result->Set(v8::String::NewFromUtf8(current, "GetFileString"), v8::FunctionTemplate::New(current, _GetFileString)); + + result->Set(v8::String::NewFromUtf8(current, "GetEditorType"), v8::FunctionTemplate::New(current, _GetEditorType)); + result->Set(v8::String::NewFromUtf8(current, "CheckNextChange"), v8::FunctionTemplate::New(current, _CheckNextChange)); + + result->Set(v8::String::NewFromUtf8(current, "GetCountChanges"), v8::FunctionTemplate::New(current, _GetChangesCount)); + result->Set(v8::String::NewFromUtf8(current, "GetChangesFile"), v8::FunctionTemplate::New(current, _GetChangesFile)); + + result->Set(v8::String::NewFromUtf8(current, "Save_AllocNative"), v8::FunctionTemplate::New(current, _Save_AllocNative)); + result->Set(v8::String::NewFromUtf8(current, "Save_ReAllocNative"), v8::FunctionTemplate::New(current, _Save_ReAllocNative)); + result->Set(v8::String::NewFromUtf8(current, "Save_End"), v8::FunctionTemplate::New(current, _Save_End)); + + result->Set(v8::String::NewFromUtf8(current, "AddImageInChanges"), v8::FunctionTemplate::New(current, _AddImageInChanges)); + + result->Set(v8::String::NewFromUtf8(current, "ConsoleLog"), v8::FunctionTemplate::New(current, _ConsoleLog)); + + // возвращаем временный хэндл хитрым образом, который переносит наш хэндл в предыдущий HandleScope и не дает ему + // уничтожиться при уничтожении "нашего" HandleScope - handle_scope + + //return handle_scope.Close(result); + return result; +} + +v8::Handle CreateNativeControlTemplateBuilder(v8::Isolate* isolate) +{ + //v8::HandleScope handle_scope(isolate); + + v8::Local result = v8::ObjectTemplate::New(); + result->SetInternalFieldCount(1); // отводим в нем место для хранения CNativeControl + + v8::Isolate* current = v8::Isolate::GetCurrent(); + + // прописываем функции - методы объекта + result->Set(v8::String::NewFromUtf8(current, "SetFilePath"), v8::FunctionTemplate::New(current, _SetFilePath)); + result->Set(v8::String::NewFromUtf8(current, "GetFilePath"), v8::FunctionTemplate::New(current, _GetFilePath)); + result->Set(v8::String::NewFromUtf8(current, "SetFileId"), v8::FunctionTemplate::New(current, _SetFileId)); + result->Set(v8::String::NewFromUtf8(current, "GetFileId"), v8::FunctionTemplate::New(current, _GetFileId)); + result->Set(v8::String::NewFromUtf8(current, "GetFileBinary"), v8::FunctionTemplate::New(current, _GetFileArrayBuffer)); + result->Set(v8::String::NewFromUtf8(current, "GetFontBinary"), v8::FunctionTemplate::New(current, _GetFontArrayBuffer)); + result->Set(v8::String::NewFromUtf8(current, "GetFontsDirectory"), v8::FunctionTemplate::New(current, _GetFontsDirectory)); + result->Set(v8::String::NewFromUtf8(current, "GetFileString"), v8::FunctionTemplate::New(current, _GetFileString)); + + result->Set(v8::String::NewFromUtf8(current, "GetEditorType"), v8::FunctionTemplate::New(current, _GetEditorType)); + result->Set(v8::String::NewFromUtf8(current, "CheckNextChange"), v8::FunctionTemplate::New(current, _CheckNextChange)); + + result->Set(v8::String::NewFromUtf8(current, "GetCountChanges"), v8::FunctionTemplate::New(current, _GetChangesCount)); + result->Set(v8::String::NewFromUtf8(current, "GetChangesFile"), v8::FunctionTemplate::New(current, _GetChangesFile)); + + result->Set(v8::String::NewFromUtf8(current, "Save_AllocNative"), v8::FunctionTemplate::New(current, _Save_AllocNative)); + result->Set(v8::String::NewFromUtf8(current, "Save_ReAllocNative"), v8::FunctionTemplate::New(current, _Save_ReAllocNative)); + result->Set(v8::String::NewFromUtf8(current, "Save_End"), v8::FunctionTemplate::New(current, _Save_End)); + + result->Set(v8::String::NewFromUtf8(current, "AddImageInChanges"), v8::FunctionTemplate::New(current, _AddImageInChanges)); + + result->Set(v8::String::NewFromUtf8(current, "ConsoleLog"), v8::FunctionTemplate::New(current, _ConsoleLog)); + + result->Set(v8::String::NewFromUtf8(current, "SaveChanges"), v8::FunctionTemplate::New(current, _SaveChanges)); + + // возвращаем временный хэндл хитрым образом, который переносит наш хэндл в предыдущий HandleScope и не дает ему + // уничтожиться при уничтожении "нашего" HandleScope - handle_scope + + //return handle_scope.Close(result); + return result; +} +// -------------------------- + +void enableTypedArrays() +{ + v8::V8::SetArrayBufferAllocator(new MallocArrayBufferAllocator()); +} diff --git a/DesktopEditor/doctrenderer/nativecontrol.h b/DesktopEditor/doctrenderer/nativecontrol.h index 8d0d380e90..c88ab9fe7f 100644 --- a/DesktopEditor/doctrenderer/nativecontrol.h +++ b/DesktopEditor/doctrenderer/nativecontrol.h @@ -7,23 +7,8 @@ #include // string convert -static std::wstring to_cstring(v8::Local v) -{ - v8::String::Utf8Value data(v); - if (NULL == *data) - return L""; - - return NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)(*data), data.length()); -} - -static std::string to_cstringA(v8::Local v) -{ - v8::String::Utf8Value data(v); - const char* p = (char*)*data; - if (NULL == p) - return ""; - return std::string(p); -} +std::wstring to_cstring(v8::Local v); +std::string to_cstringA(v8::Local v); class CNativeControl { @@ -56,6 +41,9 @@ public: std::wstring m_sConsoleLogFile; + std::wstring m_sChangesBuilderPath; + int m_nCurrentChangesBuilderIndex; + public: CMemoryStream* m_pStream; @@ -72,6 +60,8 @@ public: m_nSaveBinaryLen = 0; m_sConsoleLogFile = L""; + + m_nCurrentChangesBuilderIndex = 0; } ~CNativeControl() { @@ -159,6 +149,63 @@ public: std::cout << strVal << std::endl; } + void DumpRemoveChanges(const int& nDeleteIndex) + { + int nNaturalIndex = nDeleteIndex; + + // на каждое изменение две кавычки) + nNaturalIndex <<= 1; + + // not cool realize + BYTE* pData = NULL; + DWORD dwSize = 0; + bool bIsOk = NSFile::CFileBinary::ReadAllBytes(m_sChangesBuilderPath, &pData, dwSize); + int nCounter = 0; + + int nSize = (int)dwSize; + int nIndex = -1; + for (int i = 0; i < nSize; i++) + { + if ('\"' == pData[i]) + { + if (nCounter == nNaturalIndex) + { + nIndex = i; + break; + } + ++nCounter; + } + } + RELEASEARRAYOBJECTS(pData); + + if (-1 != nIndex) + { + NSFile::CFileBinary::Truncate(m_sChangesBuilderPath, nIndex); + } + } + + void DumpChanges(const std::string& sParam, int nDeleteIndex, int nCount) + { + if (nDeleteIndex < m_nCurrentChangesBuilderIndex) + { + // нужно удалить изменения + DumpRemoveChanges(nDeleteIndex); + } + m_nCurrentChangesBuilderIndex = nDeleteIndex + nCount; + + if (nCount != 0) + { + FILE* _file = NSFile::CFileBinary::OpenFileNative(m_sChangesBuilderPath, L"a+"); + if (NULL != _file) + { + fprintf(_file, "\""); + fprintf(_file, sParam.c_str()); + fprintf(_file, "\","); + fclose(_file); + } + } + } + void CheckFonts() { if (0 == m_map_fonts.size()) @@ -213,307 +260,42 @@ public: }; // wrap_methods ------------- -CNativeControl* unwrap_nativeobject(v8::Handle obj) -{ - v8::Handle field = v8::Handle::Cast(obj->GetInternalField(0)); - return static_cast(field->Value()); -} +CNativeControl* unwrap_nativeobject(v8::Handle obj); -void _GetFilePath(const v8::FunctionCallbackInfo& args) -{ - CNativeControl* pNative = unwrap_nativeobject(args.This()); - std::string sReturn = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(pNative->GetFilePath()); - args.GetReturnValue().Set(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), sReturn.c_str())); -} -void _SetFilePath(const v8::FunctionCallbackInfo& args) -{ - args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); +void _GetFilePath(const v8::FunctionCallbackInfo& args); +void _SetFilePath(const v8::FunctionCallbackInfo& args); - if (args.Length() < 1) - return; +void _GetFontsDirectory(const v8::FunctionCallbackInfo& args); +void _GetEditorType(const v8::FunctionCallbackInfo& args); - CNativeControl* pNative = unwrap_nativeobject(args.This()); - pNative->SetFilePath(to_cstring(args[0])); -} +void _GetChangesCount(const v8::FunctionCallbackInfo& args); +void _GetChangesFile(const v8::FunctionCallbackInfo& args); -void _GetFontsDirectory(const v8::FunctionCallbackInfo& args) -{ - CNativeControl* pNative = unwrap_nativeobject(args.This()); - std::string sReturn = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(pNative->m_strFontsDirectory); - args.GetReturnValue().Set(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), sReturn.c_str())); -} +void _GetFileId(const v8::FunctionCallbackInfo& args); +void _SetFileId(const v8::FunctionCallbackInfo& args); -void _GetEditorType(const v8::FunctionCallbackInfo& args) -{ - CNativeControl* pNative = unwrap_nativeobject(args.This()); - std::string sReturn = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(pNative->m_strEditorType); - args.GetReturnValue().Set(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), sReturn.c_str())); -} +void _CheckNextChange(const v8::FunctionCallbackInfo& args); -void _GetChangesCount(const v8::FunctionCallbackInfo& args) -{ - CNativeControl* pNative = unwrap_nativeobject(args.This()); +void _GetFileArrayBuffer(const v8::FunctionCallbackInfo& args); - int nCount = 0; - if (pNative->m_pChanges != NULL) - nCount = (int)pNative->m_pChanges->GetCount(); - args.GetReturnValue().Set(v8::Integer::New(v8::Isolate::GetCurrent(), nCount)); -} -void _GetChangesFile(const v8::FunctionCallbackInfo& args) -{ - CNativeControl* pNative = unwrap_nativeobject(args.This()); +void _GetFontArrayBuffer(const v8::FunctionCallbackInfo& args); - if (args.Length() < 1) - args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); +void _GetFileString(const v8::FunctionCallbackInfo& args); - v8::Local intValue = args[0]->ToInt32(); - int nIndex = (int)intValue->Value(); +void _Save_AllocNative(const v8::FunctionCallbackInfo& args); - std::string strFile = ""; - if (pNative->m_pChanges != NULL) - strFile = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(pNative->m_pChanges->operator []((int)nIndex)); +void _Save_ReAllocNative(const v8::FunctionCallbackInfo& args); - args.GetReturnValue().Set(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), strFile.c_str())); -} +void _Save_End(const v8::FunctionCallbackInfo& args); -void _GetFileId(const v8::FunctionCallbackInfo& args) -{ - CNativeControl* pNative = unwrap_nativeobject(args.This()); - std::string sReturn = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(pNative->GetFileId()); - args.GetReturnValue().Set(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), sReturn.c_str())); -} -void _SetFileId(const v8::FunctionCallbackInfo& args) -{ - args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); +void _ConsoleLog(const v8::FunctionCallbackInfo& args); - if (args.Length() < 1) - return; +void _SaveChanges(const v8::FunctionCallbackInfo& args); - CNativeControl* pNative = unwrap_nativeobject(args.This()); - pNative->SetFileId(to_cstring(args[0])); -} +void _AddImageInChanges(const v8::FunctionCallbackInfo& args); -void _CheckNextChange(const v8::FunctionCallbackInfo& args) -{ - CNativeControl* pNative = unwrap_nativeobject(args.This()); - - pNative->m_nCurrentChangesNumber++; - if (-1 != pNative->m_nMaxChangesNumber) - { - if (pNative->m_nCurrentChangesNumber >= pNative->m_nMaxChangesNumber) - { - args.GetReturnValue().Set(v8::Boolean::New(v8::Isolate::GetCurrent(), false)); - return; - } - } - args.GetReturnValue().Set(v8::Boolean::New(v8::Isolate::GetCurrent(), true)); -} - -void _GetFileArrayBuffer(const v8::FunctionCallbackInfo& args) -{ - if (args.Length() < 1) - { - args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); - return; - } - - CNativeControl* pNative = unwrap_nativeobject(args.This()); - - BYTE* pData = NULL; - DWORD len = 0; - pNative->getFileData(to_cstring(args[0]), pData, len); - - v8::Local _buffer = v8::ArrayBuffer::New(v8::Isolate::GetCurrent(), (void*)pData, (size_t)len); - v8::Local _array = v8::Uint8Array::New(_buffer, 0, (size_t)len); - - args.GetReturnValue().Set(_array); -} - -void _GetFontArrayBuffer(const v8::FunctionCallbackInfo& args) -{ - if (args.Length() < 1) - { - args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); - return; - } - - CNativeControl* pNative = unwrap_nativeobject(args.This()); - - BYTE* pData = NULL; - DWORD len = 0; - std::wstring strDir = pNative->m_strFontsDirectory; - -#if 0 - if (strDir.length() != 0) - { - strDir += L"/"; - strDir += to_cstring(args[0]); - } - else -#endif - - // TODO: - // по идее файлы могут совпадать по имени, но лежать в разных директориях. - // и поэтому в AllFonts.js надо бы писать пути полные. - // пока оставим по-старому - std::wstring sFind = to_cstring(args[0]); - bool bIsFullFilePath = (std::wstring::npos != sFind.find('\\') || std::wstring::npos != sFind.find('/')); - if (bIsFullFilePath) - { - bIsFullFilePath = NSFile::CFileBinary::Exists(sFind); - } - - if (!bIsFullFilePath) - { - std::map::iterator pair = pNative->m_map_fonts.find(sFind); - if (pair != pNative->m_map_fonts.end()) - strDir = pair->second; - else - strDir = pNative->m_sDefaultFont; - } - else - { - strDir = sFind; - } - - pNative->getFileData(strDir, pData, len); - - v8::Local _buffer = v8::ArrayBuffer::New(v8::Isolate::GetCurrent(), (void*)pData, (size_t)len); - v8::Local _array = v8::Uint8Array::New(_buffer, 0, (size_t)len); - - args.GetReturnValue().Set(_array); -} - -void _GetFileString(const v8::FunctionCallbackInfo& args) -{ - if (args.Length() < 1) - { - args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); - return; - } - - CNativeControl* pNative = unwrap_nativeobject(args.This()); - - BYTE* pData = NULL; - DWORD len = 0; - pNative->getFileData(to_cstring(args[0]), pData, len); - - args.GetReturnValue().Set(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), (char*)pData, v8::String::kNormalString, len)); -} - -void _Save_AllocNative(const v8::FunctionCallbackInfo& args) -{ - args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); - if (args.Length() < 1) - return; - - CNativeControl* pNative = unwrap_nativeobject(args.This()); - v8::Local intValue = args[0]->ToInt32(); - int nLen = (int)intValue->Value(); - - pNative->Save_Alloc(nLen); - - v8::Local _buffer = v8::ArrayBuffer::New(v8::Isolate::GetCurrent(), (void*)pNative->m_pSaveBinary, (size_t)pNative->m_nSaveLen); - v8::Local _array = v8::Uint8Array::New(_buffer, 0, (size_t)pNative->m_nSaveLen); - args.GetReturnValue().Set(_array); -} - -void _Save_ReAllocNative(const v8::FunctionCallbackInfo& args) -{ - args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); - if (args.Length() < 2) - return; - - CNativeControl* pNative = unwrap_nativeobject(args.This()); - int _pos = args[0]->Int32Value(); - int _len = args[1]->Int32Value(); - - pNative->Save_ReAlloc(_pos, _len); - - v8::Local _buffer = v8::ArrayBuffer::New(v8::Isolate::GetCurrent(), (void*)pNative->m_pSaveBinary, (size_t)pNative->m_nSaveLen); - v8::Local _array = v8::Uint8Array::New(_buffer, 0, (size_t)pNative->m_nSaveLen); - args.GetReturnValue().Set(_array); -} - -void _Save_End(const v8::FunctionCallbackInfo& args) -{ - args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); - if (args.Length() < 2) - return; - - CNativeControl* pNative = unwrap_nativeobject(args.This()); - std::string sHeader = to_cstringA(args[0]); - int _len = args[1]->Int32Value(); - - pNative->Save_End(sHeader, _len); -} - -void _ConsoleLog(const v8::FunctionCallbackInfo& args) -{ - args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); - if (args.Length() < 1) - return; - - CNativeControl* pNative = unwrap_nativeobject(args.This()); - pNative->ConsoleLog(to_cstringA(args[0])); -} - -void _AddImageInChanges(const v8::FunctionCallbackInfo& args) -{ - args.GetReturnValue().Set(v8::Undefined(v8::Isolate::GetCurrent())); - if (args.Length() < 1) - return; - - CNativeControl* pNative = unwrap_nativeobject(args.This()); - - std::wstring sImage = to_cstring(args[0]); - if (sImage.empty()) - return; - - std::map::const_iterator iter = pNative->m_mapImagesInChanges.find(sImage); - if (iter == pNative->m_mapImagesInChanges.end()) - pNative->m_mapImagesInChanges.insert(std::pair(sImage, true)); -} - -v8::Handle CreateNativeControlTemplate(v8::Isolate* isolate) -{ - //v8::HandleScope handle_scope(isolate); - - v8::Local result = v8::ObjectTemplate::New(); - result->SetInternalFieldCount(1); // отводим в нем место для хранения CNativeControl - - v8::Isolate* current = v8::Isolate::GetCurrent(); - - // прописываем функции - методы объекта - result->Set(v8::String::NewFromUtf8(current, "SetFilePath"), v8::FunctionTemplate::New(current, _SetFilePath)); - result->Set(v8::String::NewFromUtf8(current, "GetFilePath"), v8::FunctionTemplate::New(current, _GetFilePath)); - result->Set(v8::String::NewFromUtf8(current, "SetFileId"), v8::FunctionTemplate::New(current, _SetFileId)); - result->Set(v8::String::NewFromUtf8(current, "GetFileId"), v8::FunctionTemplate::New(current, _GetFileId)); - result->Set(v8::String::NewFromUtf8(current, "GetFileBinary"), v8::FunctionTemplate::New(current, _GetFileArrayBuffer)); - result->Set(v8::String::NewFromUtf8(current, "GetFontBinary"), v8::FunctionTemplate::New(current, _GetFontArrayBuffer)); - result->Set(v8::String::NewFromUtf8(current, "GetFontsDirectory"), v8::FunctionTemplate::New(current, _GetFontsDirectory)); - result->Set(v8::String::NewFromUtf8(current, "GetFileString"), v8::FunctionTemplate::New(current, _GetFileString)); - - result->Set(v8::String::NewFromUtf8(current, "GetEditorType"), v8::FunctionTemplate::New(current, _GetEditorType)); - result->Set(v8::String::NewFromUtf8(current, "CheckNextChange"), v8::FunctionTemplate::New(current, _CheckNextChange)); - - result->Set(v8::String::NewFromUtf8(current, "GetCountChanges"), v8::FunctionTemplate::New(current, _GetChangesCount)); - result->Set(v8::String::NewFromUtf8(current, "GetChangesFile"), v8::FunctionTemplate::New(current, _GetChangesFile)); - - result->Set(v8::String::NewFromUtf8(current, "Save_AllocNative"), v8::FunctionTemplate::New(current, _Save_AllocNative)); - result->Set(v8::String::NewFromUtf8(current, "Save_ReAllocNative"), v8::FunctionTemplate::New(current, _Save_ReAllocNative)); - result->Set(v8::String::NewFromUtf8(current, "Save_End"), v8::FunctionTemplate::New(current, _Save_End)); - - result->Set(v8::String::NewFromUtf8(current, "AddImageInChanges"), v8::FunctionTemplate::New(current, _AddImageInChanges)); - - result->Set(v8::String::NewFromUtf8(current, "ConsoleLog"), v8::FunctionTemplate::New(current, _ConsoleLog)); - - // возвращаем временный хэндл хитрым образом, который переносит наш хэндл в предыдущий HandleScope и не дает ему - // уничтожиться при уничтожении "нашего" HandleScope - handle_scope - - //return handle_scope.Close(result); - return result; -} +v8::Handle CreateNativeControlTemplate(v8::Isolate* isolate); +v8::Handle CreateNativeControlTemplateBuilder(v8::Isolate* isolate); // -------------------------- // create work with arraytypes @@ -536,114 +318,7 @@ public: } }; -static void enableTypedArrays() -{ - v8::V8::SetArrayBufferAllocator(new MallocArrayBufferAllocator()); -} - -enum CommandType -{ - ctPenXML = 0, - ctPenColor = 1, - ctPenAlpha = 2, - ctPenSize = 3, - ctPenDashStyle = 4, - ctPenLineStartCap = 5, - ctPenLineEndCap = 6, - ctPenLineJoin = 7, - ctPenDashPatern = 8, - ctPenDashPatternCount = 9, - ctPenDashOffset = 10, - ctPenAlign = 11, - ctPenMiterLimit = 12, - - // brush - ctBrushXML = 20, - ctBrushType = 21, - ctBrushColor1 = 22, - ctBrushColor2 = 23, - ctBrushAlpha1 = 24, - ctBrushAlpha2 = 25, - ctBrushTexturePath = 26, - ctBrushTextureAlpha = 27, - ctBrushTextureMode = 28, - ctBrushRectable = 29, - ctBrushRectableEnabled = 30, - ctBrushGradient = 31, - - // font - ctFontXML = 40, - ctFontName = 41, - ctFontSize = 42, - ctFontStyle = 43, - ctFontPath = 44, - ctFontGID = 45, - ctFontCharSpace = 46, - - // shadow - ctShadowXML = 50, - ctShadowVisible = 51, - ctShadowDistanceX = 52, - ctShadowDistanceY = 53, - ctShadowBlurSize = 54, - ctShadowColor = 55, - ctShadowAlpha = 56, - - // edge - ctEdgeXML = 70, - ctEdgeVisible = 71, - ctEdgeDistance = 72, - ctEdgeColor = 73, - ctEdgeAlpha = 74, - - // text - ctDrawText = 80, - ctDrawTextEx = 81, - - // pathcommands - ctPathCommandMoveTo = 91, - ctPathCommandLineTo = 92, - ctPathCommandLinesTo = 93, - ctPathCommandCurveTo = 94, - ctPathCommandCurvesTo = 95, - ctPathCommandArcTo = 96, - ctPathCommandClose = 97, - ctPathCommandEnd = 98, - ctDrawPath = 99, - ctPathCommandStart = 100, - ctPathCommandGetCurrentPoint = 101, - ctPathCommandText = 102, - ctPathCommandTextEx = 103, - - // image - ctDrawImage = 110, - ctDrawImageFromFile = 111, - - ctSetParams = 120, - - ctBeginCommand = 121, - ctEndCommand = 122, - - ctSetTransform = 130, - ctResetTransform = 131, - - ctClipMode = 140, - - ctCommandLong1 = 150, - ctCommandDouble1 = 151, - ctCommandString1 = 152, - ctCommandLong2 = 153, - ctCommandDouble2 = 154, - ctCommandString2 = 155, - - ctPageWidth = 200, - ctPageHeight = 201, - - ctPageStart = 202, - ctPageEnd = 203, - - ctError = 255 -}; +void enableTypedArrays(); class CChangesWorker { @@ -1172,6 +847,8 @@ private: ////////////////////////////////////////////////////////////////////////////// +void CreateNativeObject(const v8::FunctionCallbackInfo& args); +void CreateNativeObjectBuilder(const v8::FunctionCallbackInfo& args); +void CreateNativeMemoryStream(const v8::FunctionCallbackInfo& args); #endif // NATIVECONTROL - diff --git a/DesktopEditor/doctrenderer/test/main.cpp b/DesktopEditor/doctrenderer/test/main.cpp index caa6a1affe..254a5a2201 100644 --- a/DesktopEditor/doctrenderer/test/main.cpp +++ b/DesktopEditor/doctrenderer/test/main.cpp @@ -11,15 +11,15 @@ int main(int argc, char *argv[]) #if 1 std::wstring strXml = L"\ -1\ +0\ 3\ -D:\\build_doc\ -D:\\build_doc\\EditorWithChanges.bin\ -D:\\activex\\AVS\\Sources\\TeamlabOffice\\trunk\\OfficeWeb\\Fonts\\native\ -D:\\build_doc\\media\ +D:\\DE_CAD4\ +D:\\DE_CAD4\\EditorWithChanges.bin\ +D:\\activex\\AVS\\Sources\\TeamlabOffice\\trunk\\ServerComponents\\DesktopEditor\\ChromiumBasedEditors2\\app\\test\\src\\build\\win64\\Debug\\Local\\converter\\fonts\\\ +D:\\DE_CAD4\\media\ D:\\activex\\AVS\\Sources\\TeamlabOffice\\trunk\\ServerComponents\\Test\\Applications\\TestAVSOfficeDocxFile2\\TestAVSOfficeDocxFile2\\bin\\x86\\presentationthemes\ \ -D:\\build_doc\\changes\\changes0.json\ +D:\\DE_CAD4\\changes\\changes0.json\ \ "; @@ -54,7 +54,7 @@ int main(int argc, char *argv[]) #if 1 - NSDoctRenderer::CDoctrenderer oRenderer; + NSDoctRenderer::CDoctrenderer oRenderer(L"C:/ProgramData/ONLYOFFICE/webdata/cloud/fonts/AllFonts.js"); std::wstring sError; oRenderer.Execute(strXml, sError); @@ -68,7 +68,7 @@ int main(int argc, char *argv[]) CPdfRenderer oPDF(&oFonts); oPDF.SetTempFolder(L"D:\\test_pdf"); - oPDF.OnlineWordToPdfFromBinary(L"D:\\test_pdf\\pdf.bin", L"D:\\test_pdf\\123.pdf"); + oPDF.OnlineWordToPdfFromBinary(L"D:\\DE_CAD4\\EditorWithChanges.bin", L"D:\\test_pdf\\123.pdf"); #endif diff --git a/DesktopEditor/doctrenderer/test_builder/docbuilder.pro b/DesktopEditor/doctrenderer/test_builder/docbuilder.pro new file mode 100644 index 0000000000..5956e0f60b --- /dev/null +++ b/DesktopEditor/doctrenderer/test_builder/docbuilder.pro @@ -0,0 +1,58 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2015-01-19T14:14:33 +# +#------------------------------------------------- + +QT -= core +QT -= gui + +TARGET = docbuilder +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + +CONFIG -= debug_and_release debug_and_release_target + +############### destination path ############### +DESTINATION_SDK_PATH = $$PWD/../../../SDK/lib + +# WINDOWS +win32:contains(QMAKE_TARGET.arch, x86_64):{ +CONFIG(debug, debug|release) { + DESTINATION_SDK_PATH_DOCTRENDERER = $$DESTINATION_SDK_PATH/win_64/DEBUG +} else { + DESTINATION_SDK_PATH_DOCTRENDERER = $$DESTINATION_SDK_PATH/win_64 +} +} +win32:!contains(QMAKE_TARGET.arch, x86_64):{ +CONFIG(debug, debug|release) { + DESTINATION_SDK_PATH_DOCTRENDERER = $$DESTINATION_SDK_PATH/win_32/DEBUG +} else { + DESTINATION_SDK_PATH_DOCTRENDERER = $$DESTINATION_SDK_PATH/win_32 +} +} + +linux-g++:contains(QMAKE_HOST.arch, x86_64):{ + DESTINATION_SDK_PATH_DOCTRENDERER = $$DESTINATION_SDK_PATH/linux_64 +} +linux-g++:!contains(QMAKE_HOST.arch, x86_64):{ + DESTINATION_SDK_PATH_DOCTRENDERER = $$DESTINATION_SDK_PATH/linux_32 +} + +mac { + DESTINATION_SDK_PATH_DOCTRENDERER = $$DESTINATION_SDK_PATH/mac_64 +} + +CONFIG(debug, debug|release) { + DESTDIR = $$PWD/Debug +} else { + DESTDIR = $$PWD/Release +} + +################################################ + +LIBS += -L$$DESTINATION_SDK_PATH_DOCTRENDERER -ldoctrenderer + +SOURCES += main.cpp diff --git a/DesktopEditor/doctrenderer/test_builder/main.cpp b/DesktopEditor/doctrenderer/test_builder/main.cpp new file mode 100644 index 0000000000..08dac03cb6 --- /dev/null +++ b/DesktopEditor/doctrenderer/test_builder/main.cpp @@ -0,0 +1,51 @@ +#include "../docbuilder.h" + +#define AVS_OFFICESTUDIO_FILE_DOCUMENT 0x0040 +#define AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0001 +#define AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0002 +#define AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0003 +#define AVS_OFFICESTUDIO_FILE_DOCUMENT_RTF AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0004 +#define AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0005 +#define AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0006 +#define AVS_OFFICESTUDIO_FILE_DOCUMENT_MHT AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0007 +#define AVS_OFFICESTUDIO_FILE_DOCUMENT_EPUB AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0008 +#define AVS_OFFICESTUDIO_FILE_DOCUMENT_FB2 AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0009 +#define AVS_OFFICESTUDIO_FILE_DOCUMENT_MOBI AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x000a + +#define AVS_OFFICESTUDIO_FILE_PRESENTATION 0x0080 +#define AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX AVS_OFFICESTUDIO_FILE_PRESENTATION + 0x0001 +#define AVS_OFFICESTUDIO_FILE_PRESENTATION_PPT AVS_OFFICESTUDIO_FILE_PRESENTATION + 0x0002 +#define AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP AVS_OFFICESTUDIO_FILE_PRESENTATION + 0x0003 +#define AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX AVS_OFFICESTUDIO_FILE_PRESENTATION + 0x0004 + +#define AVS_OFFICESTUDIO_FILE_SPREADSHEET 0x0100 +#define AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX AVS_OFFICESTUDIO_FILE_SPREADSHEET + 0x0001 +#define AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLS AVS_OFFICESTUDIO_FILE_SPREADSHEET + 0x0002 +#define AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS AVS_OFFICESTUDIO_FILE_SPREADSHEET + 0x0003 +#define AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV AVS_OFFICESTUDIO_FILE_SPREADSHEET + 0x0004 + +#define AVS_OFFICESTUDIO_FILE_CROSSPLATFORM 0x0200 +#define AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF AVS_OFFICESTUDIO_FILE_CROSSPLATFORM + 0x0001 +#define AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU AVS_OFFICESTUDIO_FILE_CROSSPLATFORM + 0x0003 +#define AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS AVS_OFFICESTUDIO_FILE_CROSSPLATFORM + 0x0004 + +int main(int argc, char *argv[]) +{ + NSDoctRenderer::CDocBuilder oBuilder; + + // tmpfolder + oBuilder.SetTmpFolder(L"D:/BuilderTest"); + +#if 1 + oBuilder.CreateFile(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX); + oBuilder.ExecuteCommand(L"Add_Text(\"Oleg\");"); +#endif + +#if 0 + oBuilder.OpenFile(L"D:/TESTFILES/images.docx", L""); +#endif + + oBuilder.SaveFile(AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF, L"D:/TESTFILES/images.pdf"); + + return 0; +}